event

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2022 License: Apache-2.0 Imports: 3 Imported by: 0

README

event

A lightweight event dispatcher for go project to implement event driven programming

installation

go get -u github.com/go-study-lab/event

Jump to Usage Example

Dispatcher Methods

Load event dispatcher singleton
event.Dispacthcer()

It will return a singleton of *event.eventDispatcher, which is a core component and all functionality would supply through it by.

Bind event listener
func (dispatcher *eventDispatcher) Subscribe(e *Event, l IListener)

Subscribe method can specify an event listener for a specific event. An event listener must implement IListener interface, we will explain this interface in next section.

Publish event
func (dispatcher *eventDispatcher) Dispatch(e *Event)

Dispatcher's Dispatch method would let us push an event, then the dispatcher would execute event's bound listeners.

Verify event has listeners
func (dispatcher *eventDispatcher) HasEventListener(e *Event) bool
Remove event listener
func (dispatcher *eventDispatcher) RemoveEventListener(e *Event, l IListener)

Event

Type Event is an event wrapper for concrete event data

type Event struct {
    eventName     string
    eventTime     time.Time
    concreteEvent IEvent
    eventType     string
}

A concrete event must implements interface IEvent

type IEvent interface {
    EventName() string
}

Event Methods

NewEvent
func NewEvent(concreteEvent IEvent) *Event

This is a factory method of Event instance.

OccurredOn
func (e *Event) OccurredOn() time.Time

Return event occurred time.

EventData
func (e *Event) EventData() IEvent

Return concrete event data.

EventName
func (e *Event) EventName() string

Return name of event.

IListener

IListener defines behaviors an event listener must implements.

type IListener interface {
    EventHandler() Handler
    AsyncProcess() bool
}

type Handler func(e *Event)
EventHandler Method

EventHandler returns a handler func for event bound to listener.

Given a listener instance *listener, it should provide EventHandler like below:

func (*listener) EventHandler() event.Handler {
    return func(e *event.Event) {
        fmt.Println("Event received")
    }
}
AsyncProcess
func (*listener) AsyncProcess() bool {
    return false
}

If AsyncProcess returned false, event.Handler func provided by EventHandler would be executed in same goroutine with the event trigger func, this means event trigger would be blocked until all his synchronized listener's handler were finished.

In the contrast event.Handler would be executed in other goroutine and event trigger would not be blocked to wait listener's completion.

Usage Examples

All dispatcher functions' demo can be found in Example Code.

This section will showcase how to define event and listener, then dispatch/publish an event.

  1. Define an UserCreated event.
type UserCreated struct {
	UserId   int
	UserName string
	Tx       *Tx
}

type Tx struct {
	// Mock as a DB transaction
	DSN string
	Tid int64
}

func (*UserCreated) EventName() string {
	return "UserCreated"
}

func UserCreatedEvent(e *UserCreated) *event.Event {
	return event.NewEvent(e)
}
  1. Define corresponding listener for UserCreated event.
type UserCreatedListener struct {
}

func (*UserCreatedListener) EventHandler() event.Handler {
	return func(e *event.Event) {
		var eData *UserCreated
		var ok bool

		if eData, ok = e.EventData().(*UserCreated); !ok {
			fmt.Println("can not convert event data to type *UserCreated")
			return
		}

		fmt.Printf("event data, userId:%d, userName:%s, Tx:%p \n", eData.UserId, eData.UserName, eData.Tx)
	}
}

// When we want to use a same
// DB transaction in event trigger and listener to  get ACID assurance, then
// AsyncProcess must return false.
func (*UserCreatedListener) AsyncProcess() bool {
	return false
}
  1. Bind event and listener in init func.
func init() {
    eventDispatcher := event.Dispatcher()
    eventDispatcher.Subscribe(UserCreatedEvent(new(UserCreated)), new(UserCreatedListener))
}
  1. Publish/Dispatch event
func PublishCreateUserEvent() {
	user := &User{
		UserId:   1,
		UserName: "KK",
	}
	tx := &domainevent.Tx{DSN: "localhost:3306/test_db", Tid: 1}
	fmt.Printf("Tx in envet trigger: %p \n", tx)

	// assume use tx to create user, then publish a userCreated event
	event.Dispatcher().Dispatch(event.NewEvent(&domainevent.UserCreated{
		UserId:   user.UserId,
		UserName: user.UserName,
		Tx:       tx, // in event handler, we can use this tx to execute other db operation
		// in the same transaction , this method will ensure event trigger and listener as
		// an atomically processed unit in system.
	}))
}

func main() {
    PublishCreateUserEvent()
}

You can find this example's code in Example Code.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Dispatcher

func Dispatcher() *eventDispatcher

func NewDispatcher

func NewDispatcher() *eventDispatcher

Types

type Event

type Event struct {
	// contains filtered or unexported fields
}

Event : Type of domainevent

func NewEvent

func NewEvent(concreteEvent IEvent) *Event

NewEvent : Factory of Event obj

func (*Event) EventData

func (e *Event) EventData() IEvent

func (*Event) EventName

func (e *Event) EventName() string

func (*Event) OccurredOn

func (e *Event) OccurredOn() time.Time

type Handler

type Handler func(e *Event)

Handler of Event in Listeners

type IEvent

type IEvent interface {
	EventName() string
}

type IEventDispatcher

type IEventDispatcher interface {
	// Subscribe for listener subscribe specified event
	Subscribe(event *Event, listener IListener)
	// RemoveEventListener remove event listener held by dispatcher
	RemoveEventListener(event *Event, listener IListener) bool
	//HasEventListener verify whether dispatcher held listener for specified event or not
	HasEventListener(event *Event) bool
	// Dispatch publish event and execute event listeners
	Dispatch(event *Event)
}

IEventDispatcher interface of event dispatcher

type IListener

type IListener interface {
	// EventHandler
	// returns a handler func for event bound to listener.
	EventHandler() Handler
	// AsyncProcess
	// return false: Handler func will execute in same goroutine with event trigger func,
	// means event trigger will be blocked until all his synchronized listener's handler are finished
	// return true: Handler will execute in other goroutine, event trigger will not
	// be blocked to wait listener's completion.
	AsyncProcess() bool
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL