mirror of
https://github.com/NUTtech/bell.git
synced 2024-11-19 20:31:41 +02:00
issue-16: Create multiple copies of an event handler closes #16
This commit is contained in:
parent
f6444240c9
commit
571bef02be
16
README.md
16
README.md
@ -1,6 +1,6 @@
|
||||
# Bell
|
||||
|
||||
[![GoDoc](https://pkg.go.dev/badge/github.com/nuttech/bell?status.svg)](https://pkg.go.dev/github.com/nuttech/bell?tab=doc)
|
||||
[![GoDoc](https://pkg.go.dev/badge/github.com/nuttech/bell?status.svg)](https://pkg.go.dev/github.com/nuttech/bell/v2?tab=doc)
|
||||
[![Release](https://img.shields.io/github/release/nuttech/bell.svg?style=flat)](https://github.com/nuttech/bell/releases)
|
||||
[![codecov](https://codecov.io/gh/NUTtech/bell/branch/master/graph/badge.svg?token=3TMnbQkEny)](https://codecov.io/gh/NUTtech/bell)
|
||||
[![Tests](https://github.com/NUTtech/bell/actions/workflows/tests.yml/badge.svg)](https://github.com/NUTtech/bell/actions/workflows/tests.yml)
|
||||
@ -59,16 +59,22 @@ bell.Listen("event_name", func(message bell.Message) {
|
||||
})
|
||||
```
|
||||
|
||||
You can add a handler with multiple copies for parallel event processing.
|
||||
|
||||
```go
|
||||
bell.ListenN("event_name", func(msg bell.Message) { fmt.Println(msg) }, 42)
|
||||
```
|
||||
|
||||
### Calling an event
|
||||
|
||||
This code call event. Activating handlers, who subscribed on "event_name" event
|
||||
|
||||
```go
|
||||
bell.Call("event_name", "some data")
|
||||
bell.Ring("event_name", "some data")
|
||||
|
||||
bell.Call("event_name", 1) // int
|
||||
bell.Ring("event_name", 1) // int
|
||||
|
||||
bell.Call("event_name", false) // bool
|
||||
bell.Ring("event_name", false) // bool
|
||||
```
|
||||
|
||||
If you passing struct type of data:
|
||||
@ -77,7 +83,7 @@ If you passing struct type of data:
|
||||
type userStruct struct {
|
||||
Name string
|
||||
}
|
||||
bell.Call("event_name", userStruct{Name: "Jon"})
|
||||
bell.Ring("event_name", userStruct{Name: "Jon"})
|
||||
```
|
||||
|
||||
Then parsing the data in the handler may look like this:
|
||||
|
42
bell.go
42
bell.go
@ -41,31 +41,39 @@ func (e *Events) Queue(size uint) *Events {
|
||||
return e
|
||||
}
|
||||
|
||||
// Listen Subscribe on event where
|
||||
// ListenN Subscribe on event where
|
||||
// event - the event name,
|
||||
// handlerFunc - handler function
|
||||
func (e *Events) Listen(event string, handlerFunc func(message Message)) {
|
||||
// copiesCount - count handlers copies run
|
||||
func (e *Events) ListenN(event string, handlerFunc func(message Message), copiesCount uint) {
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
|
||||
channel := make(chan Message, e.queueSize)
|
||||
|
||||
go func(c chan Message, wg *sync.WaitGroup) {
|
||||
for {
|
||||
message, ok := <-c
|
||||
if !ok {
|
||||
break
|
||||
for i := uint(0); i < copiesCount; i++ {
|
||||
go func(c chan Message, wg *sync.WaitGroup) {
|
||||
for {
|
||||
message, ok := <-c
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
handlerFunc(message)
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
handlerFunc(message)
|
||||
|
||||
wg.Done()
|
||||
}
|
||||
}(channel, &e.wg)
|
||||
}(channel, &e.wg)
|
||||
}
|
||||
|
||||
e.channels[event] = append(e.channels[event], channel)
|
||||
}
|
||||
|
||||
// Listen Subscribe on event where
|
||||
// event - the event name,
|
||||
// handlerFunc - handler function
|
||||
func (e *Events) Listen(event string, handlerFunc func(message Message)) {
|
||||
e.ListenN(event, handlerFunc, 1)
|
||||
}
|
||||
|
||||
// Ring Call event there
|
||||
// event - event name
|
||||
// message - data that will be passed to the event handler
|
||||
@ -142,6 +150,14 @@ func (e *Events) Wait() {
|
||||
// globalState store of global event handlers
|
||||
var globalState = New()
|
||||
|
||||
// ListenN Subscribe on event where
|
||||
// event - the event name,
|
||||
// handlerFunc - handler function
|
||||
// copiesCount - count handlers copies run
|
||||
func ListenN(event string, handlerFunc func(message Message), copiesCount uint) {
|
||||
globalState.ListenN(event, handlerFunc, copiesCount)
|
||||
}
|
||||
|
||||
// Listen Subscribe on event where
|
||||
// event - the event name,
|
||||
// handlerFunc - handler function
|
||||
|
21
bell_test.go
21
bell_test.go
@ -19,6 +19,27 @@ func resetSystem() {
|
||||
globalState = &Events{channels: map[string][]chan Message{}}
|
||||
}
|
||||
|
||||
// TestListenN checking the function of adding multiple copies of event listeners
|
||||
func TestListenN(t *testing.T) {
|
||||
resetSystem()
|
||||
defer resetSystem()
|
||||
|
||||
eventName := "event"
|
||||
var wasRunning int32
|
||||
ListenN(eventName, func(Message) { atomic.AddInt32(&wasRunning, 1) }, 3)
|
||||
|
||||
require.NoError(t, Ring(eventName, nil))
|
||||
Wait()
|
||||
|
||||
assert.Equal(t, int32(1), wasRunning)
|
||||
|
||||
require.NoError(t, Ring(eventName, nil))
|
||||
require.NoError(t, Ring(eventName, nil))
|
||||
Wait()
|
||||
|
||||
assert.Equal(t, int32(3), wasRunning)
|
||||
}
|
||||
|
||||
// TestListen Testing the function of adding event listeners
|
||||
func TestListen(t *testing.T) {
|
||||
resetSystem()
|
||||
|
Loading…
Reference in New Issue
Block a user