Documentation ¶
Index ¶
- func ApplyWith[Payload any](r Registerer, apply func(Payload) error, commandNames ...string)
- func Handle[P any](ctx context.Context, bus Bus, name string, handler func(Ctx[P]) error) (<-chan error, error)
- func HandleWith[Payload any](r Registerer, handler func(Ctx[Payload]) error, commandNames ...string)
- func MustHandle[P any](ctx context.Context, bus Bus, name string, handler func(Ctx[P]) error) <-chan error
- func NewRegistry(opts ...codec.Option) *codec.Registry
- func RegisterHandler[Payload any](r Registerer, commandName string, handler func(Ctx[Payload]) error)
- type Bus
- type Cmd
- type Command
- type Context
- type ContextOption
- type Ctx
- type Data
- type DispatchConfig
- type DispatchOption
- type Dispatcher
- type Handler
- type Handlers
- type Of
- type Option
- type Registerer
- type Reporter
- type Subscriber
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyWith ¶ added in v0.1.2
func ApplyWith[Payload any](r Registerer, apply func(Payload) error, commandNames ...string)
ApplyWith registers the command applier for the given commands. When a command handler one of the given commands, it calls the provided apply function with the command payload to execute the command.
ApplyWith calls HandleWith under the hood to register the command handler.
func Handle ¶
func Handle[P any](ctx context.Context, bus Bus, name string, handler func(Ctx[P]) error) (<-chan error, error)
Handle is a shortcut for
NewHandler(bus).Handle(ctx, name, handler)
func HandleWith ¶ added in v0.1.2
func HandleWith[Payload any](r Registerer, handler func(Ctx[Payload]) error, commandNames ...string)
HandleWith is an alias for RegisterHandler.
func MustHandle ¶
func MustHandle[P any](ctx context.Context, bus Bus, name string, handler func(Ctx[P]) error) <-chan error
MustHandle is a shortcut for
NewHandler(bus).MustHandle(ctx, name, handler)
func NewRegistry ¶ added in v0.1.2
NewRegistry returns a new command registry for encoding and decoding of command payloads for transmission over a network.
func RegisterHandler ¶ added in v0.1.2
func RegisterHandler[Payload any](r Registerer, commandName string, handler func(Ctx[Payload]) error)
RegisterHandler registers the handler for the given command.
type Foo struct { *aggregate.Base *handler.BaseHandler Foo string Bar string Baz string } type FooEvent { Foo string } type BarEvent { Bar string } type BazEvent { Bar string } func NewFoo(id uuid.UUID) *Foo { foo := &Foo{ Base: aggregate.New("foo", id), Handler: handler.NewBase(), } // Register event appliers. event.ApplyWith(foo, foo.foo, "foo") event.ApplyWith(foo, foo.bar, "bar") event.ApplyWith(foo, foo.baz, "baz") // Register command handlers. command.HandleWith(foo, func(ctx command.Ctx[string]) { return foo.Foo(ctx.Payload()) }, "foo") command.HandleWith(foo, func(ctx command.Ctx[string]) { return foo.Bar(ctx.Payload()) }, "bar") command.HandleWith(foo, func(ctx command.Ctx[string]) { return foo.Baz(ctx.Payload()) }, "baz") return foo } func (f *Foo) Foo(input string) error { aggregate.Next(f, "foo", FooEvent{Foo: input}) } func (f *Foo) foo(e event.Of[FooEvent]) { f.Foo = e.Data().Foo } func (f *Foo) Bar(input string) error { aggregate.Next(f, "bar", BarEvent{Bar: input}) } func (f *Foo) bar(e event.Of[BarEvent]) { f.Bar = e.Data().Bar } func (f *Foo) Baz(input string) error { aggregate.Next(f, "baz", BazEvent{Baz: input}) } func (f *Foo) baz(e event.Of[BazEvent]) { f.Baz = e.Data().Baz }
Types ¶
type Cmd ¶
Cmd is the command implementation.
func Cast ¶ added in v0.1.2
Cast casts the payload of the given command to the given `To` type. If the payload is not of type `To`, Cast panics.
func New ¶
New returns a new command with the given name and payload. A random UUID is generated and set as the command id.
func TryCast ¶ added in v0.1.2
TryCast tries to cast the payload of the given command to the given `To` type. If the payload is not of type `To`, false is returned.
func (Cmd[P]) Aggregate ¶
func (cmd Cmd[P]) Aggregate() event.AggregateRef
Aggregate returns the aggregate that the command acts on.
type ContextOption ¶ added in v0.1.2
type ContextOption func(*options)
ContextOption is a Context option.
type Ctx ¶ added in v0.1.2
type Ctx[P any] interface { context.Context Of[P] // AggregateID returns the id of the aggregate that the command is linked to, // or uuid.Nil if no aggregate was linked to this command. AggregateID() uuid.UUID // AggregateName returns the name of the aggregate that the command is linked to, // or "" if no aggregate was linked to this command. AggregateName() string // Finish should be called after the command has been handled to notify the // dispatcher bus about the execution result. If a command was dispatched // synchronously, Finish must be called; otherwise the dispatcher bus will // never return. Finish(context.Context, ...finish.Option) error }
Ctx is the context of a dispatched command with a specific payload type.
func CastContext ¶ added in v0.1.2
CastContext casts the payload of the given context to the given `To` type. If the payload is not a `To`, CastContext panics.
func NewContext ¶ added in v0.1.2
NewContext returns a context for the given command.
type Data ¶
type Data[Payload any] struct { ID uuid.UUID Name string Payload Payload AggregateName string AggregateID uuid.UUID }
Data contains the fields of a Cmd.
type DispatchConfig ¶
type DispatchConfig struct { // A synchronous dispatch waits for the execution of the Command to finish // and returns the execution error if there was any. // // A dispatch is automatically made synchronous when Repoter is non-nil. Synchronous bool // If Reporter is not nil, the Bus will report the execution result of a // Command to Reporter by calling Reporter.Report(). // // A non-nil Reporter makes the dispatch synchronous. Reporter Reporter }
Config is the configuration for dispatching a command.
type DispatchOption ¶
type DispatchOption func(*DispatchConfig)
DispatchOption is an option for dispatching commands.
type Dispatcher ¶ added in v0.1.2
type Dispatcher interface { // Dispatch dispatches the provided command to subscribers of the command. // // Depending on the implementation, the command may be dispatched to a // single or multiple subscribers. The implementation provided by the // `cmdbus` package ensures that a command is dispatched to at most one // subscriber. Dispatch(context.Context, Command, ...DispatchOption) error }
A Dispatcher dispatches commands to subscribed handlers.
type Handler ¶
type Handler[P any] struct { // contains filtered or unexported fields }
Handler wraps a Bus to provide a convenient way to subscribe to and handle commands.
func NewHandler ¶
NewHandler wraps the provided Bus in a *Handler.
func (*Handler[P]) Handle ¶
func (h *Handler[P]) Handle(ctx context.Context, name string, handler func(Ctx[P]) error) (<-chan error, error)
Handle registers the provided function as a handler for the given command. Handle subscribes to the command over the underlying Bus. The command.Context returned by the Bus is passed to the provided handler function. Afterwards, the `Finish` method of the command.Context is called by *Handler to report the execution result of the command.
Handle returns a channel of asynchronous errors. Users are responsible for receiving the errors from the channel, to avoid blocking. Errors that are sent into the channel are
- all asynchronous errors from the underlying Bus
- all errors returned by the provided handler function
- errors returned by the `Finish` method of command.Context
When ctx is canceled, the returned error channel is closed.
type Handlers ¶ added in v0.2.2
Handlers is a map of event names to command handlers. Handlers can be embedded into structs to implement Registerer.
func (Handlers) CommandHandler ¶ added in v0.2.2
CommandHandlers returns the handlers for the given command.
func (Handlers) CommandNames ¶ added in v0.2.4
CommandNames returns the registered command names.
func (Handlers) HandleCommand ¶ added in v0.2.2
HandleEvent calls the registered handler of the given Command.
func (Handlers) RegisterCommandHandler ¶ added in v0.2.2
RegisterCommandHandler implements Registerer.
type Of ¶ added in v0.1.2
type Of[Payload any] interface { // ID returns the command id. ID() uuid.UUID // Name returns the command name. Name() string // Payload returns the command payload. Payload() Payload // Aggregate returns the aggregate this command acts on. Aggregate() event.AggregateRef }
Of is a command with the given specific payload type. A command has a unique id, a name, and a user-provided payload. A command can optionally provide the aggregate that it acts on.
type Option ¶
Option is an option for creating a command.
type Registerer ¶ added in v0.1.2
type Registerer interface { // RegisterCommandHandler registers a command handler for the given command name. RegisterCommandHandler(commandName string, handler func(Context) error) }
A Registerer is a type that can register handlers for different commands.
type Subscriber ¶ added in v0.1.2
type Subscriber interface { // Subscribe subscribes to the given commands and returns two channels – // a Context channel and an error channel. When a command is dispatched to // this subscriber, a new Context is sent into the Context channel. Context // is a context.Context that additionally provides the dispatched command data. // // var bus command.Bus // // Subscribe to "foo" and "bar" commands. // res, errs, err := bus.Subscribe(context.TODO(), "foo", "bar") // // handle err // for ctx := range res { // log.Printf( // "Handling %q command ... [aggregate_name: %q, aggregate_id: %q]", // ctx.Name(), ctx.AggregateName(), ctx.AggregateID(), // ) // // log.Printf("Payload:\n%v", ctx.Payload()) // } Subscribe(ctx context.Context, names ...string) (<-chan Context, <-chan error, error) }
A Subscriber subscribes to commands that are dispatched by a Dispatcher.