diff --git a/pkg/corredor/service.go b/pkg/corredor/service.go index 16a6dbf61..b37e9c3f9 100644 --- a/pkg/corredor/service.go +++ b/pkg/corredor/service.go @@ -59,7 +59,7 @@ type ( } eventRegistry interface { - Register(h eventbus.Handler, ops ...eventbus.TriggerRegOp) uintptr + Register(h eventbus.HandlerFn, ops ...eventbus.HandlerRegOp) uintptr Unregister(ptrs ...uintptr) } @@ -255,7 +255,7 @@ func (svc *service) registerServerScripts(ss ...*ServerScript) { // registers that script to the list of manual triggers func (svc *service) registerTriggers(script *ServerScript) []uintptr { var ( - ops []eventbus.TriggerRegOp + ops []eventbus.HandlerRegOp err error ptrs = make([]uintptr, 0, len(script.Triggers)) diff --git a/pkg/corredor/util.go b/pkg/corredor/util.go index 702f23136..5378c94fc 100644 --- a/pkg/corredor/util.go +++ b/pkg/corredor/util.go @@ -56,7 +56,7 @@ func pluckManualTriggers(script *ServerScript) map[string]string { } // converts trigger's constraint to eventbus' constraint options -func makeTriggerOpts(t *Trigger) (oo []eventbus.TriggerRegOp, err error) { +func makeTriggerOpts(t *Trigger) (oo []eventbus.HandlerRegOp, err error) { if len(t.Events) == 0 { return nil, fmt.Errorf("can not generate trigger without at least one events") } diff --git a/pkg/corredor/util_test.go b/pkg/corredor/util_test.go index 4ed47a4fe..b4f9ddab2 100644 --- a/pkg/corredor/util_test.go +++ b/pkg/corredor/util_test.go @@ -66,7 +66,7 @@ func TestTriggerOptsMaking(t *testing.T) { }, } - oo []eventbus.TriggerRegOp + oo []eventbus.HandlerRegOp err error ) diff --git a/pkg/eventbus/README.adoc b/pkg/eventbus/README.adoc index 11a103ebb..0ce4ea163 100644 --- a/pkg/eventbus/README.adoc +++ b/pkg/eventbus/README.adoc @@ -1,6 +1,6 @@ # pkg/eventbus -Package handles event dispatching and trigger registration +Package handles event dispatching and handler registration ## Event @@ -21,14 +21,14 @@ Deferred events (onTimestamp and onInterval) are executed by scheduler package s #### Manual events Manual events (onManual) are a special case. -Events are not (nor should be) triggered directly or through eventbus. +These events are not (nor should be) dispatched directly or through event-bus. We use it to route requests and pack attributes from the API to the Corredor service ### Event matcher Matcher is a function on event that helps filtering fired events. -It decides (returns true or false) if fired event is a match for any of a registered triggers +It decides (returns true or false) if fired event is a match for any of a registered handlers Bus has basic internal filtering for resource & event type. Other constraints are passed to event's matcher function. @@ -45,20 +45,20 @@ All constraints must match. First non-match will break constraint checking procedure. -## Triggers +## Handler -Trigger is combination of (event matching) rules/constraints and event handler. -Handler is a callback function called when a compatible event is fired. +Handler is combination of (event matching) rules/constraints and handler callback function. +Function is called when a event compatible with registered rules & constraints is fired. -Trigger can respond to multiple resource/event combinations. +Handler can respond to multiple resource/event combinations. ### Constraints -Matcher function is called multiple times, once per each trigger constraint. +Matcher function is called multiple times, once per each handler constraint. If any of the calls result in a non-match, check -Trigger without constraint is considered a match. +Handler without any constraints is considered a match. ### Weight -Weight controls order of trigger execution. +Weight controls order of execution. diff --git a/pkg/eventbus/constraints.go b/pkg/eventbus/constraints.go index 903d62e76..09702f4fa 100644 --- a/pkg/eventbus/constraints.go +++ b/pkg/eventbus/constraints.go @@ -112,11 +112,11 @@ func mustLikeMaker(name string, not bool, vv ...string) (*mustBeLike, error) { } func MustBeLike(name string, vv ...string) (ConstraintMatcher, error) { - return &mustBeLike{name: name, values: vv}, nil + return mustLikeMaker(name, false, vv...) } func MustNotBeLike(name string, vv ...string) (ConstraintMatcher, error) { - return &mustBeLike{name: name, values: vv, not: true}, nil + return mustLikeMaker(name, true, vv...) } func (c mustBeLike) Match(value string) bool { diff --git a/pkg/eventbus/eventbus.go b/pkg/eventbus/eventbus.go index 9d9c6fe6e..22b3dcc14 100644 --- a/pkg/eventbus/eventbus.go +++ b/pkg/eventbus/eventbus.go @@ -24,11 +24,11 @@ type ( wg *sync.WaitGroup // Read & write locking - // prevent event handling during trigger (un)registration + // prevent event handling during handler (un)registration l *sync.RWMutex // list of registered handlers - triggers map[uintptr]*trigger + handlers map[uintptr]*handler } ) @@ -50,7 +50,7 @@ func New() *eventbus { return &eventbus{ wg: &sync.WaitGroup{}, l: &sync.RWMutex{}, - triggers: make(map[uintptr]*trigger), + handlers: make(map[uintptr]*handler), } } @@ -61,7 +61,7 @@ func (b *eventbus) WaitFor(ctx context.Context, ev Event) (err error) { b.l.RLock() defer b.l.RUnlock() for _, t := range b.find(ev) { - err = func(ctx context.Context, t *trigger) error { + err = func(ctx context.Context, t *handler) error { b.wg.Add(1) defer b.wg.Done() return t.Handle(ctx, ev) @@ -82,7 +82,7 @@ func (b *eventbus) Dispatch(ctx context.Context, ev Event) { defer b.l.RUnlock() for _, t := range b.find(ev) { b.wg.Add(1) - go func(ctx context.Context, t *trigger) { + go func(ctx context.Context, t *handler) { defer b.wg.Done() _ = t.Handle(ctx, ev) }(ctx, t) @@ -96,18 +96,18 @@ func (b *eventbus) wait() { b.wg.Wait() } -// Finds all registered triggers compatible with given event +// Finds all registered handlers compatible with given event // -// It returns sorted triggers +// It returns sorted handlers // // There is still room for improvement (performance wise) by indexing -// resources and events of each trigger. -func (b *eventbus) find(ev Event) (tt TriggerSet) { +// resources and events of each handler. +func (b *eventbus) find(ev Event) (tt HandlerSet) { if ev == nil { return } - for _, t := range b.triggers { + for _, t := range b.handlers { if !t.Match(ev) { continue @@ -121,28 +121,28 @@ func (b *eventbus) find(ev Event) (tt TriggerSet) { return } -// Register creates a new trigger with given handler, resource, event with other options and constraints +// Register creates a new handler with given handler, resource, event with other options and constraints // -// It returns a trigger identifier that can be used to remove (unregister) trigger later -func (b *eventbus) Register(h Handler, ops ...TriggerRegOp) uintptr { +// It returns a handler identifier that can be used to remove (unregister) handler later +func (b *eventbus) Register(h HandlerFn, ops ...HandlerRegOp) uintptr { b.l.Lock() defer b.l.Unlock() var ( - trigger = NewTrigger(h, ops...) - ptr = uintptr(unsafe.Pointer(trigger)) + handlers = NewHandler(h, ops...) + ptr = uintptr(unsafe.Pointer(handlers)) ) - b.triggers[ptr] = trigger + b.handlers[ptr] = handlers return ptr } -// Unregister removes one or more registered triggers +// Unregister removes one or more registered handlers func (b *eventbus) Unregister(ptrs ...uintptr) { b.l.Lock() defer b.l.Unlock() for _, ptr := range ptrs { - delete(b.triggers, ptr) + delete(b.handlers, ptr) } } diff --git a/pkg/eventbus/eventbus_test.go b/pkg/eventbus/eventbus_test.go index 08a39ed58..0eb529491 100644 --- a/pkg/eventbus/eventbus_test.go +++ b/pkg/eventbus/eventbus_test.go @@ -18,23 +18,23 @@ func TestEventbusRegUnreg(t *testing.T) { bus = New() ) - a.Empty(bus.triggers) + a.Empty(bus.handlers) h1 := bus.Register(nil) a.NotZero(h1) h2 := bus.Register(nil) a.NotZero(h2) h3 := bus.Register(nil) a.NotZero(h3) - a.Len(bus.triggers, 3) + a.Len(bus.handlers, 3) bus.Unregister(h1) - a.Len(bus.triggers, 2) + a.Len(bus.handlers, 2) bus.Unregister(h2) - a.Len(bus.triggers, 1) + a.Len(bus.handlers, 1) bus.Unregister(h3) - a.Empty(bus.triggers) + a.Empty(bus.handlers) } -func BenchmarkEventbusTriggerLookup(b *testing.B) { +func BenchmarkEventbusHandlerLookup(b *testing.B) { var ( bus = New() ptrs []uintptr diff --git a/pkg/eventbus/triggers.go b/pkg/eventbus/handlers.go similarity index 59% rename from pkg/eventbus/triggers.go rename to pkg/eventbus/handlers.go index 634500119..35a87c41a 100644 --- a/pkg/eventbus/triggers.go +++ b/pkg/eventbus/handlers.go @@ -8,10 +8,10 @@ import ( ) type ( - Handler func(ctx context.Context, ev Event) error + HandlerFn func(ctx context.Context, ev Event) error - trigger struct { - handler Handler + handler struct { + handler HandlerFn resourceTypes map[string]bool eventTypes map[string]bool constraints constraintSet @@ -19,30 +19,30 @@ type ( } // @todo add sorting interface - TriggerSet []*trigger + HandlerSet []*handler - TriggerRegOp func(t *trigger) + HandlerRegOp func(t *handler) eventInvokerSettable interface { SetInvoker(auth.Identifiable) } ) -// Match matches trigger with resource event -func (t trigger) Match(re Event) bool { +// Match matches handler with resource event +func (t handler) Match(re Event) bool { if re == nil { return false } if len(re.ResourceType()) == 0 || !t.resourceTypes[re.ResourceType()] { // Expecting to have valid resource type and match at least one - // defined resource on the trigger + // defined resource on the handler return false } if len(re.EventType()) == 0 || !t.eventTypes[re.EventType()] { // Expecting to have valid event type and match at least one - // defined event on the trigger + // defined event on the handler return false } @@ -56,7 +56,7 @@ func (t trigger) Match(re Event) bool { return true } -func (t trigger) Handle(ctx context.Context, ev Event) error { +func (t handler) Handle(ctx context.Context, ev Event) error { defer sentry.Recover() if eis, ok := ev.(eventInvokerSettable); ok { @@ -66,8 +66,8 @@ func (t trigger) Handle(ctx context.Context, ev Event) error { return t.handler(ctx, ev) } -func NewTrigger(h Handler, ops ...TriggerRegOp) *trigger { - var t = &trigger{ +func NewHandler(h HandlerFn, ops ...HandlerRegOp) *handler { + var t = &handler{ resourceTypes: make(map[string]bool), eventTypes: make(map[string]bool), handler: h, @@ -80,36 +80,36 @@ func NewTrigger(h Handler, ops ...TriggerRegOp) *trigger { return t } -func For(rr ...string) TriggerRegOp { - return func(t *trigger) { +func For(rr ...string) HandlerRegOp { + return func(t *handler) { for _, r := range rr { t.resourceTypes[r] = true } } } -func On(ee ...string) TriggerRegOp { - return func(t *trigger) { +func On(ee ...string) HandlerRegOp { + return func(t *handler) { for _, e := range ee { t.eventTypes[e] = true } } } -func Constraint(c ConstraintMatcher) TriggerRegOp { - return func(t *trigger) { +func Constraint(c ConstraintMatcher) HandlerRegOp { + return func(t *handler) { t.constraints = append(t.constraints, c) } } -func Weight(weight int) TriggerRegOp { - return func(t *trigger) { +func Weight(weight int) HandlerRegOp { + return func(t *handler) { t.weight = weight } } -// Trigger-set sorting: +// handler sorting: -func (set TriggerSet) Len() int { return len(set) } -func (set TriggerSet) Swap(i, j int) { set[i], set[j] = set[j], set[i] } -func (set TriggerSet) Less(i, j int) bool { return set[i].weight < set[j].weight } +func (set HandlerSet) Len() int { return len(set) } +func (set HandlerSet) Swap(i, j int) { set[i], set[j] = set[j], set[i] } +func (set HandlerSet) Less(i, j int) bool { return set[i].weight < set[j].weight } diff --git a/pkg/eventbus/trigger_test.go b/pkg/eventbus/handlers_test.go similarity index 68% rename from pkg/eventbus/trigger_test.go rename to pkg/eventbus/handlers_test.go index 07f8c0128..dfdedde3b 100644 --- a/pkg/eventbus/trigger_test.go +++ b/pkg/eventbus/handlers_test.go @@ -41,10 +41,10 @@ func (e *mockEvent) SetInvoker(identity auth.Identifiable) { e.identity = identity } -func TestTrigger_Match(t *testing.T) { +func TestHandler_Match(t *testing.T) { cases := []struct { name string - ops []TriggerRegOp + ops []HandlerRegOp ev Event match bool }{ @@ -54,22 +54,22 @@ func TestTrigger_Match(t *testing.T) { false, }, {"empty resource", - []TriggerRegOp{For("foo"), On("bar")}, + []HandlerRegOp{For("foo"), On("bar")}, &mockEvent{rType: "", eType: "bar"}, false, }, {"empty event", - []TriggerRegOp{For("foo"), On("bar")}, + []HandlerRegOp{For("foo"), On("bar")}, &mockEvent{rType: "foo", eType: ""}, false, }, {"simple foo-bar test", - []TriggerRegOp{For("foo"), On("bar")}, + []HandlerRegOp{For("foo"), On("bar")}, &mockEvent{rType: "foo", eType: "bar"}, true, }, {"ConstraintMatcher match", - []TriggerRegOp{For("foo"), On("bar"), Constraint(MustMakeConstraint("baz", "=", "baz"))}, + []HandlerRegOp{For("foo"), On("bar"), Constraint(MustMakeConstraint("baz", "=", "baz"))}, &mockEvent{ rType: "foo", eType: "bar", @@ -79,7 +79,7 @@ func TestTrigger_Match(t *testing.T) { true, }, {"ConstraintMatcher mismatch", - []TriggerRegOp{For("foo"), On("bar"), Constraint(MustMakeConstraint("baz", "=", "baz"))}, + []HandlerRegOp{For("foo"), On("bar"), Constraint(MustMakeConstraint("baz", "=", "baz"))}, &mockEvent{ rType: "foo", eType: "bar", @@ -92,20 +92,20 @@ func TestTrigger_Match(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - var trigger = NewTrigger(nil, c.ops...) + var handler = NewHandler(nil, c.ops...) if c.match { - assert.True(t, trigger.Match(c.ev), "Expecting to match") + assert.True(t, handler.Match(c.ev), "Expecting to match") } else { - assert.False(t, trigger.Match(c.ev), "Expecting to not match") + assert.False(t, handler.Match(c.ev), "Expecting to not match") } }) } } -func TestTrigger_RegOps(t *testing.T) { - makeTestTrigger := func(t *trigger) *trigger { +func TestHandler_RegOps(t *testing.T) { + makeTestHandler := func(t *handler) *handler { if t.resourceTypes == nil { t.resourceTypes = make(map[string]bool) } @@ -119,45 +119,45 @@ func TestTrigger_RegOps(t *testing.T) { cases := []struct { name string - exp *trigger - ops []TriggerRegOp + exp *handler + ops []HandlerRegOp }{ { "empty", - makeTestTrigger(&trigger{}), + makeTestHandler(&handler{}), nil, }, { "resource types", - makeTestTrigger(&trigger{resourceTypes: map[string]bool{"foo": true, "bar": true}}), - []TriggerRegOp{For("foo", "bar")}, + makeTestHandler(&handler{resourceTypes: map[string]bool{"foo": true, "bar": true}}), + []HandlerRegOp{For("foo", "bar")}, }, { "event types", - makeTestTrigger(&trigger{eventTypes: map[string]bool{"foo": true, "bar": true}}), - []TriggerRegOp{On("foo", "bar")}, + makeTestHandler(&handler{eventTypes: map[string]bool{"foo": true, "bar": true}}), + []HandlerRegOp{On("foo", "bar")}, }, { "weight", - makeTestTrigger(&trigger{weight: 42}), - []TriggerRegOp{Weight(42)}, + makeTestHandler(&handler{weight: 42}), + []HandlerRegOp{Weight(42)}, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { - assert.Equal(t, c.exp, NewTrigger(nil, c.ops...)) + assert.Equal(t, c.exp, NewHandler(nil, c.ops...)) }) } } -func TestTriggerHandler(t *testing.T) { +func TestHandlerHandler(t *testing.T) { var ( a = assert.New(t) ctx = context.Background() ev = &mockEvent{} passedthrough bool - trSimple = &trigger{ + trSimple = &handler{ handler: func(ctx context.Context, ev Event) error { passedthrough = true a.True(auth.IsSuperUser(ev.(*mockEvent).identity)) @@ -175,16 +175,16 @@ func TestTriggerHandler(t *testing.T) { a.True(passedthrough, "expecting to pass through simple handler") } -func TestTriggerSorting(t *testing.T) { +func TestHandlerSorting(t *testing.T) { var ( a = assert.New(t) - tt = TriggerSet{ - NewTrigger(nil, Weight(3)), - NewTrigger(nil, Weight(1)), - NewTrigger(nil, Weight(2)), + tt = HandlerSet{ + NewHandler(nil, Weight(3)), + NewHandler(nil, Weight(1)), + NewHandler(nil, Weight(2)), } - w2s = func(tt TriggerSet) (out string) { + w2s = func(tt HandlerSet) (out string) { for _, t := range tt { out += fmt.Sprintf("%d,", t.weight) }