1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-03-01 00:35:28 +08:00

Compare commits

...

2 Commits

Author SHA1 Message Date
dudaodong
23e61f1acf update pem file 2025-01-14 15:58:58 +08:00
dudaodong
cb308f628c feat: add eventbus 2025-01-14 15:57:43 +08:00
4 changed files with 466 additions and 61 deletions

View File

@@ -1,51 +1,51 @@
-----BEGIN rsa private key-----
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
-----END rsa private key-----

View File

@@ -1,14 +1,14 @@
-----BEGIN rsa public key-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3aIM62NSgImSuiZwlvnV
Y9U+nJbq/77e5TMQa8h0OiY8d/c4OfyCHM2vQIlxl28a3WpbUkI3kebkDEefLDoB
xaL1+A+x8S5Lvy0zfNk/Eo2vxNmJOnWF8FLAPFhZq7DzGIGsmgDHe9uXDhsbosfq
34chnYOQuZ9/mFy9+Jv8axI+Cgbrd0N6MVlZ50LEQ3x5SY0xVnCPDxPFKPumvZNe
D3prp5BvX4v3IoA5Xx1Kkm2tM4yIkJrfZFX+B+BGjpyCt6HU+yz+i7gtSjtZ5Ivp
npvsJ0SseSz9AXCIfofFxqpO40VrGRGK3bKyTDaZjvybt7+5IMb4dUyzKMdjujjL
StKP0S+W2phEaNWHLEzXA3AXOJ+nRN6oplso0BNtyiC9sWKSJUWbUqmdZXmbVuB6
vZDb5Ae9KLgeHeb37HUdFbNs5ruspfdoDaXZzUI2zM2M8A0NRzxQJUGbDxqyPvPU
Er84O1P6A6WQ1JlOpljGB6fprgF7Su/HHYesEYPbTUoV/WrcYTVdoOiC7K5jNgRV
apbng8NNDvaQvsJwKgeRDonzxsMG21Iqd0/ekaRp+t8BwX6kHJtkadGUkF5aDoWe
cnyk8baN/JAVuGv4IN8K7dtKBOTmKxPFtyPHAl6rUlc/oKnQ/36MoRTXJwiqRCGn
aSrjaU++9M2VC6zBecCERYECAwEAAQ==
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuYcMNNn4v0OaL/Ufwj0p
kChajjUm1Nb3OeU4bXX26i+khkXNy6KaoRzlAfsH1Fli4iv7x6c9cde4Q63R7Wod
vzcH1W2HKxQ3Ht6hkeS2RKgJEm8o/Pbzr10yaULwjVLXsTkG6ssIdQLw3zwz6XRD
vyU66NbE3mNDIh1yAtJUmPoeRcA4QMbMM+5P888Ht6ETsLVkMx1uFYALbGidlACB
S7hyBtc0ibWjdAG9rSZg7E3MAhz5dRYmkGAJqSA4aHWL6FT2gXXkrP36D4+hbQA6
UsBLxs5nM4Cl7fzdysJWv1suldiB84+gYRmiumsj/odwVcxxFcxI1sDgabzI5IKT
waGLLz5hu+7in9lAIEqtfH/Ui5pfEw8qH1ymkLnlkSAtTZ4ByMaw869zP0AYnn1m
p+dJ5Mo1mqy0+qZn2E4FITrAOgr306D/7Ce1ZE+UZ2/i7hpkcdAD1PdY1c+Ffmps
osZ/WVcvHUH65Fz1TR6YMz0poeBj27+CBziA6P1MKfBNpBx+UfHomK5O2356S90z
qd5z0W6t1rkgLSPcR592yszAM72h+KHUtGB/rs6OUum4yfw3EVA4R4plO1lU50sc
UgwducOB7ihYSQPU87IPHcydWQ5NLobygxzqNYpIb0pPrLTBP1ZM9v6wY16xs6kC
knmr3e7aQckxq17MuNIkewsCAwEAAQ==
-----END rsa public key-----

185
eventbus/eventbus.go Normal file
View File

