From 2d9a7048b2e3eeb1054db53e955f1bcd50d92478 Mon Sep 17 00:00:00 2001 From: werben Date: Sat, 9 Sep 2023 12:13:19 +0800 Subject: [PATCH] Change InitSingleton() to ResetSingleton() and create and store a global EventBus object in init(). --- README-CN.md | 14 +++++++---- README.md | 14 +++++++---- singleton.go | 20 ++++++++++------ singleton_test.go | 61 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 75 insertions(+), 34 deletions(-) diff --git a/README-CN.md b/README-CN.md index 1c0d8c4..71272e1 100644 --- a/README-CN.md +++ b/README-CN.md @@ -73,18 +73,24 @@ func main() { ### 使用全局的EventBus单例对象 -为了更方便的使用EventBus, 这里有一个全局的EventBus单例对象,使用`eventbus.InitSingleton() `初始化这个单例对象,这个对象内部的channel是无缓冲的,直接使用`eventbus.Subscribe()`,`eventbus.Publish()`,`eventbus.Unsubscribe()`,将会调用该单例对象对应的方法。 +为了更方便的使用EventBus, 这里有一个全局的EventBus单例对象,这个单例内部的channel是无缓冲的,直接使用`eventbus.Subscribe()`,`eventbus.Publish()`,`eventbus.Unsubscribe()`,将会调用该单例对象对应的方法。 ```go +package main + +import ( + "fmt" + "time" + + "github.com/werbenhu/eventbus" +) + func handler(topic string, payload int) { fmt.Printf("topic:%s, payload:%d\n", topic, payload) } func main() { - // 初始化单例对象 - eventbus.InitSingleton() - // eventbus.Subscribe() 将调用全局单例singleton.Subscribe()方法 eventbus.Subscribe("testtopic", handler) diff --git a/README.md b/README.md index dff1cba..f7f3b3e 100644 --- a/README.md +++ b/README.md @@ -79,18 +79,24 @@ func main() { ``` ### Using the global singleton object of EventBus -To make it more convenient to use EventBus, there is a global singleton object for EventBus. You can initialize this singleton object by calling `eventbus.InitSingleton()`. The internal channel of this object is unbuffered, and you can directly use `eventbus.Subscribe()`, `eventbus.Publish()`, and `eventbus.Unsubscribe()` to call the corresponding methods of the singleton object. +To make it more convenient to use EventBus, there is a global singleton object for EventBus. The internal channel of this singleton is unbuffered, and you can directly use `eventbus.Subscribe()`, `eventbus.Publish()`, and `eventbus.Unsubscribe()` to call the corresponding methods of the singleton object. ```go +package main + +import ( + "fmt" + "time" + + "github.com/werbenhu/eventbus" +) + func handler(topic string, payload int) { fmt.Printf("topic:%s, payload:%d\n", topic, payload) } func main() { - // Initialize the singleton object - eventbus.InitSingleton() - // eventbus.Subscribe() will call the global singleton's Subscribe() method eventbus.Subscribe("testtopic", handler) diff --git a/singleton.go b/singleton.go index dd2189d..102a509 100644 --- a/singleton.go +++ b/singleton.go @@ -5,14 +5,17 @@ var ( singleton *EventBus ) -// InitSingleton initializes the singleton instance of EventBus, which will be created only when necessary. -func InitSingleton() { - if singleton == nil { +func init() { + ResetSingleton() +} - // If singleton is nil, we create a new instance of EventBus using the New() - // function and assign it to the singleton variable. - singleton = New() +// ResetSingleton resets the singleton object. If the singleton object is not nil, +// it first closes the old singleton, and then creates a new singleton instance. +func ResetSingleton() { + if singleton != nil { + singleton.Close() } + singleton = New() } // Unsubscribe removes handler defined for a topic. @@ -42,5 +45,8 @@ func PublishSync(topic string, payload any) error { // Close closes the singleton instance of EventBus. func Close() { - singleton.Close() + if singleton != nil { + singleton.Close() + singleton = nil + } } diff --git a/singleton_test.go b/singleton_test.go index ed511c7..abf024e 100644 --- a/singleton_test.go +++ b/singleton_test.go @@ -7,18 +7,8 @@ import ( "github.com/stretchr/testify/assert" ) -func recreateSingleton() { - singleton = nil - InitSingleton() -} - -func Test_InitSingleton(t *testing.T) { - recreateSingleton() - assert.NotNil(t, singleton) -} - func Test_SingletonSubscribe(t *testing.T) { - recreateSingleton() + ResetSingleton() err := Subscribe("testtopic", busHandlerOne) assert.Nil(t, err) assert.NotNil(t, singleton) @@ -37,14 +27,14 @@ func Test_SingletonSubscribe(t *testing.T) { }) assert.Equal(t, ErrHandlerFirstParam, err) - Close() + singleton.Close() err = Unsubscribe("testtopic", busHandlerTwo) assert.Equal(t, ErrChannelClosed, err) + Close() } func Test_SingletonUnsubscribe(t *testing.T) { - recreateSingleton() - + ResetSingleton() err := Unsubscribe("testtopic", busHandlerOne) assert.Equal(t, ErrNoSubscriber, err) assert.NotNil(t, singleton) @@ -54,15 +44,15 @@ func Test_SingletonUnsubscribe(t *testing.T) { err = Unsubscribe("testtopic", busHandlerOne) assert.Nil(t, err) - Close() + singleton.Close() err = Unsubscribe("testtopic", busHandlerTwo) assert.Equal(t, ErrChannelClosed, err) + Close() } func Test_SingletonPublish(t *testing.T) { - recreateSingleton() - + ResetSingleton() err := Publish("testtopic", 1) assert.Nil(t, err) assert.NotNil(t, singleton) @@ -87,8 +77,7 @@ func Test_SingletonPublish(t *testing.T) { } func Test_SingletonPublishSync(t *testing.T) { - recreateSingleton() - + ResetSingleton() err := Publish("testtopic", 1) assert.Nil(t, err) assert.NotNil(t, singleton) @@ -111,3 +100,37 @@ func Test_SingletonPublishSync(t *testing.T) { wg.Wait() Close() } + +func BenchmarkSingletonPublish(b *testing.B) { + ResetSingleton() + Subscribe("testtopic", busHandlerOne) + + b.ResetTimer() + var wg sync.WaitGroup + wg.Add(1) + go func() { + for i := 0; i < b.N; i++ { + Publish("testtopic", i) + } + wg.Done() + }() + wg.Wait() + Close() +} + +func BenchmarkSingletonPublishSync(b *testing.B) { + ResetSingleton() + Subscribe("testtopic", busHandlerOne) + + b.ResetTimer() + var wg sync.WaitGroup + wg.Add(1) + go func() { + for i := 0; i < b.N; i++ { + PublishSync("testtopic", i) + } + wg.Done() + }() + wg.Wait() + Close() +}