Skip to content

Commit

Permalink
Add source and update README
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-ywliu committed Sep 27, 2020
1 parent a1e9a0f commit 99b77ca
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 1 deletion.
106 changes: 105 additions & 1 deletion README.md
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)
}
}
```
49 changes: 49 additions & 0 deletions dispatcher.go
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)
}
}
9 changes: 9 additions & 0 deletions event.go
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()
}
8 changes: 8 additions & 0 deletions job.go
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{}
}
6 changes: 6 additions & 0 deletions listener.go
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{})
}

0 comments on commit 99b77ca

Please sign in to comment.