thrift

package module
v0.0.0-...-c984d99 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2013 License: BSD-3-Clause Imports: 14 Imported by: 0

README

Thrift Package for Go

API Documentation: http://godoc.org/github.com/samuel/go-thrift

License

3-clause BSD. See LICENSE file.

Overview

So why another thrift package? While the existing one (thrift4go) works well, my philosophy is that interfaces should match the language. Most Thrift libraries try to match the API of the original which makes them awkward to use in other languages.

As an example, Go already has the idea of a thrift transport in the ReadWriteCloser interfaces.

Another design decision was to keep the generated code as terse as possible. The generator only creates a struct and the encoding/decoding is done through reflection. Annotations are used to set thrift ID for a field and options such as 'required'.

Example struct:

type User struct {
    Id        int64    `thrift:"1,required"`
    Name      string   `thrift:"2"`
    PostCount int32    `thrift:"3,keepempty"`
    Flags     []string `thrift:"4"`
    SomeSet   []string `thrift:"5,set"`
}

Types

Most types map directly to the native Go types, but there are some quirks and limitations.

  • Go supports a more limited set of types for map keys than Thrift

  • To use a set define the field as []type and provide a tag of "set":

      StringSet []string `thrift:"1,set"`
    
  • Unsigned types aren't supported. Thrift only has signed types. Could encode/decode unsigned types as their signed counterparts, but I decided against that for now.

  • []byte get encoded/decoded as a string because the Thrift binary type is the same as string on the wire.

RPC

The standard Go net/rpc package is used to provide RPC. Although, one incompatibility is the net/rpc's use of ServiceName.Method for naming RPC methods. To get around this the Thrift ServerCodec prefixes method names with "Thrift".

Transport

There are no specific transport "classes" as there are in most Thrift libraries. Instead, the standard io.ReadWriteCloser is used as the interface. If the value also implements the thrift.Flusher interface then Flush() error is called after protocol.WriteMessageEnd.

Framed transport is supported by wrapping a value implementing io.ReadWriteCloser with thrift.NewFramedReadWriteCloser(value)

One-way requests
Client

One-way request support needs to be enabled on the RPC codec explicitly. The reason they're not allowed by default is because the Go RPC package doesn't actually support one-way requests. To get around this requires a rather janky hack of using channels to track pending requests in the codec and faking responses.

Server

One-way requests aren't yet implemented on the server side.

Parser & Code Generator

The "parser" subdirectory contains a Thrift IDL parser, and "generator" contains a Go code generator. It could be extended to include other languages.

How to use the generator:

$ go install github.com/samuel/go-thrift/generator

$ generator --help
Usage of parsimony: [options] inputfile outputfile
  -go.binarystring=false: Always use string for binary instead of []byte
  -go.json.enumnum=false: For JSON marshal enums by number instead of name
  -go.packagename="": Override the package name
  -go.pointers=false: Make all fields pointers

$ mkdir $GOPATH/src/cassandra
$ generator cassandra.thrift $GOPATH/cassandra/thrift.go

# Then can import "cassandra"

TODO

  • "extends" for services
  • default values (is it worth it? maybe just annotations?)

Documentation

Index

Constants

View Source
const (
	TypeStop   = 0
	TypeVoid   = 1
	TypeBool   = 2
	TypeByte   = 3
	TypeI08    = 3
	TypeDouble = 4
	TypeI16    = 6
	TypeI32    = 8
	TypeI64    = 10
	TypeString = 11
	TypeUtf7   = 11
	TypeStruct = 12
	TypeMap    = 13
	TypeSet    = 14
	TypeList   = 15
	TypeUtf8   = 16
	TypeUtf16  = 17
)
View Source
const (
	ExceptionUnknown            = 0
	ExceptionUnknownMethod      = 1
	ExceptionInvalidMessageType = 2
	ExceptionWrongMethodName    = 3
	ExceptionBadSequenceId      = 4
	ExceptionMissingResult      = 5
	ExceptionInternalError      = 6
	ExceptionProtocolError      = 7
)
View Source
const (
	DefaultMaxFrameSize = 1024 * 1024
)

Variables

View Source
var (
	ErrTooManyPendingRequests = errors.New("thrift.client: too many pending requests")
	ErrOnewayNotEnabled       = errors.New("thrift.client: one way support not enabled on codec")
)
View Source
var (
	ErrUnimplemented = errors.New("thrift: unimplemented")
)

Functions

func CamelCase

func CamelCase(s string) string

func DecodeStruct

func DecodeStruct(r io.Reader, protocol Protocol, v interface{}) (err error)

func Dial

func Dial(network, address string, framed bool, protocol Protocol, supportOnewayRequests bool) (*rpc.Client, error)

Dial connects to a Thrift RPC server at the specified network address using the specified protocol.

func EncodeStruct

func EncodeStruct(w io.Writer, protocol Protocol, v interface{}) (err error)

func NewClient

func NewClient(conn io.ReadWriteCloser, protocol Protocol, supportOnewayRequests bool) *rpc.Client

NewClient returns a new rpc.Client to handle requests to the set of services at the other end of the connection.

func NewClientCodec

func NewClientCodec(conn io.ReadWriteCloser, protocol Protocol, supportOnewayRequests bool) rpc.ClientCodec

NewClientCodec returns a new rpc.ClientCodec using Thrift RPC on conn using the specified protocol.

func NewServerCodec

func NewServerCodec(conn io.ReadWriteCloser, protocol Protocol) rpc.ServerCodec

