thrift

    Thrift IDL、类型绑定、Binary/Compact 和分帧 RPC

    Download zip
    Version
    0.5.0
    License
    MIT
    Last updated
    5 hours ago
    Downloads
    1

    #可执行 API 示例

    增加 Binary/Compact Map/Set,12 组 Apache Thrift 独立向量对照。这些例子调用公开 API,并随 moon test 执行。

    ///|
    test "documented map container" {
    let value = @thrift.MapValue(
    Some(@thrift.BinaryKind),
    Some(@thrift.I32Kind),
    [(@thrift.Binary(b"answer"), @thrift.I32(42))],
    )
    let wire = @thrift.encode(value, @thrift.BinaryProtocol)
    assert_eq(
    @thrift.decode(wire, @thrift.MapKind, @thrift.BinaryProtocol),
    value,
    )
    }

    另有 MoonBit IDL 解析、schema 校验和类型绑定生成,以及 Node TCP/TLS/mTLS 宿主,见 README.md。仍不声称完整 Apache Thrift 兼容;本例所用通用值 API 解码 Compact 空 Map 时,线路不含键值类型信息,类型字段为 None/None

    #分帧 RPC 客户端

    ///|
    test "documented framed RPC exchange" {
    let client = @thrift.Client::new(@thrift.CompactProtocol)
    let request = client.call("ping", @thrift.Struct([]))
    let frames = @thrift.FrameDecoder::new()
    let message = @thrift.decode_message(
    frames.feed(request)[0],
    @thrift.CompactProtocol,
    )
    let reply : @thrift.Message = {
    name: message.name,
    sequence_id: message.sequence_id,
    message_type: 2,
    body: @thrift.Struct([(0, @thrift.I32(42))]),
    }
    assert_eq(
    client.feed(@thrift.encode_framed_message(reply, @thrift.CompactProtocol)),
    [reply],
    )
    client.finish()
    }

    CodecError

    pub suberror CodecError {
    Invalid(String)
    } derive(
    Debug
    )

    SchemaError

    pub suberror SchemaError {
    Syntax(String, IdlLocation)
    InvalidSchema(String)
    } derive(
    Debug
    )

    Client

    pub struct Client {
    protocol : Protocol
    strict_read : Bool
    strict_write : Bool
    decoder : FrameDecoder
    pending : Map[Int, String]
    next_sequence : UInt
    failed : Bool
    }

    Transport-independent framed RPC client state. The host supplies socket I/O. Protocol errors poison this instance; create a new client after reconnecting.

    Client::call

    fn Client::call(self : Client, name : String, body : Value, oneway? : Bool) -> Bytes raise CodecError

    Encode a request and register its signed sequence id. Oneway calls do not create a pending response. Returns one complete TFramedTransport frame.

    Client::call_with_id

    fn Client::call_with_id(self : Client, name : String, body : Value, oneway? : Bool, response_name? : String?) -> (Int, Bytes) raise CodecError

    Return the registered sequence id alongside the frame. Multiplexed requests may specify the unprefixed response name used by TMultiplexedProtocol peers.

    Client::feed

    fn Client::feed(self : Client, chunk : Bytes) -> Array[Message] raise CodecError

    Accept arbitrary socket chunks. Responses may arrive in any order. Application exceptions (type 3) are delivered as Message values.

    Client::finish

    fn Client::finish(self : Client) -> Unit raise CodecError

    Validate clean EOF, including outstanding calls.

    Client::new

    fn Client::new(protocol : Protocol, strict_read? : Bool, strict_write? : Bool) -> Client raise CodecError

    Client::pending_count

    fn Client::pending_count(self : Client) -> Int

    FrameDecoder

    pub struct FrameDecoder {
    max_frame : Int
    header : UInt64
    header_bytes : Int
    expected : Int
    buffer : Array[Byte]
    failed : Bool
    }

    A bounded incremental transport decoder. Invalid input poisons the decoder until reset. feed is transactional: no partial frames are returned on error.

    FrameDecoder::feed

    fn FrameDecoder::feed(self : FrameDecoder, chunk : Bytes) -> Array[Bytes] raise CodecError

    FrameDecoder::finish

    fn FrameDecoder::finish(self : FrameDecoder) -> Unit raise CodecError

    FrameDecoder::new

    fn FrameDecoder::new(max_frame? : Int) -> FrameDecoder raise CodecError

    FrameDecoder::reset

    fn FrameDecoder::reset(self : FrameDecoder) -> Unit

    IdlConst

    pub(all) enum IdlConst {
    IntegerConstant(Int64)
    FloatConstant(Double)
    StringConstant(String)
    NameConstant(String)
    ListConstant(Array[IdlConst])
    MapConstant(Array[(IdlConst, IdlConst)])
    } derive(Eq,
    Debug
    )

    IdlDefinition

    pub(all) enum IdlDefinition {
    Alias(String, IdlType, Map[String, String])
    Enumeration(String, Array[(String, Int)], Map[String, String])
    Record(String, String, Array[IdlField], Map[String, String])
    Constant(String, IdlType, IdlConst)
    Service(String, String?, Array[IdlMethod], Map[String, String])
    } derive(Eq,
    Debug
    )

    IdlField

    pub(all) struct IdlField {
    id : Int
    name : String
    field_type : IdlType
    requiredness : String
    default_value : IdlConst?
    annotations : Map[String, String]
    location : IdlLocation
    } derive(Eq,
    Debug
    )

    IdlLocation

    pub(all) struct IdlLocation {
    source : String
    offset : Int
    line : Int
    column : Int
    } derive(Eq, ToJson,
    Debug
    )

    IdlMethod

    pub(all) struct IdlMethod {
    name : String
    return_type : IdlType
    oneway : Bool
    arguments : Array[IdlField]
    exceptions : Array[IdlField]
    annotations : Map[String, String]
    location : IdlLocation
    } derive(Eq,
    Debug
    )

    IdlModule

    pub(all) struct IdlModule {
    source : String
    includes : Array[String]
    namespaces : Map[String, String]
    cpp_includes : Array[String]
    definitions : Array[IdlDefinition]
    } derive(Eq,
    Debug
    )

    IdlType

    pub(all) enum IdlType {
    Base(String)
    Named(String)
    ListOf(IdlType)
    SetOf(IdlType)
    MapOf(IdlType, IdlType)
    } derive(Eq,
    Debug
    )

    Kind

    pub(all) enum Kind {
    BoolKind
    ByteKind
    I16Kind
    I32Kind
    I64Kind
    DoubleKind
    BinaryKind
    StructKind
    ListKind
    SetKind
    MapKind
    UuidKind
    } derive(Eq,
    Debug
    )

    Message

    pub(all) struct Message {
    name : String
    message_type : Int
    sequence_id : Int
    body : Value
    } derive(Eq,
    Debug
    )

    RPC message envelope. message_type: 1=call, 2=reply, 3=exception, 4=oneway.

    Protocol

    pub(all) enum Protocol {
    BinaryProtocol
    CompactProtocol
    } derive(Eq,
    Debug
    )

    RpcOutcome

    pub(all) enum RpcOutcome {
    Success(Json)
    DeclaredException(String, Json)
    ApplicationFailure(Int, String)
    } derive(Eq,
    Debug
    )

    Schema

    pub struct Schema {
    // private fields
    }

    Resolved IDL modules. No filesystem access is performed by this value.

    Schema::decode_json

    fn Schema::decode_json(self : Schema, name : String, data : Bytes, protocol : Protocol) -> Json raise

    Schema::describe

    fn Schema::describe(self : Schema) -> Json raise SchemaError

    Canonical resolved schema description, retaining declarations and annotations.

    Schema::encode_json

    fn Schema::encode_json(self : Schema, name : String, input : Json, protocol : Protocol) -> Bytes raise

    Schema::from_json

    fn Schema::from_json(self : Schema, name : String, input : Json) -> Value raise SchemaError

    Convert named-field JSON to a wire tree, applying explicit IDL defaults. i64 uses decimal strings, binary uses {"$binary":"hex"}, and maps use pair arrays.

    Schema::get_method

    fn Schema::get_method(self : Schema, service : String, name : String) -> IdlMethod raise SchemaError

    Schema::get_module

    fn Schema::get_module(self : Schema) -> IdlModule

    Schema::make_call

    fn Schema::make_call(self : Schema, service : String, name : String, arguments : Json, sequence_id : Int) -> Message raise SchemaError

    Schema::make_reply

    fn Schema::make_reply(self : Schema, service : String, name : String, sequence_id : Int, outcome : RpcOutcome) -> Message raise SchemaError

    Schema::read_call

    fn Schema::read_call(self : Schema, service : String, request : Message) -> Json raise SchemaError

    Schema::read_reply

    fn Schema::read_reply(self : Schema, service : String, name : String, response : Message) -> RpcOutcome raise SchemaError

    Schema::service_functions

    fn Schema::service_functions(self : Schema, service : String) -> Array[IdlMethod] raise SchemaError

    Schema::services

    fn Schema::services(self : Schema) -> Array[String]

    Schema::to_json

    fn Schema::to_json(self : Schema, name : String, value : Value) -> Json raise SchemaError

    Read a wire tree with unknown/type-mismatched fields skipped and required fields checked.

    Schema::warnings

    fn Schema::warnings(self : Schema) -> Array[String]

    Value

    pub(all) enum Value {
    Bool(Bool)
    Byte(Int)
    I16(Int)
    I32(Int)
    I64(Int64)
    Double(Double)
    Binary(Bytes)
    Struct(Array[(Int, Value)])
    List(Kind, Array[Value])
    SetValue(Kind, Array[Value])
    MapValue(Kind?, Kind?, Array[(Value, Value)])
    Uuid(Bytes)
    } derive(Eq,
    Debug
    )

    Value::kind

    fn Value::kind(self : Value) -> Kind

    application_exception

    fn application_exception(name : String, sequence_id : Int, code : Int, message : String) -> Message

    Construct standard TApplicationException without an IDL dependency.

    compile_schema

    fn compile_schema(root : String, sources : Map[String, String], include_paths? : Array[String]) -> Schema raise SchemaError

    Compile in-memory .thrift files, following includes relative to each source.

    decode

    fn decode(data : Bytes, root : Kind, protocol : Protocol) -> Value raise CodecError

    Root type is supplied by caller, as in Thrift IDL. Trailing bytes are rejected.

    decode_message

    fn decode_message(data : Bytes, protocol : Protocol, strict_read? : Bool) -> Message raise CodecError

    decode_prefix

    fn decode_prefix(data : Bytes, root : Kind, protocol : Protocol) -> (Value, Int) raise CodecError

    Read one value from a byte stream; returns the consumed byte count.

    decode_selected

    fn decode_selected(data : Bytes, fields : Array[(Int, Kind)], protocol : Protocol) -> Value raise CodecError

    Decode only requested fields of a struct. Unknown and mismatched fields are skipped on the wire. Duplicates retain wire order, as in the generic decoder.

    encode

    fn encode(value : Value, protocol : Protocol) -> Bytes raise CodecError

    encode_framed_message

    fn encode_framed_message(message : Message, protocol : Protocol, strict_write? : Bool) -> Bytes raise CodecError

    encode_message

    fn encode_message(message : Message, protocol : Protocol, strict_write? : Bool) -> Bytes raise CodecError

    Binary and Compact v1 envelopes. Binary writes strict headers by default.

    frame

    fn frame(payload : Bytes, max_frame? : Int) -> Bytes raise CodecError

    Apache TFramedTransport wire format: nonnegative signed big-endian i32 length.

    parse_idl

    fn parse_idl(text : String, source? : String) -> IdlModule raise SchemaError

    Parse one Thrift IDL document. Includes and named references are resolved by compile_schema.

    skip_prefix

    fn skip_prefix(data : Bytes, root : Kind, protocol : Protocol) -> Int raise CodecError

    Return the byte length of the first wire value, validating skipped data.