1
0
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:
lowit 2022-04-29 13:57:18 +03:00 committed by lowitea
parent f6444240c9
commit 571bef02be
3 changed files with 61 additions and 18 deletions

View File

@ -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
View File

@ -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

View File

@ -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()