rbus

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Mar 23, 2021 License: MIT Imports: 3 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrReservation = errors.New("double reservation requested for channel name")

ErrReservation is an error raised if a name is reserved twice with the message bus

View Source
var ErrUnknownService = errors.New("the requested service does not exist yet")

ErrUnknownService is the response a service gets if it requests a handler that does not exist yet

Functions

This section is empty.

Types

type Rbus

type Rbus interface {
	Register(serviceName string, capacity uint16) (<-chan Request, error)
	Request(serviceName string, timeOut time.Duration, request interface{}) (Response, error)
}

Rbus is a request bus interface for inter service communication. The actual implementation is in this file as well and may be constructed by invoking NewRBus()

This request bus is a many-to-one message bus. IE: Many services can talk to a single registered service by name. The service that calls Register() should listen to the returned channel in a loop and launch a handler for each request. The bus is safe against races and deadlocks under a few assumptions. In order use this bus in a safe manner, the code that uses this bus must follow this contract. The description follows:

A request that is sent BEFORE a service has been registered MUST use a timeout OR MUST gracefully handle an ErrUnknownService response.

A request that is sent BEFORE a service has been registered AND DOES use a timeout, MUST check the response in a select statement that also checks for a timeout.

If a program may have a message sent to a service that does not exist before the message is sent, the program SHOULD assume that a timeout is an uncaught exception and unwind. This recommendation is to prevent a bad service name from silently causing a memory leak.

If a service sends a request with a timeout, it MUST check the timeout to prevent memory leaks, but MAY continue operation IFF the service is guaranteed to have existed before any message could have been sent.

The service does not have to check for timeouts before writing a response. The service can pre-emptively quit processing a response if a time out occurs before processing starts or at any time during. Once a timeout occurs, there is no guarantee if the requestee will get a timeout or the response. This is because a select statement returns a random item if more than one is available.

If a timeout occurs before a message may be placed on the bus, the message will never enter the bus. This is to provide backpressure for an overloaded service. The backpressure limit is set by the request channel capacity.

If a requester calls Request() using a timeout of zero, no timeout signal will ever be fired. Specifically, the timeout channel will not be constructed. This means if a timeout of zero is used, any go routine that calls Timeout() outside of a Go routine MUST do so in a select statement. This requirement MUST be observed to prevent deadlocks from waiting for a non-existent channel.

The consuming service MUST always call Timeout() in a select statement if the service does call timeout. Once again, the service does not have to listen for a timeout, but if it does it must do it in a select.

func NewRBus

func NewRBus() Rbus

NewRBus returns a Request Bus as an interface.

type Request

type Request interface {
	Timeout() <-chan struct{}
	Request() interface{}
	Respond(interface{})
}

Request is the interface handed to the handler of a request from the bus

type Response

type Response interface {
	Timeout() <-chan struct{}
	Response() <-chan interface{}
}

Response is the interface handed back to the caller of the request bus

Jump to

Keyboard shortcuts

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