All Projects → porthos-rpc → Porthos Go

porthos-rpc / Porthos Go

Licence: other
A RPC over AMQP library for the Go programming language

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to Porthos Go

Activemq Artemis
Mirror of Apache ActiveMQ Artemis
Stars: ✭ 685 (+9685.71%)
Mutual labels:  amqp, broker
Enmasse
EnMasse - Self-service messaging on Kubernetes and OpenShift
Stars: ✭ 185 (+2542.86%)
Mutual labels:  amqp, broker
Php Amqplib
The most widely used PHP client for RabbitMQ
Stars: ✭ 3,950 (+56328.57%)
Mutual labels:  amqp
Node Celery
Celery client for Node.js
Stars: ✭ 648 (+9157.14%)
Mutual labels:  amqp
Mosquitto
Eclipse Mosquitto - An open source MQTT broker
Stars: ✭ 5,794 (+82671.43%)
Mutual labels:  broker
Stocksharp
Algorithmic trading and quantitative trading open source platform to develop trading robots (stock markets, forex, crypto, bitcoins, and options).
Stars: ✭ 4,601 (+65628.57%)
Mutual labels:  broker
Hprose Java
Hprose is a cross-language RPC. This project is Hprose 2.0 for Java
Stars: ✭ 542 (+7642.86%)
Mutual labels:  rpc-client
Xxl Mq
A lightweight distributed message queue framework.(分布式消息队列XXL-MQ)
Stars: ✭ 358 (+5014.29%)
Mutual labels:  broker
Aio Pika
AMQP 0.9 client designed for asyncio and humans.
Stars: ✭ 611 (+8628.57%)
Mutual labels:  amqp
Lapin
AMQP client library in Rust, with a clean, futures based API
Stars: ✭ 497 (+7000%)
Mutual labels:  amqp
Alibaba Rsocket Broker
Alibaba RSocket Broker: Mesh, Streaming & IoT
Stars: ✭ 485 (+6828.57%)
Mutual labels:  broker
Servicebus
Simple service bus for sending events between processes using amqp.
Stars: ✭ 415 (+5828.57%)
Mutual labels:  amqp
Hivemq Community Edition
HiveMQ CE is a Java-based open source MQTT broker that fully supports MQTT 3.x and MQTT 5. It is the foundation of the HiveMQ Enterprise Connectivity and Messaging Platform
Stars: ✭ 562 (+7928.57%)
Mutual labels:  broker
Amqp
Go client for AMQP 0.9.1
Stars: ✭ 4,170 (+59471.43%)
Mutual labels:  amqp
Graylog2 Server
Free and open source log management
Stars: ✭ 5,952 (+84928.57%)
Mutual labels:  amqp
Hyperf
🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.
Stars: ✭ 4,206 (+59985.71%)
Mutual labels:  amqp
Azure Service Bus
☁️ Azure Service Bus service issue tracking and samples
Stars: ✭ 472 (+6642.86%)
Mutual labels:  amqp
Ejabberd
Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
Stars: ✭ 5,077 (+72428.57%)
Mutual labels:  broker
Volantmq
High-Performance MQTT Server
Stars: ✭ 785 (+11114.29%)
Mutual labels:  broker
Imi
imi 是基于 Swoole 的 PHP 协程开发框架,它支持 Http、Http2、WebSocket、TCP、UDP、MQTT 等主流协议的服务开发,特别适合互联网微服务、即时通讯聊天im、物联网等场景!。QQ群:17916227
Stars: ✭ 680 (+9614.29%)
Mutual labels:  amqp

Porthos GoDoc Build Status Go Report Card License

A RPC library for the Go programming language that operates over AMQP.

Status

Beta. Server and Client API may change a bit.

Goal

Provide a language-agnostic RPC library to write distributed systems.

Client

The client is very simple. NewClient takes a broker, a service name and a timeout value (message TTL). The service name is only intended to serve as the request routing key (meaning every service name (or microservice) has its own queue). Each client declares only one response queue, in order to prevent broker's resources wastage.

Creating a new client

// first of all you need a broker
b, _ := porthos.NewBroker(os.Getenv("AMQP_URL"))
defer b.Close()

// then you create a new client (you can have as many clients as you want using the same broker)
calculatorService, _ := porthos.NewClient(b, "CalculatorService", 120)
defer calculatorService.Close()

The Call builder

.Call(methodName string)

Creates a call builder.

.WithTimeout(d duration)

Defines a timeout for the current call. Example:

calculatorService.Call("addOne").WithTimeout(2*time.Second)...

.WithMap(m map[string]interface{})

Sets the given map as the request body of the current call. The content type used is application/json. Example:

calculatorService.Call("addOne").WithMap(map[string]interface{}{"value": 20})...

.WithStruct(s interface{})

Sets the given struct as the request body of the current call. The content type used is application/json. Example:

