Documentation
¶
Index ¶
- Constants
- Variables
- func SetResponderChain(ctx context.Context, inst *Chain) (context.Context, error)
- func SetResponderChainIfAbsent(ctx context.Context, inst *Chain) (context.Context, error)
- func WithResponderChain(ctx context.Context, fn func(*Chain))
- type Chain
- func (chain *Chain) Add(responder Respondable) (Respondable, error)
- func (chain *Chain) AddNamed(name string, responder Respondable) (Respondable, error)
- func (chain *Chain) AddNamedWithPriority(name string, responder Respondable, priority int) (Respondable, error)
- func (chain *Chain) AddOrReplace(responder Respondable) Respondable
- func (chain *Chain) AddOrReplaceNamed(name string, responder Respondable) Respondable
- func (chain *Chain) AddOrReplaceNamedWithPriority(name string, responder Respondable, priority int) Respondable
- func (chain *Chain) AddOrReplaceWithPriority(responder Respondable, priority int) Respondable
- func (chain *Chain) AddWithPriority(responder Respondable, priority int) (Respondable, error)
- func (chain *Chain) Clear()
- func (chain *Chain) Count() int
- func (chain *Chain) Invoke(event events.Event) events.Event
- func (chain *Chain) IsEmpty() bool
- func (chain *Chain) MustSendFirst(event events.Event) events.Event
- func (chain *Chain) MustSendNamed(name string, event events.Event) events.Event
- func (chain *Chain) Name() string
- func (chain *Chain) Names() []string
- func (chain *Chain) Remove(responder Respondable) bool
- func (chain *Chain) RemoveNamed(name string) bool
- func (chain *Chain) RespondsTo(event events.Event) bool
- func (chain *Chain) SendAll(event events.Event) []events.Event
- func (chain *Chain) SendFirst(event events.Event) (events.Event, bool)
- func (chain *Chain) SendNamed(name string, event events.Event) (events.Event, bool, bool)
- func (chain *Chain) SendType(typeName string, event events.Event) []events.Event
- func (chain *Chain) Type() string
- type Respondable
Constants ¶
const ContextKeyResponderChain = "gohacks/responder@v1"
Key used to store the instance in the context's user value.
Variables ¶
var ( // Error condition signalled when an attempt is made to add a // non-unique responder to a responder chain. ErrDuplicateResponder error = errors.Base("duplicate responder") // Error condition signalled when a responder's name via `Name()` is // invalid or zero length. ErrResponderNameInvalid error = errors.Base("responder name invalid") )
var ErrValueNotResponderChain = errors.Base("value is not *Chain")
Signalled if the instance associated with the context key is not of type *Chain.
Functions ¶
func SetResponderChain ¶ added in v1.0.6
Set ResponderChain stores the instance in the context map.
func SetResponderChainIfAbsent ¶ added in v1.0.6
SetResponderChainIfAbsent sets only if not already present.
func WithResponderChain ¶ added in v1.0.6
WithResponderChain calls fn with the instance or fallback.
Types ¶
type Chain ¶
type Chain struct {
// contains filtered or unexported fields
}
Responder chain structure.
This attempts to bring a little bit of Smalltalk and Objective-C to the wonderful world of Go.
It might also attempt to bring a bit of MIT Flavors, too... but don't expect to see crazy like `defwrapper` and `defwhopper`.
func FromResponderChain ¶ added in v1.0.6
FromResponderChain returns the instance or the fallback.
func GetResponderChain ¶ added in v1.0.6
Get the logger from the given context.
Will return ErrValueNotResponderChain if the value in the context is not of type *Chain.
func MustGetResponderChain ¶ added in v1.0.6
Attempt to get the instance from the given context. Panics if the operation fails.
func TryGetResponderChain ¶ added in v1.0.6
TryGetResponderChain returns the instance and true if present and typed.
func (*Chain) Add ¶
func (chain *Chain) Add(responder Respondable) (Respondable, error)
Adds a responder to the responder chain.
The responder will have a default priority of 0.
Returns `ErrDuplicateResponder` if a non-unique responder is added.
func (*Chain) AddNamed ¶
func (chain *Chain) AddNamed(name string, responder Respondable) (Respondable, error)
Adds the supplied responder to the chain using a user-specified name.
The given name overrides that provided by the `Name()` method in the responder, thus should only be used in use-cases where you need a specific identifier for a responder.
The responder will have a default priority of 0.
Returns `ErrDuplicateResponder` if a non-unique responder is added.
func (*Chain) AddNamedWithPriority ¶
func (chain *Chain) AddNamedWithPriority( name string, responder Respondable, priority int, ) (Respondable, error)
Adds the supplied responder to the chain using a user-specified name and priority.
The given name overrides that provided by the `Name()` method in the responder, thus should only be used in use-cases where you need a specific identifier for a responder.
Returns `ErrDuplicateResponder` if a non-unique responder is added.
func (*Chain) AddOrReplace ¶
func (chain *Chain) AddOrReplace(responder Respondable) Respondable
Adds a responder to the responder chain.
The responder will have a default priority of 0.
If the responder already exists in the chain then it is replaced with the provided responder.
func (*Chain) AddOrReplaceNamed ¶
func (chain *Chain) AddOrReplaceNamed(name string, responder Respondable) Respondable
Adds the supplied responder to the chain using a user-specified name.
The responder will have a default priority of 0.
If the responder already exists in the chain then it is replaced with the provided responder.
The given name overrides that provided by the `Name()` method in the responder, thus should only be used in use-cases where you need a specific identifier for a responder.
func (*Chain) AddOrReplaceNamedWithPriority ¶
func (chain *Chain) AddOrReplaceNamedWithPriority( name string, responder Respondable, priority int, ) Respondable
Adds the supplied responder to the chain using a user-specified name and priority.
If the responder already exists in the chain then it is replaced with the provided responder.
The given name overrides that provided by the `Name()` method in the responder, thus should only be used in use-cases where you need a specific identifier for a responder.
func (*Chain) AddOrReplaceWithPriority ¶
func (chain *Chain) AddOrReplaceWithPriority(responder Respondable, priority int) Respondable
Adds a responder to the responder chain.
If the responder already exists in the chain then it is replaced with the provided responder.
func (*Chain) AddWithPriority ¶
func (chain *Chain) AddWithPriority(responder Respondable, priority int) (Respondable, error)
Adds the supplied responder to the chain using the given priority.
Returns `ErrDuplicateResponder` if a non-unique responder is added.
func (*Chain) Invoke ¶
Send an event to the chain.
The first object that can respond to the event will consume it.
Implements `Respondable`.
func (*Chain) MustSendFirst ¶
Send a message to the responder chain. Panics if no responder is able to respond to the event.
func (*Chain) MustSendNamed ¶
Send a message to a specific responder. Panics if the responder does not exist or does not respond to the event.
func (*Chain) Remove ¶
func (chain *Chain) Remove(responder Respondable) bool
func (*Chain) RemoveNamed ¶
Remove the named responder from the responder chain.
Returns false if no such responder was found.
func (*Chain) RespondsTo ¶
Iterate over responders checking if any implement the given event.
The first responder found that responds to the event will result in `true` being returned.
Implements `Respondable`.
func (*Chain) SendAll ¶
Send a message to all responders in the chain.
All responders capable of responding to the event will receive the event.
Returns a list of objects of interface `events.Event`, which may be the same event as was passed. Doing sanity on the return values is up to you
This method is thread-safe.
func (*Chain) SendFirst ¶
Send a message to the responder chain.
The first responder capable of responding to the event will consume the event.
Returns an object of interface `events.Event`, which may be the same event that was passed to it. Doing sanity on the return value is up to you.
Unlike `SendNamed`, there is no indicator that either receivers were not found or that there were no receivers. So it would be wise to assume that a `false` means that absolutely nothing in the chain received your event.
Example usage would be:
```go
result, ok := someChain.Send(evt)
if !ok {
log.Warn("No responders have responded to the event.")
} else {
log.Info("At least one responder has responded to the event.")
}
```
This method is thread-safe.
func (*Chain) SendNamed ¶
Send a message to a specific responder.
Returns an object of interface `events.Event`, which may be the same event that was passed to it. Doing sanity on the return value is up to you. Returns the resulting event from the responder, a boolean value that states if the responder was able to respond, and a boolean value that states whether the responder was found.
Example usage would be:
```go
result, responds, found := someChain.SendNamed("something", evt)
if !found {
log.Warn("Responder `something` not found!")
} else if !responds {
log.Info("Responder 'something' ignored the event.")
} else {
log.Debug("Event was handled.")
}
```
This method is thread-safe.
func (*Chain) SendType ¶
Send a message to all responders of a given type in the chain.
All responders of the given type that are capable of responding to the event will receive the event.
Returns a list of objects of interface `events.Event`, which may be the same event as was passed. Doing sanity on the return values is up to you.
This method is thread-safe.
type Respondable ¶
type Respondable interface {
// A unique name for the respondable object.
//
// As this allows us to send events to a specific thing the value
// returned here must be unique.
Name() string
// The type of the respondable object.
//
// This can be the internal Go type, or some arbitrary user-specified
// value that makes sense to you.
//
// This is used to implement a "send to all of type" system.
Type() string
// Does the receiver respond to a specific event or event type?
//
// There is no definition for what `RespondsTo` should do other than
// return a boolean that states whether an object responds to an
// event or not.
RespondsTo(events.Event) bool
// Send an event to the object.
//
// There is no second return value to indicate success or whether
// the event was handled or not. The idea being that the receiver
// will send an `events.Response` event back.
Invoke(events.Event) events.Event
}
Objects the implement these methods are considered `respondable` and are deemed capable of being sent messages directly or via responder chain.