Documentation
¶
Index ¶
- Constants
- func EventDispatcherMustFromContainer(serviceContainer containercontract.Container) eventcontract.EventDispatcher
- func EventDispatcherMustFromResolver(resolver containercontract.Resolver) eventcontract.EventDispatcher
- type Event
- type EventDispatcher
- func (instance *EventDispatcher) AddListener(eventName string, listener eventcontract.EventListener, priority int) eventcontract.ListenerRegistration
- func (instance *EventDispatcher) AddSubscriber(subscriber eventcontract.EventSubscriber)
- func (instance *EventDispatcher) Dispatch(runtimeInstance runtimecontract.Runtime, event eventcontract.Event) (eventcontract.Event, error)
- func (instance *EventDispatcher) DispatchName(runtimeInstance runtimecontract.Runtime, eventName string, payload any) (eventcontract.Event, error)
- func (instance *EventDispatcher) MarkListenerMaySkipRequiredListeners(registration eventcontract.ListenerRegistration)
- func (instance *EventDispatcher) MarkListenerRequired(registration eventcontract.ListenerRegistration)
- func (instance *EventDispatcher) RegisteredEvents() []eventcontract.RegisteredEvent
- func (instance *EventDispatcher) RemoveListener(registration eventcontract.ListenerRegistration) bool
- func (instance *EventDispatcher) RemoveSubscriber(subscriber eventcontract.EventSubscriber) int
- type EventDispatcherAdapter
- func (instance *EventDispatcherAdapter) AddListener(eventName string, listener eventcontract.EventListener, priority int) eventcontract.ListenerRegistration
- func (instance *EventDispatcherAdapter) AddSubscriber(subscriber eventcontract.EventSubscriber)
- func (instance *EventDispatcherAdapter) Dispatch(runtimeInstance runtimecontract.Runtime, eventValue eventcontract.Event) (eventcontract.Event, error)
- func (instance *EventDispatcherAdapter) DispatchName(runtimeInstance runtimecontract.Runtime, eventName string, payload any) (eventcontract.Event, error)
- func (instance *EventDispatcherAdapter) MarkListenerMaySkipRequiredListeners(registration eventcontract.ListenerRegistration)
- func (instance *EventDispatcherAdapter) MarkListenerRequired(registration eventcontract.ListenerRegistration)
- func (instance *EventDispatcherAdapter) RegisteredEvents() []eventcontract.RegisteredEvent
- func (instance *EventDispatcherAdapter) RemoveListener(registration eventcontract.ListenerRegistration) bool
- func (instance *EventDispatcherAdapter) RemoveSubscriber(subscriber eventcontract.EventSubscriber) int
- type RequiredListenerSkippedError
- func NewRequiredListenerSkippedError(eventName string, stoppedByListenerName string) *RequiredListenerSkippedError
- func NewRequiredListenerSkippedErrorWithCause(eventName string, failedListenerName string, cause error) *RequiredListenerSkippedError
- func NewRequiredListenerSkippedErrorWithStoppedListenerFailure(eventName string, stoppedByListenerName string, cause error) *RequiredListenerSkippedError
- type SubscribedEvent
Constants ¶
const (
ServiceEventDispatcher = "service.event.dispatcher"
)
Variables ¶
This section is empty.
Functions ¶
func EventDispatcherMustFromContainer ¶
func EventDispatcherMustFromContainer(serviceContainer containercontract.Container) eventcontract.EventDispatcher
func EventDispatcherMustFromResolver ¶
func EventDispatcherMustFromResolver(resolver containercontract.Resolver) eventcontract.EventDispatcher
Types ¶
type Event ¶
type Event struct {
// contains filtered or unexported fields
}
Event is not safe for concurrent use. The dispatcher runs the listeners of one dispatch in sequence, so a listener sees every write a listener before it made; dispatching one event value from two goroutines, or writing to it from a goroutine a listener started, races on the propagation flag. Give each dispatch its own event.
func NewEvent ¶
func NewEvent( name string, payload any, clockInstance clockcontract.Clock, ) *Event
func NewEventFromEvent ¶
func NewEventFromEvent(event eventcontract.Event) *Event
func NewEventWithTimestamp ¶
func (*Event) IsPropagationStopped ¶
func (*Event) StopPropagation ¶
func (instance *Event) StopPropagation()
type EventDispatcher ¶
type EventDispatcher struct {
// contains filtered or unexported fields
}
func NewEventDispatcher ¶
func NewEventDispatcher(clock clockcontract.Clock) *EventDispatcher
func (*EventDispatcher) AddListener ¶
func (instance *EventDispatcher) AddListener( eventName string, listener eventcontract.EventListener, priority int, ) eventcontract.ListenerRegistration
func (*EventDispatcher) AddSubscriber ¶
func (instance *EventDispatcher) AddSubscriber(subscriber eventcontract.EventSubscriber)
func (*EventDispatcher) Dispatch ¶
func (instance *EventDispatcher) Dispatch(runtimeInstance runtimecontract.Runtime, event eventcontract.Event) (eventcontract.Event, error)
func (*EventDispatcher) DispatchName ¶
func (instance *EventDispatcher) DispatchName(runtimeInstance runtimecontract.Runtime, eventName string, payload any) (eventcontract.Event, error)
func (*EventDispatcher) MarkListenerMaySkipRequiredListeners ¶ added in v2.9.0
func (instance *EventDispatcher) MarkListenerMaySkipRequiredListeners(registration eventcontract.ListenerRegistration)
MarkListenerMaySkipRequiredListeners flags the registered listener so that when it stops propagation it is allowed to skip required listeners behind it without failing dispatch — the explicit opt-out that restores the plain stop-and-proceed behavior for a listener that knowingly short-circuits.
func (*EventDispatcher) MarkListenerRequired ¶ added in v2.9.0
func (instance *EventDispatcher) MarkListenerRequired(registration eventcontract.ListenerRegistration)
MarkListenerRequired flags the registered listener so that if another listener stops event propagation before it runs, dispatch returns a RequiredListenerSkippedError and the caller can fail closed. An unknown registration is refused rather than ignored: a mark that lands nowhere leaves the guarantee unarmed while reporting that it was applied, and the caller has no way to tell.
The mark necessarily follows the registration it takes as its argument, so a dispatch running between the two steps sees the listener unmarked and a stop in that window skips it without the error. Registration at boot — before anything dispatches — closes the window; a runtime registrar that needs the guarantee armed atomically must not dispatch the event until the mark is applied.
func (*EventDispatcher) RegisteredEvents ¶
func (instance *EventDispatcher) RegisteredEvents() []eventcontract.RegisteredEvent
RegisteredEvents reports a point-in-time view: a subscriber installation running concurrently is observed mid-step — a listener already live whose owning registration is not recorded yet answers with no owner until the installation finishes. Dispatch correctness never depends on this view.
func (*EventDispatcher) RemoveListener ¶
func (instance *EventDispatcher) RemoveListener(registration eventcontract.ListenerRegistration) bool
func (*EventDispatcher) RemoveSubscriber ¶
func (instance *EventDispatcher) RemoveSubscriber(subscriber eventcontract.EventSubscriber) int
type EventDispatcherAdapter ¶
type EventDispatcherAdapter struct {
// contains filtered or unexported fields
}
func NewEventDispatcherAdapter ¶
func NewEventDispatcherAdapter( eventDispatcher eventcontract.EventDispatcher, ) *EventDispatcherAdapter
func (*EventDispatcherAdapter) AddListener ¶
func (instance *EventDispatcherAdapter) AddListener(eventName string, listener eventcontract.EventListener, priority int) eventcontract.ListenerRegistration
func (*EventDispatcherAdapter) AddSubscriber ¶
func (instance *EventDispatcherAdapter) AddSubscriber(subscriber eventcontract.EventSubscriber)
func (*EventDispatcherAdapter) Dispatch ¶
func (instance *EventDispatcherAdapter) Dispatch(runtimeInstance runtimecontract.Runtime, eventValue eventcontract.Event) (eventcontract.Event, error)
func (*EventDispatcherAdapter) DispatchName ¶
func (instance *EventDispatcherAdapter) DispatchName(runtimeInstance runtimecontract.Runtime, eventName string, payload any) (eventcontract.Event, error)
func (*EventDispatcherAdapter) MarkListenerMaySkipRequiredListeners ¶ added in v2.9.0
func (instance *EventDispatcherAdapter) MarkListenerMaySkipRequiredListeners(registration eventcontract.ListenerRegistration)
MarkListenerMaySkipRequiredListeners forwards to the wrapped dispatcher and records the mark for inspection, refusing a wrapped dispatcher that cannot mark required listeners for the reason MarkListenerRequired gives.
func (*EventDispatcherAdapter) MarkListenerRequired ¶ added in v2.9.0
func (instance *EventDispatcherAdapter) MarkListenerRequired(registration eventcontract.ListenerRegistration)
MarkListenerRequired forwards to the wrapped dispatcher and records the mark for inspection. A wrapped dispatcher that cannot mark required listeners is refused rather than absorbed: callers probe for RequiredListenerRegistrar precisely to learn whether the guarantee is available, and the adapter satisfies that probe on its own behalf, so swallowing the mark here would answer the probe yes and leave the fail-closed guarantee unarmed.
func (*EventDispatcherAdapter) RegisteredEvents ¶
func (instance *EventDispatcherAdapter) RegisteredEvents() []eventcontract.RegisteredEvent
RegisteredEvents reports a point-in-time view: a registration or removal running concurrently is observed mid-step — a listener already live in the wrapped dispatcher whose record here is not written yet, or the reverse during removal. The view settles the moment the concurrent (un)installation finishes; dispatch correctness never depends on it.
The view covers what was registered THROUGH the adapter: a listener added directly on the wrapped dispatcher is live for dispatch but absent here, and a mark applied through the adapter for such a registration arms the wrapped dispatcher's guarantee while this bookkeeping — inspection only — has nothing to record it on. One registration surface per dispatcher keeps the inspection truthful.
func (*EventDispatcherAdapter) RemoveListener ¶
func (instance *EventDispatcherAdapter) RemoveListener(registration eventcontract.ListenerRegistration) bool
func (*EventDispatcherAdapter) RemoveSubscriber ¶
func (instance *EventDispatcherAdapter) RemoveSubscriber(subscriber eventcontract.EventSubscriber) int
type RequiredListenerSkippedError ¶ added in v2.13.0
type RequiredListenerSkippedError struct {
// contains filtered or unexported fields
}
func NewRequiredListenerSkippedError ¶ added in v2.13.0
func NewRequiredListenerSkippedError(eventName string, stoppedByListenerName string) *RequiredListenerSkippedError
NewRequiredListenerSkippedError reports that a listener stopped event propagation while a listener marked required through RequiredListenerRegistrar was still behind it, so that listener never ran. The type matters more than the message: it is what lets a caller separate this class from an ordinary listener failure and refuse the dispatch outright, which is what the http kernel does for kernel.request — a stopping listener that also produced a response would otherwise have that response served with access control never consulted.
Type-assert the error a dispatch returns directly rather than reaching through the cause chain with errors.As: a listener is free to dispatch further events, and one of those nested dispatches skipping a required listener of its own travels up as the cause of an ordinary listener error. Failing the outer dispatch closed for that is a different, wider policy than refusing the dispatch that actually skipped the listener.
func NewRequiredListenerSkippedErrorWithCause ¶ added in v2.13.0
func NewRequiredListenerSkippedErrorWithCause(eventName string, failedListenerName string, cause error) *RequiredListenerSkippedError
NewRequiredListenerSkippedErrorWithCause reports the same refusal for a dispatch that ABORTED on a failing listener while a listener marked required was still behind it: a listener that fails ends the dispatch exactly as decisively as one that stops propagation, so the required listener never ran. The failure that ended the dispatch travels as the cause, so the diagnostic of the listener that actually broke is not lost behind the refusal.
func NewRequiredListenerSkippedErrorWithStoppedListenerFailure ¶ added in v2.13.0
func NewRequiredListenerSkippedErrorWithStoppedListenerFailure(eventName string, stoppedByListenerName string, cause error) *RequiredListenerSkippedError
NewRequiredListenerSkippedErrorWithStoppedListenerFailure reports the stop's own refusal for a listener that FAILED while also stopping propagation with a required listener behind it. The refusal keeps the stop's message and context — the stop is the decision the caller reacts to — and the listener's failure travels as the cause: the failure was deliberately returned unlogged by the dispatch on the promise that the caller's record names it, and without the cause this was the one path on which it reached no log at all.
func (*RequiredListenerSkippedError) Error ¶ added in v2.13.0
func (instance *RequiredListenerSkippedError) Error() string
func (*RequiredListenerSkippedError) Unwrap ¶ added in v2.13.0
func (instance *RequiredListenerSkippedError) Unwrap() error
type SubscribedEvent ¶
type SubscribedEvent struct {
// contains filtered or unexported fields
}
func NewSubscribedEvent ¶
func NewSubscribedEvent( listener eventcontract.EventListener, priority int, ) *SubscribedEvent
func (*SubscribedEvent) Listener ¶
func (instance *SubscribedEvent) Listener() eventcontract.EventListener
func (*SubscribedEvent) Priority ¶
func (instance *SubscribedEvent) Priority() int