@@ -0,0 +1,185 @@
// Copyright 2025 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package eventbus implements a simple event bus.
package eventbus
import (
"fmt"
"sort"
"sync"
)
// Event is the struct that is passed to the event listener, now it directly uses the generic Payload type.
type Event[T any] struct {
Topic string
Payload T
}
// EventBus is the struct that holds the listeners and the error handler.
type EventBus[T any] struct {
// listeners map[string][]*EventListener[T]
listeners sync.Map
mu sync.RWMutex
errorHandler func(err error)
}
// EventListener is the struct that holds the listener function and its priority.
type EventListener[T any] struct {
priority int
listener func(eventData T)
async bool
filter func(eventData T) bool
}
// NewEventBus creates a new EventBus.
func NewEventBus[T any]() *EventBus[T] {
return &EventBus[T]{
listeners: sync.Map{},
}
}
// Subscribe subscribes to an event with a specific event topic and listener function.
func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) {
eb.mu.Lock()
defer eb.mu.Unlock()
el := &EventListener[T]{
priority: priority,
listener: listener,
async: async,
filter: filter,
}
listenersInterface, _ := eb.listeners.LoadOrStore(topic, []*EventListener[T]{})
listeners := listenersInterface.([]*EventListener[T])
listeners = append(listeners, el)
sort.Slice(listeners, func(i, j int) bool {
return listeners[i].priority > listeners[j].priority
})
eb.listeners.Store(topic, listeners)
}
// Unsubscribe unsubscribes from an event with a specific event topic and listener function.
func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) {
eb.mu.Lock()
defer eb.mu.Unlock()
listenersInterface, ok := eb.listeners.Load(topic)
if !ok {
return
}
listeners := listenersInterface.([]*EventListener[T])
listenerPtr := fmt.Sprintf("%p", listener)
var updatedListeners []*EventListener[T]
for _, l := range listeners {
if fmt.Sprintf("%p", l.listener) != listenerPtr {
updatedListeners = append(updatedListeners, l)
}
}
eb.listeners.Store(topic, updatedListeners)
}
// Publish publishes an event with a specific event topic and data payload.
func (eb *EventBus[T]) Publish(event Event[T]) {
eb.mu.RLock()
defer eb.mu.RUnlock()
listenersInterface, exists := eb.listeners.Load(event.Topic)
if !exists {
return
}
listeners := listenersInterface.([]*EventListener[T])
for _, listener := range listeners {
if listener.filter != nil && !listener.filter(event.Payload) {
continue
}
if listener.async {
go eb.publishToListener(listener, event)
} else {
eb.publishToListener(listener, event)
}
}
}
func (eb *EventBus[T]) publishToListener(listener *EventListener[T], event Event[T]) {
defer func() {
if r := recover(); r != nil && eb.errorHandler != nil {
eb.errorHandler(fmt.Errorf("%v", r))
}
}()
listener.listener(event.Payload)
}
// SetErrorHandler sets the error handler function.
func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) {
eb.errorHandler = handler
}
// ClearListeners clears all the listeners.
func (eb *EventBus[T]) ClearListeners() {
eb.mu.Lock()
defer eb.mu.Unlock()
eb.listeners = sync.Map{}
}
// ClearListenersByTopic clears all the listeners by topic.
func (eb *EventBus[T]) ClearListenersByTopic(topic string) {
eb.mu.Lock()
defer eb.mu.Unlock()
eb.listeners.Delete(topic)
}
// GetListenersCount returns the number of listeners for a specific event topic.
func (eb *EventBus[T]) GetListenersCount(topic string) int {
eb.mu.RLock()
defer eb.mu.RUnlock()
listenersInterface, ok := eb.listeners.Load(topic)
if !ok {
return 0
}
listeners := listenersInterface.([]*EventListener[T])
return len(listeners)
}
// GetAllListenersCount returns the total number of listeners.
func (eb *EventBus[T]) GetAllListenersCount() int {
eb.mu.RLock()
defer eb.mu.RUnlock()
count := 0
eb.listeners.Range(func(key, value interface{}) bool {
count += len(value.([]*EventListener[T]))
return true
})
return count
}
// GetEvents returns all the events topics.
func (eb *EventBus[T]) GetEvents() []string {
eb.mu.RLock()
defer eb.mu.RUnlock()
var events []string
eb.listeners.Range(func(key, value interface{}) bool {
events = append(events, key.(string))
return true
})
return events
}

220
eventbus/eventbus_test.go Normal file
View File