calculatorService.Call("addOne").WithStruct(myStruct)...

.WithArgs(args ...interface{})

Sets the given args as the request body of the current call. The content type used is application/json. Example:

calculatorService.Call("add").WithArgs(1, 2)...

.WithBody(body []byte)

Sets the given byte array as the request body of the current call. The content type is application/octet-stream. Example:

calculatorService.Call("addOne").WithBody(byteArray)...

.WithBodyContentType(body []byte, contentType string)

Sets the given byte array as the request body of the current call. Also takes a contentType. Example:

calculatorService.Call("addOne").WithBodyContentType(jsonByteArrayJ, "application/json")...

.Async() (Slot, error)

Performs the remote call and returns a slot that contains the response channel. Example:

s, err := calculatorService.Call("addOne").WithArgs(1).Async()
s.Dispose()

r := <-s.ResponseChannel()
json, err := r.UnmarshalJSON()

You can easily handle timeout with a select:

select {
case r := <-s.ResponseChannel():
    json, err := r.UnmarshalJSON()
case <-time.After(2 * time.Second):
    ...
}

.Sync() (*ClientResponse, error)

Performs the remote call and returns the response. Example:

r, err := calculatorService.Call("addOne").WithMap(map[string]interface{}{"value": 20}).Sync()
json, err := r.UnmarshalJSON()

.Void() error

Performs the remote call that doesn't return anything. Example:

err := loggingService.Call("log").WithArgs("INFO", "some log message").Void()

You can find a full client example at _examples/client/example_client.go.

Server

The server also takes a broker and a service name. After that, you Register all your handlers and finally ServeForever.

Creating a new server

b, _ := porthos.NewBroker(os.Getenv("AMQP_URL"))
defer b.Close()

calculatorService, _ := porthos.NewServer(b, "CalculatorService", 10, false)
defer calculatorService.Close()

.Register(methodName string, handler MethodHandler)

Register a method with the given handler. Example:

calculatorService.Register("addOne", func(req porthos.Request, res *porthos.Response) {
    type input struct {
        Value int `json:"value"`
    }

    type output struct {
        Original int `json:"original_value"`
        Sum      int `json:"value_plus_one"`
    }

    var i input

    _ = req.Bind(&i)

    res.JSON(porthos.OK, output{i.Value, i.Value + 1})
})

.RegisterWithSpec(method string, handler MethodHandler, spec Spec)

Register a method with the given handler and a Spec. Example:

calculatorService.RegisterWithSpec("addOne", addOneHandler, porthos.Spec{
    Description: "Adds one to the given int argument",
    Request: porthos.ContentSpec{
        ContentType: "application/json",
        Body:        porthos.BodySpecFromStruct(input{}),
    },
    Response: porthos.ContentSpec{
        ContentType: "application/json",
        Body:        porthos.BodySpecFromArray(output{}),
    },
})

Through the Specs Shipper Extension the specs are shipped to a queue call porthos.specs and can be displayed in the Porthos Playground.

.AddExtension(ext Extension)

Adds the given extension to the server.

.ListenAndServe()

Starts serving RPC requests.

calculatorService.ListenAndServe()

.Close()

Close the server and AMQP channel. This method returns right after the AMQP channel is closed. In order to give time to the current request to finish (if there's one) it's up to you to wait using the NotifyClose.

.Shutdown()

Shutdown shuts down the server and AMQP channel. It provider graceful shutdown, since it will wait the result of <-s.NotifyClose().

You can find a full server example at _examples/server/example_server.go.

Extensions

Extensions can be used to add custom actions to the RPC Server. The available "events" are incoming and outgoing.

func NewLoggingExtension() *Extension {
    ext := porthos.NewExtension()

    go func() {
        for {
            select {
            case in := <-ext.Incoming():
                log.Printf("Before executing method: %s", in.Request.MethodName)
            case out := <-ext.Outgoing():
                log.Printf("After executing method: %s", out.Request.MethodName)
            }
        }
    }()

    return ext
}

Then you just have to add the extension to the server:

userService.AddExtension(NewLoggingExtension())

Built-in extensions

Metrics Shipper Extension

This extension will ship metrics to the AMQP broker, any application can consume and display them as needed.

userService.AddExtension(porthos.NewMetricsShipperExtension(broker, porthos.MetricsShipperConfig{
    BufferSize: 150,
}))

Access Log Extension

userService.AddExtension(NewAccessLogExtension())

Specs Shipper Extension

userService.AddExtension(porthos.NewSpecShipperExtension(broker))

Contributing

Please read the contributing guide

Pull requests are very much welcomed. Make sure a test or example is included that covers your change.

Docker is being used for the local environment. To build/run/test your code you can bash into the server container:

$ docker-compose run server bash
[email protected]:/go/src/github.com/porthos-rpc/porthos-go# go run example_client.go
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].