fluffle

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2016 License: MIT Imports: 7 Imported by: 1

README

fluffle-go

Build Status

This is a Go implementation of the Fluffle design for JSON-RPC over RabbitMQ. It is built for interoperability with the Ruby implementation.

Note: Due to the design of the JSON-RPC protocol it is unfeasible to safely implement batch requests on clients in a thread-safe way. Therefore batch requests are not implemented in the client.

Examples

A client is initialized with the URL string to the AMQP server. Calls can then be made to a queue on that server. The Call method will block until a response is received or times out (5 seconds).

import "github.com/Everlane/fluffle-go"

client, err := fluffle.NewClient("amqp://localhost")
if err != nil {
	panic(err)
}

resp, err := client.Call("uppercase", []interface{}{"Hello world"}, "default")
if err != nil {
	panic(err)
} else {
	fmt.Printf("%s\n", resp) // -> HELLO WORLD
}

Servers are initialized in an "empty" state; they then have their handlers and AMQP connection explicitly set up before calling Start to begin blocking for requests.

server := fluffle.NewServer()
err := server.Connect("amqp://localhost")
if err != nil {
	panic(err)
}

server.DrainFunc("default", func(req *fluffle.Request) (interface{}, error) {
	param := req.Params[0].(string)
	return strings.ToUpper(param), nil
})

// This will block the current goroutine
err = server.Start()
if err != nil {
	panic(err)
}

License

Released under the MIT license, see LICENSE for details.

Documentation

Index

Examples

Constants

View Source
const DEFAULT_EXCHANGE = ""

Variables

This section is empty.

Functions

func RequestQueueName

func RequestQueueName(name string) string

func ResponseQueueName

func ResponseQueueName(name string) string

Types

type Client

type Client struct {
	UUID          uuid.UUID
	Connection    *amqp.Connection
	Channel       *amqp.Channel
	ResponseQueue *amqp.Queue
	// contains filtered or unexported fields
}

func NewBareClient

func NewBareClient(uuid uuid.UUID) *Client

Creates a client with the given UUID and initializes its internal data structures. Does not setup connections or perform any network operations. You will almost always want to use NewClient.

func NewClient

func NewClient(url string) (*Client, error)

Create a client, connect it to the given AMQP server, and setup a queue to receive responses on.

Example
client, err := NewClient("amqp://localhost")
if err != nil {
	panic(err)
}

resp, err := client.Call("uppercase", []interface{}{"Hello world."}, "default")
if err != nil {
	panic(err)
} else {
	fmt.Printf("uppercase: %s\n", resp)
}
Output:

func (*Client) Call

func (c *Client) Call(method string, params []interface{}, queue string) (interface{}, error)

Call a remote method over JSON-RPC and return its response. This will block the goroutine on which it is called.

func (*Client) CallWithRequest

func (c *Client) CallWithRequest(request *Request, queue string) (interface{}, error)

func (*Client) DecodeResponse

func (c *Client) DecodeResponse(response *Response) (interface{}, error)

Figure out what was in the response payload: was it a result, an error, or unknown?

func (*Client) Publish

func (c *Client) Publish(payload *Request, queue string) error

payload: JSON-RPC request payload to be sent

queue: Queue on which to send the request

func (*Client) PublishAndWait

func (c *Client) PublishAndWait(payload *Request, queue string) (*Response, error)

Publishes a request onto the given queue, then waits for a response to that message on the client's response queue.

func (*Client) SetupResponseQueue

func (c *Client) SetupResponseQueue() error

Declares the response queue and starts consuming (listening) deliveries from it. This is normally the final step in setting up a usable client.

Note that this spawns a separate goroutine for handling replies from deliveries, so it does not block the calling goroutine.

type CustomError

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

func (*CustomError) Code

func (err *CustomError) Code() int

func (*CustomError) Data

func (err *CustomError) Data() interface{}

func (*CustomError) Error

func (err *CustomError) Error() string

func (*CustomError) Message

func (err *CustomError) Message() string

type Error

type Error interface {
	Code() int
	Message() string
	Data() interface{}
}

func WrapError

func WrapError(err error) Error

Wrap a normal Go error in a WrappedError struct. Skips wrapping errors that are already fluffle-go error types.

type ErrorResponse

type ErrorResponse struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

Format of an error object within a response object.

func (*ErrorResponse) Error

func (e *ErrorResponse) Error() string

type Handler

type Handler interface {
	Handle(*Request) (interface{}, error)
}

type HandlerFunc

type HandlerFunc func(*Request) (interface{}, error)

Allows ordinary functions to fulfill the Handler interface. Used by the DrainFunc method.

func (HandlerFunc) Handle

func (fn HandlerFunc) Handle(req *Request) (interface{}, error)

type MethodNotFoundError

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

func (*MethodNotFoundError) Code

func (err *MethodNotFoundError) Code() int

func (*MethodNotFoundError) Error

func (err *MethodNotFoundError) Error() string

func (*MethodNotFoundError) Message

func (err *MethodNotFoundError) Message() string

type ParseError

type ParseError struct{}

func (*ParseError) Code

func (err *ParseError) Code() int

func (*ParseError) Data

func (err *ParseError) Data() interface{}

func (*ParseError) Error

func (err *ParseError) Error() string

func (*ParseError) Message

func (err *ParseError) Message() string

type Request

type Request struct {
	JsonRpc string        `json:"jsonrpc"`
	Id      string        `json:"id"`
	Method  string        `json:"method"`
	Params  []interface{} `json:"params"`
}

type Response

type Response struct {
	JsonRpc string         `json:"jsonrpc"`
	Id      string         `json:"id"`
	Result  interface{}    `json:"result"`
	Error   *ErrorResponse `json:"error"`
}

type Server

type Server struct {
	Connection *amqp.Connection
	// contains filtered or unexported fields
}

func NewServer

func NewServer() *Server

Initialize a new server with all the necessary internal data structures.

func (*Server) Connect

func (server *Server) Connect(url string) error

Connect to an AMQP server. This should be called after initializing a server with NewServer and before calling Start.

func (*Server) Drain

func (server *Server) Drain(queue string, handler Handler)

Add a handler for a given queue.

func (*Server) DrainFunc

func (server *Server) DrainFunc(queue string, handler func(*Request) (interface{}, error))

Add a function to handle requests on a given queue.

func (*Server) Start

func (server *Server) Start() error

Declares queues for the configured handlers on the server and starts consuming payloads for those queues. This will block the caller goroutine until the server's channel is closed (eg. by calling Stop() on the server).

func (*Server) Stop

func (server *Server) Stop() error

Closes the server's channel. This will make it stop consuming payloads on its handlers' queues.

type WrappedError

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

Wraps a normal Go error to provide methods fulfilling the Error interface for use in crafting error objects in a response.

func (*WrappedError) Code

func (err *WrappedError) Code() int

func (*WrappedError) Data

func (err *WrappedError) Data() interface{}

func (*WrappedError) Message

func (err *WrappedError) Message() string

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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