diff options
author | Valery Piashchynski <[email protected]> | 2021-10-30 13:33:06 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2021-10-30 13:33:06 -0700 |
commit | b78558d0af7f813f81de0338400f99291932347f (patch) | |
tree | e71fcd3ed2d8bbc1bb4542290a11d5cb9730a4b1 /events/docs | |
parent | c8c3f9f113eae13aa37cf92043b288bb0c68a622 (diff) | |
parent | 1cac0d3efd40e8950004c8d953fb5d1f2d53197b (diff) |
[#839]: refactoring(eventsbus): add docs, udpate testsv2.6.0-alpha.2
[#839]: refactoring(eventsbus): add docs, udpate tests
Diffstat (limited to 'events/docs')
-rw-r--r-- | events/docs/events.md | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/events/docs/events.md b/events/docs/events.md index e69de29b..37059b25 100644 --- a/events/docs/events.md +++ b/events/docs/events.md @@ -0,0 +1,136 @@ +## RoadRunner Events bus + +RR events bus might be useful when one plugin raises some event on which another plugin should react. For example, +plugins like sentry might log errors from the `http` plugin. + +## Simple subscription + +Events bus supports wildcard subscriptions on the events as well as the direct subscriptions on the particular event. + +Let's have a look at the simple example: + +```go +package foo + +import ( + "github.com/spiral/roadrunner/v2/events" +) + +func foo() { + eh, id := events.Bus() + defer eh.Unsubscribe(id) + + ch := make(chan events.Event, 100) + err := eh.SubscribeP(id, "http.EventJobOK", ch) + if err != nil { + panic(err) + } + + eh.Send(events.NewEvent(events.EventJobOK, "http", "foo")) + evt := <-ch + // evt.Message() -> "foo" + // evt.Plugin() -> "http" + // evt.Type().String() -> "EventJobOK" +} +``` + +Here: +1. `eh, id := events.Bus()` get the instance (it's global) of the events bus. Make sure to unsubscribe event handler when you don't need it anymore: `eh.Unsubscribe(id)`. +2. `ch := make(chan events.Event, 100)` create an events channel. +3. `err := eh.SubscribeP(id, "http.EventJobOK", ch)` subscribe to the events which fits your pattern (`http.EventJobOK`). +4. `eh.Send(events.NewEvent(events.EventJobOK, "http", "foo"))` emit event from the any plugin. +5. `evt := <-ch` get the event. + +Notes: +1. If you use only `eh.Send` events bus function, you don't need to unsubscribe, so, you may simplify the declaration to the `eh, _ := events.Bus()`. + +## Wildcards + +As mentioned before, RR events bus supports wildcards subscriptions, like: `*.SomeEvent`, `http.*`, `http.Some*`, `*`. +Let's have a look at the next sample of code: + +```go +package foo + +import ( + "github.com/spiral/roadrunner/v2/events" +) + +func foo() { + eh, id := events.Bus() + defer eh.Unsubscribe(id) + + ch := make(chan events.Event, 100) + err := eh.SubscribeP(id, "http.*", ch) + if err != nil { + panic(err) + } + + eh.Send(events.NewEvent(events.EventJobOK, "http", "foo")) + evt := <-ch + // evt.Message() -> "foo" + // evt.Plugin() -> "http" + // evt.Type().String() -> "EventJobOK" +} +``` + +One change between these samples is in the `SubscribeP` pattern: `err := eh.SubscribeP(id, "http.*", ch)`. Here we used `http.*` instead of `http.EventJobOK`. + +You also have the access to the event message, plugin and type. Message is a custom, user-defined message to log or to show to the subscriber. Plugin is a source plugin who raised this event. And the event type - is your custom or RR event type. + + +## How to implement custom event + +Event type is a `fmt.Stringer`. That means, that your custom event type should implement this interface. Let's have a look at how to do that: + +```go +package foo + +type MySuperEvent uint32 + +const ( + EventHTTPError MySuperEvent = iota +) + +func (mse MySuperEvent) String() string { + switch mse { + case EventHTTPError: + return "EventHTTPError" + default: + return "UnknownEventType" + } +} +``` + +Here we defined a custom type - `MySuperEvent`. For sure, it might have any name you want and represent for example some domain field like `WorkersPoolEvent` represents RR sync.pool events. Then you need to implement a `fmt.Stringer` on your custom event type. +Next you need to create an enum with the actual events and that's it. + +How to use that: +```go +package foo + +import ( + "github.com/spiral/roadrunner/v2/events" +) + +func foo() { + eh, id := events.Bus() + defer eh.Unsubscribe(id) + + ch := make(chan events.Event, 100) + err := eh.SubscribeP(id, "http.EventHTTPError", ch) + if err != nil { + panic(err) + } + + // first arg of the NewEvent method is fmt.Stringer + eh.Send(events.NewEvent(EventHTTPError, "http", "foo")) + evt := <-ch + // evt.Message() -> "foo" + // evt.Plugin() -> "http" + // evt.Type().String() -> "EventHTTPError" +} +``` + +Important note: you don't need to import your custom event types into the subscriber. You only need to know the name of that event and pass a string to the subscriber. + |