-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
177 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,106 @@ | ||
# event | ||
Event listener and dispatcher for Golang | ||
A go package for event listener and dispatcher with channel. | ||
|
||
**Original Place: [event-listener-and-dispatcher-example-with-golang](http://www.inanzzz.com/index.php/post/2qdl/event-listener-and-dispatcher-example-with-golang)** | ||
|
||
## Features | ||
|
||
- One dispatcher can register many listeners. | ||
|
||
- One dispatcher can register many events for a specific given listener. | ||
|
||
- One dispatcher can dispatch many events. | ||
|
||
- One listener can listen on many events. | ||
|
||
- One event can be linked to one event type. | ||
|
||
- The dispatcher prevents registering duplicated events. | ||
|
||
- The dispatcher prevents dispatching non-registered events. | ||
|
||
## Usage Sample | ||
|
||
### Create your own events | ||
|
||
user/created.go: | ||
|
||
```go | ||
package user | ||
|
||
import ( | ||
"log" | ||
"time" | ||
|
||
"github.com/tim-ywliu/event" | ||
) | ||
|
||
const Created event.Name = "user.created" | ||
|
||
type CreatedEvent struct { | ||
Time time.Time | ||
ID string | ||
} | ||
|
||
func (e CreatedEvent) Handle() { | ||
log.Printf("creating: %+v\n", e) | ||
} | ||
``` | ||
|
||
### Write your event listener | ||
|
||
user/listener.go: | ||
|
||
```go | ||
package user | ||
|
||
import ( | ||
"log" | ||
) | ||
|
||
type UserListener struct{} | ||
|
||
func (u UserListener) Listen(event interface{}) { | ||
switch event := event.(type) { | ||
case CreatedEvent: | ||
event.Handle() | ||
default: | ||
log.Printf("registered an invalid user event: %T\n", event) | ||
} | ||
} | ||
``` | ||
|
||
### Write your event dispatch method | ||
|
||
user/dispatcher.go: | ||
|
||
```go | ||
package user | ||
|
||
var userDispatcher *event.Dispatcher | ||
|
||
import ( | ||
"log" | ||
"time" | ||
|
||
"github.com/tim-ywliu/event" | ||
) | ||
|
||
func RegisterUserDispatcher() error { | ||
userDispatcher = event.NewDispatcher() | ||
if err := userDispatcher.Register(UserListener{}, Created); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func DispatchUserCreatedEvent() { | ||
err := userDispatcher.Dispatch(Created, CreatedEvent{ | ||
Time: time.Now().UTC(), | ||
ID: "111", | ||
}) | ||
if err != nil { | ||
log.Println(err) | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package event | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
type Dispatcher struct { | ||
jobs chan job | ||
events map[Name]Listener | ||
} | ||
|
||
func NewDispatcher() *Dispatcher { | ||
d := &Dispatcher{ | ||
jobs: make(chan job), | ||
events: make(map[Name]Listener), | ||
} | ||
|
||
go d.consume() | ||
|
||
return d | ||
} | ||
|
||
func (d *Dispatcher) Register(listener Listener, names ...Name) error { | ||
for _, name := range names { | ||
if _, ok := d.events[name]; ok { | ||
return fmt.Errorf("the '%s' event is already registered", name) | ||
} | ||
|
||
d.events[name] = listener | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (d *Dispatcher) Dispatch(name Name, event interface{}) error { | ||
if _, ok := d.events[name]; !ok { | ||
return fmt.Errorf("the '%s' event is not registered", name) | ||
} | ||
|
||
d.jobs <- job{eventName: name, eventType: event} | ||
|
||
return nil | ||
} | ||
|
||
func (d *Dispatcher) consume() { | ||
for job := range d.jobs { | ||
d.events[job.eventName].Listen(job.eventType) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package event | ||
|
||
// All custom events names must be of this type. | ||
type Name string | ||
|
||
// All custom event types must satisfy this interface. | ||
type Event interface { | ||
Handle() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package event | ||
|
||
// job represents events. When a new event is dispatched, it | ||
// gets tuned into a job and put into `Dispatcher.jobs` channel. | ||
type job struct { | ||
eventName Name | ||
eventType interface{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package event | ||
|
||
// All custom event listeners must satisfy this interface. | ||
type Listener interface { | ||
Listen(event interface{}) | ||
} |