NewServerCodec returns a new rpc.ServerCodec using Thrift RPC on conn using the specified protocol.

func ReadValue

func ReadValue(r io.Reader, p Protocol, thriftType byte) (interface{}, error)

func ServeConn

func ServeConn(conn io.ReadWriteCloser, protocol Protocol)

ServeConn runs the Thrift RPC server on a single connection. ServeConn blocks, serving the connection until the client hangs up. The caller typically invokes ServeConn in a go statement.

func SkipValue

func SkipValue(r io.Reader, p Protocol, thriftType byte) error

Types

type ApplicationException

type ApplicationException struct {
	Message string `thrift:"1"`
	Type    int32  `thrift:"2"`
}

Application level thrift exception

func (*ApplicationException) String

func (e *ApplicationException) String() string

type Decoder

type Decoder interface {
	DecodeThrift(io.Reader, Protocol) error
}

type Encoder

type Encoder interface {
	EncodeThrift(io.Writer, Protocol) error
}

type ErrFrameTooBig

type ErrFrameTooBig struct {
	Size    int
	MaxSize int
}

func (*ErrFrameTooBig) Error

func (e *ErrFrameTooBig) Error() string

type Flusher

type Flusher interface {
	Flush() error
}

type FramedReadWriteCloser

type FramedReadWriteCloser struct {
	// contains filtered or unexported fields
}

func NewFramedReadWriteCloser

func NewFramedReadWriteCloser(wrapped io.ReadWriteCloser, maxFrameSize int) *FramedReadWriteCloser

func (*FramedReadWriteCloser) Close

func (f *FramedReadWriteCloser) Close() error

func (*FramedReadWriteCloser) Flush

func (f *FramedReadWriteCloser) Flush() error

func (*FramedReadWriteCloser) Read

func (f *FramedReadWriteCloser) Read(p []byte) (int, error)

func (*FramedReadWriteCloser) ReadByte

func (f *FramedReadWriteCloser) ReadByte() (byte, error)

func (*FramedReadWriteCloser) Write

func (f *FramedReadWriteCloser) Write(p []byte) (int, error)

type MissingRequiredField

type MissingRequiredField struct {
	StructName string
	FieldName  string
}

func (*MissingRequiredField) Error

func (e *MissingRequiredField) Error() string

type Protocol

type Protocol interface {
	WriteMessageBegin(w io.Writer, name string, messageType byte, seqid int32) error
	WriteMessageEnd(w io.Writer) error
	WriteStructBegin(w io.Writer, name string) error
	WriteStructEnd(w io.Writer) error
	WriteFieldBegin(w io.Writer, name string, fieldType byte, id int16) error
	WriteFieldEnd(w io.Writer) error
	WriteFieldStop(w io.Writer) error
	WriteMapBegin(w io.Writer, keyType byte, valueType byte, size int) error
	WriteMapEnd(w io.Writer) error
	WriteListBegin(w io.Writer, elementType byte, size int) error
	WriteListEnd(w io.Writer) error
	WriteSetBegin(w io.Writer, elementType byte, size int) error
	WriteSetEnd(w io.Writer) error
	WriteBool(w io.Writer, value bool) error
	WriteByte(w io.Writer, value byte) error
	WriteI16(w io.Writer, value int16) error
	WriteI32(w io.Writer, value int32) error
	WriteI64(w io.Writer, value int64) error
	WriteDouble(w io.Writer, value float64) error
	WriteString(w io.Writer, value string) error
	WriteBytes(w io.Writer, value []byte) error

	ReadMessageBegin(r io.Reader) (name string, messageType byte, seqid int32, err error)
	ReadMessageEnd(r io.Reader) error
	ReadStructBegin(r io.Reader) error
	ReadStructEnd(r io.Reader) error
	ReadFieldBegin(r io.Reader) (fieldType byte, id int16, err error)
	ReadFieldEnd(r io.Reader) error
	ReadMapBegin(r io.Reader) (keyType byte, valueType byte, size int, err error)
	ReadMapEnd(r io.Reader) error
	ReadListBegin(r io.Reader) (elementType byte, size int, err error)
	ReadListEnd(r io.Reader) error
	ReadSetBegin(r io.Reader) (elementType byte, size int, err error)
	ReadSetEnd(r io.Reader) error
	ReadBool(r io.Reader) (bool, error)
	ReadByte(r io.Reader) (byte, error)
	ReadI16(r io.Reader) (int16, error)
	ReadI32(r io.Reader) (int32, error)
	ReadI64(r io.Reader) (int64, error)
	ReadDouble(r io.Reader) (float64, error)
	ReadString(r io.Reader) (string, error)
	ReadBytes(r io.Reader) ([]byte, error)
}

func NewBinaryProtocol

func NewBinaryProtocol(strictWrite bool, strictRead bool) Protocol

func NewCompactProtocol

func NewCompactProtocol() Protocol

func NewTextProtocol

func NewTextProtocol() Protocol

type ProtocolError

type ProtocolError struct {
	Protocol string
	Message  string
}

func (ProtocolError) Error

func (e ProtocolError) Error() string

type UnsupportedTypeError

type UnsupportedTypeError struct {
	Type reflect.Type
}

func (*UnsupportedTypeError) Error

func (e *UnsupportedTypeError) Error() string

type UnsupportedValueError

type UnsupportedValueError struct {
	Value reflect.Value
	Str   string
}

func (*UnsupportedValueError) Error

func (e *UnsupportedValueError) Error() string

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL