cbus

package module
v3.1.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2017 License: MIT Imports: 4 Imported by: 6

README

cbus

A command bus for executing arbitrary commands.

Golang Version

This package requires Go version 1.7 or higher because it uses the newly added context package.

Status

Build Status Coverage Status Go Report Card

Documentation and Usage

Full documentation and examples can be found at GoDoc

Documentation

Overview

Package cbus provides a Command Bus implementation that allows client code to execute arbitrary commands with a given handler.

Example

type User struct {
	Name string
}

type CreateUserCommand struct {
	Name string
}

func (cuc *CreateUserCommand) Type() string {
	return "CreateUser"
}

func main() {
	bus := &Bus{}

	bus.Handle(&CreateUserCommand{}, HandlerFunc(func(ctx context.Context, command Command) (interface{}, error) {
		user := &User{
			Name: command.(*CreateUserCommand).Name,
		}
		return user, nil
	}))

	ctx, _ := context.WithTimeout(context.Background(), time.Duration(5)*time.Second)
	result, _ := bus.ExecuteContext(
		ctx,
		&CreateUserCommand{"Mr. Foo Bar"},
	)

	fmt.Println(result.(*User).Name) //Mr. Foo Bar
}

This package requires Go version 1.7 or higher because it uses the context package.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsHandlerNotFoundError

func IsHandlerNotFoundError(err error) bool

IsHandlerNotFoundError determines whether or not err is of type *HandlerNotFoundError.

Types

type Bus

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

Bus is the Command Bus implementation. A Bus contains a one to one mapping from Command types to Handlers. The reflect.TypeOf interface is used as keys to map from Commands to Handlers. It additionally contains Listeners that are called during specific steps during a Command's execution.

All Command Handlers and Event Listeners are called from a Bus in a newly spawned goroutine per Command execution. The Before Listeners are called just before the Command's Handler is called. The Command Handler will not be called until the optional Listeners have returned. After the Command Handler returns, either the AfterSuccess or AfterError Listeners will be called depending on the existence of err returned from the Handler. The Complete Listeners are called after the After* events regardless of successful or errored results from the Handler. All registered Listeners are called in the order they were added via Listen().

The zero value for Bus is fully functional. Type Bus is safe for use by multiple goroutines.

func (*Bus) Execute

func (b *Bus) Execute(command Command) (result interface{}, err error)

Execute is sugar for b.ExecuteContext(context.Background(), command).

func (*Bus) ExecuteContext

func (b *Bus) ExecuteContext(ctx context.Context, command Command) (result interface{}, err error)

ExecuteContext attempts to find a Handler for command's Type(). If a Handler is not found, then ErrHandlerNotFound is returned immediately. If a Handler is found, then a new goroutine is spawned and all registered Before Listeners are called, followed by command's Handler, finally followed by all registered After* and Complete Listeners.

If ctx.Done() is closed before the event Listeners and command Handler complete, then ctx.Err() is returned with a nil result.

func (*Bus) Handle

func (b *Bus) Handle(command Command, handler Handler) (prev Handler)

Handle associates a Handler in b that will be called when a Command whose type equals command's type. Only one Handler is allowed per Command type. Any previously added Handlers with the same commandType will be overwritten. prev is the Handler previously associated with commandType if it exists.

func (*Bus) Listen

func (b *Bus) Listen(et EventType, lis Listener)

Listen registers lis to be called for all Commands at the time in the Command lifecycle denoted by et. A value for et that is not documented in this package will never be called.

func (*Bus) ListenCommand

func (b *Bus) ListenCommand(et EventType, command Command, lis Listener)

ListenCommand registers lis to be called for Commands of the same type as command at the time in the Command lifecycle denoted by et. A value for et that is not documented in this package will never be called.

func (*Bus) RemoveHandler

func (b *Bus) RemoveHandler(command Command) Handler

