-
Notifications
You must be signed in to change notification settings - Fork 1
/
bus.go
68 lines (59 loc) · 2.45 KB
/
bus.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package dew
import (
"context"
)
// Bus contains the core methods for dispatching commands.
type Bus interface {
// Register adds the handler to the mux for the given command type.
// It finds the handler methods that have the following signature:
//
// func (h *Handler) FooMethod(ctx context.Context, command *BarCommand) error
Register(handler any)
// Use appends the middlewares to the mux middleware chain.
// The middleware chain will be executed in the order they were added.
// These middlewares are executed per command instead of per dispatch / query.
Use(op OpType, middlewares ...func(next Middleware) Middleware)
// Group creates a new mux with a copy of the parent middlewares.
Group(fn func(mx Bus)) Bus
// UseDispatch appends the middlewares to the dispatch middleware chain.
// Dispatch middlewares are executed only once per dispatch instead of per command.
UseDispatch(middlewares ...func(next Middleware) Middleware)
// UseQuery appends the middlewares to the query middleware chain.
// Query middlewares are executed only once per query instead of per command.
UseQuery(middlewares ...func(next Middleware) Middleware)
}
type busKey struct{}
// NewContext creates a new context with the given bus.
func NewContext(ctx context.Context, bus Bus) context.Context {
return context.WithValue(ctx, busKey{}, bus)
}
// FromContext returns the bus from the context.
func FromContext(ctx context.Context) (Bus, bool) {
bus, ok := ctx.Value(busKey{}).(Bus)
return bus, ok
}
// MustFromContext returns the bus from the context, panicking if not found.
func MustFromContext(ctx context.Context) Bus {
bus, ok := FromContext(ctx)
if !ok {
panic("bus not found in context")
}
return bus
}
// Context represents the context for a command execution.
type Context interface {
// Context returns the underlying context.Context.
Context() context.Context
// WithContext returns a new Context with the given context.
WithContext(ctx context.Context) Context
// WithValue returns a new Context with the given key-value pair added to the context.
WithValue(key, val any) Context
// Command returns the command object to be processed.
Command() Command
}
// HandlerFunc defines a function type that takes a context and a command, returning an error.
type HandlerFunc[T any] func(ctx context.Context, command *T) error
// Handle calls the function f(ctx, command).
func (f HandlerFunc[T]) Handle(ctx context.Context, command *T) error {
return f(ctx, command)
}