@@ -0,0 +1,220 @@
package eventbus
import (
"sync"
"testing"
"time"
"github.com/duke-git/lancet/v2/internal"
)
func TestEventBus_Subscribe(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_Subscribe")
eb := NewEventBus[int]()
eb.Subscribe("event1", func(eventData int) {
assert.Equal(1, eventData)
}, false, 0, nil)
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
}
func TestEventBus_Unsubscribe(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_Unsubscribe")
eb := NewEventBus[int]()
receivedData := 0
listener := func(eventData int) {
receivedData = eventData
}
eb.Subscribe("event1", listener, false, 0, nil)
eb.Unsubscribe("event1", listener)
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
assert.Equal(0, receivedData)
}
func TestEventBus_Subscribe_WithFilter(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_Subscribe_WithFilter")
eb := NewEventBus[int]()
receivedData := 0
listener := func(eventData int) {
receivedData = eventData
}
filter := func(eventData int) bool {
return eventData == 1
}
eb.Subscribe("event1", listener, false, 0, filter)
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
eb.Publish(Event[int]{Topic: "event1", Payload: 2})
assert.Equal(1, receivedData)
}
func TestEventBus_Subscribe_WithPriority(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_Subscribe_WithPriority")
eb := NewEventBus[int]()
var receivedData []int
listener1 := func(eventData int) {
receivedData = append(receivedData, 1)
}
listener2 := func(eventData int) {
receivedData = append(receivedData, 2)
}
eb.Subscribe("event1", listener1, false, 1, nil)
eb.Subscribe("event1", listener2, false, 2, nil)
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
assert.Equal([]int{2, 1}, receivedData)
}
func TestEventBus_Subscribe_Async(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_Subscribe_Async")
eb := NewEventBus[string]()
var wg sync.WaitGroup
wg.Add(1)
eb.Subscribe("event1", func(eventData string) {
time.Sleep(100 * time.Millisecond)
assert.Equal("hello", eventData)
wg.Done()
}, true, 1, nil)
eb.Publish(Event[string]{Topic: "event1", Payload: "hello"})
wg.Wait()
}
func TestEventBus_ErrorHandler(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_ErrorHandler")
eb := NewEventBus[string]()
eb.SetErrorHandler(func(err error) {
assert.Equal("error", err.Error())
})
eb.Subscribe("event1", func(eventData string) {
panic("error")
}, false, 0, nil)
eb.Publish(Event[string]{Topic: "event1", Payload: "hello"})
}
func TestEventBus_ClearListeners(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_ClearListeners")
eb := NewEventBus[int]()
receivedData1 := 0
receivedData2 := 0
eb.Subscribe("event1", func(eventData int) {
receivedData1 = eventData
}, false, 0, nil)
eb.Subscribe("event2", func(eventData int) {
receivedData2 = eventData
}, false, 0, nil)
eb.ClearListeners()
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
eb.Publish(Event[int]{Topic: "event1", Payload: 2})
assert.Equal(0, receivedData1)
assert.Equal(0, receivedData2)
}
func TestEventBus_ClearListenersByTopic(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_ClearListenersByTopic")
eb := NewEventBus[int]()
receivedData1 := 0
receivedData2 := 0
eb.Subscribe("event1", func(eventData int) {
receivedData1 = eventData
}, false, 0, nil)
eb.Subscribe("event2", func(eventData int) {
receivedData2 = eventData
}, false, 0, nil)
eb.ClearListenersByTopic("event1")
eb.Publish(Event[int]{Topic: "event1", Payload: 1})
eb.Publish(Event[int]{Topic: "event2", Payload: 2})
assert.Equal(0, receivedData1)
assert.Equal(2, receivedData2)
}
func TestEventBus_GetListenersCount(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_GetListenersCount")
eb := NewEventBus[int]()
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
assert.Equal(2, eb.GetListenersCount("event1"))
assert.Equal(1, eb.GetListenersCount("event2"))
}
func TestEventBus_GetAllListenersCount(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_GetAllListenersCount")
eb := NewEventBus[int]()
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
assert.Equal(3, eb.GetAllListenersCount())
}
func TestEventBus_GetEvents(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestEventBus_GetEvents")
eb := NewEventBus[int]()
eb.Subscribe("event1", func(eventData int) {}, false, 0, nil)
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
events := eb.GetEvents()
assert.Equal(2, len(events))
assert.Equal("event1", events[0])
assert.Equal("event2", events[1])
}