RemoveHandler removes the Handler associated with Command's type and returns it. This is a no-op and returns nil if a Handler does not exist for command.

func (*Bus) RemoveListener

func (b *Bus) RemoveListener(et EventType, lis Listener) bool

RemoveListener removes all Listeners that match lis (via ==) and et. The return value indicates if any Listeners were removed.

func (*Bus) RemoveListenerCommand

func (b *Bus) RemoveListenerCommand(et EventType, command Command) []Listener

RemoveListenerCommand remove all Listeners that were registered with Command type equal to command's and et. It returns all removed Listeners.

type Command

type Command interface{}

Command is an empty interface that anything can implement and allows for executing arbitrary values on a Bus. Therefore, a Command is any defined type that get associated with Handler. The specific implementation of a Command can then carry the payload for the command to execute.

type Event

type Event struct {
	//EventType is the type of the Event. This will designate what part of the
	//lifecycle a Command is in.
	EventType

	//Result is the possible result of that occurred during a Command Handler's execution.
	//Result will be nil on Before and AfterError Events.
	//It will be the result value that occurred for AfterSuccess and Complete Events
	//if there was a result.
	Result interface{}

	//Err is the possible error that occurred during a Command Handler's execution.
	//Err will be nil on Before and AfterSuccess Events.
	//It will be the error that occurred for AfterError and Complete Events if there
	//was an error.
	Err error

	//Command is the Command that is executing or has completed execution.
	Command
}

Event is the type that is emitted during a Command's lifecycle.

type EventType

type EventType string

EventType is an enumeration of types of events that occur in a Command's execution lifecycle.

const (
	//Before denotes Events that are called after a Handler has been found for a
	//Command but before the Command's Handler is called.
	Before EventType = "Before"

	//AfterSuccess denotes Events that are called after a Command's Handler has
	//returned with a nil error.
	AfterSuccess EventType = "AfterSuccess"

	//AfterError denotes Events that are called after a Command's Handler has
	//returned with a non-nil error.
	AfterError EventType = "AfterError"

	//Complete denotes Events that are called after a Command's Handler has
	//returned regardless of successful or error completion.
	//The Complete Event is called after all prior After* Events have completed.
	Complete EventType = "Complete"
)

type ExecutionPanicError

type ExecutionPanicError struct {
	//Panic is the value received from recover() if not nil.
	Panic interface{}
}

ExecutionPanicError occurs when a Handler or Listener panics during execution.

func (*ExecutionPanicError) Error

func (e *ExecutionPanicError) Error() string

Error is the error implementation.

type Handler

type Handler interface {
	Handle(ctx context.Context, command Command) (result interface{}, err error)
}

Handler defines the contract for executing a Command within a context.Context. The result and err return parameters will be returned from Bus.Execute*() calls which allows Command executors to know the results of the Command's execution.

type HandlerFunc

type HandlerFunc func(ctx context.Context, command Command) (result interface{}, err error)

HandlerFunc is a function definition for a Handler.

func (HandlerFunc) Handle

func (hf HandlerFunc) Handle(ctx context.Context, command Command) (result interface{}, err error)

Handle calls hf with ctx and command.

type HandlerNotFoundError

type HandlerNotFoundError struct {
	//Command is the Command that a Handler was not found for.
	Command
}

HandlerNotFoundError occurs when a Handler has not been registered for a Command's type.

func (*HandlerNotFoundError) Error

func (e *HandlerNotFoundError) Error() string

Error is the error implementation.

type Listener

type Listener interface {
	OnEvent(ctx context.Context, event Event)
}

Listener defines the contract for responding to an Event during a Command's lifecycle.

type ListenerFunc

type ListenerFunc func(ctx context.Context, event Event)

ListenerFunc if a function implementation of a Listener.

func (ListenerFunc) OnEvent

func (lf ListenerFunc) OnEvent(ctx context.Context, event Event)

OnEvent calls lf with ctx and event.

Jump to

Keyboard shortcuts

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