Hi were you talking about something like this? I used channels over callbacks. I quickly prototyped it. Is this approach better or we have to do improvements?
package main import ( "fmt" "math/rand" "sync" "time" ) type Data struct { data interface{} topic string } type ChannelSlice []chan Data type EventBus struct { subscribers map[string] ChannelSlice rm sync.RWMutex } func (eb *EventBus)publish(topic string, data interface{}) { eb.rm.RLock() if ch, found := eb.subscribers[topic]; found { go _boradcastEvent(Data{data: data, topic:topic}, ch) } eb.rm.RUnlock() } func _boradcastEvent(data Data, sl ChannelSlice) { for _, ch := range sl { ch <- data } } func (eb *EventBus)subscribe(topic string, ch chan Data) { eb.rm.Lock() if prev, found := eb.subscribers[topic]; found { eb.subscribers[topic] = append(prev, ch) } else { eb.subscribers[topic] = append([] chan Data{}, ch) } eb.rm.Unlock() } var eb = &EventBus{ subscribers: map[string]ChannelSlice{}, } func printData(ch string, data Data) { fmt.Printf("Channel: %s; Topic: %s; Data: %v\n", ch, data.topic, data.data) } func publisTo(topic string, data string) { for { eb.publish(topic, data) time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond) } } func main() { ch1 := make(chan Data) ch2 := make(chan Data) ch3 := make(chan Data) eb.subscribe("topic1", ch1) eb.subscribe("topic2", ch2) eb.subscribe("topic2", ch3) go publisTo("topic1", "Hi topic 1") go publisTo("topic2", "Welcome to topic 2") for { select { case d := <-ch1: go printData("ch1", d) case d := <-ch2: go printData("ch2", d) case d := <-ch3: go printData("ch3", d) } } } On Monday, March 11, 2019 at 10:29:33 AM UTC+5:30, Marcin Romaszewicz wrote: > > Channels are producer/consumer queues, they don't handle one to many > broadcasting, you'd need one channel per subscriber then you'd queue the > message to each of them. In my opinion, they work more nicely than > callbacks, since your handler can run in its own execution context, and not > in the callback invoker's execution context. They are really nice for round > robin between multiple receivers, though. > > Why write it yourself? Check out the Go bindings for Zeromq > <http://zeromq.org/bindings:go>, which supports pub-sub in exactly the > way you mention. I've used this thing in production to route > 200,000 > pub/sub messages per second. It may be overkill if you're within a single > process, though. > > -- Marcin > > > On Sun, Mar 10, 2019 at 9:41 PM Kasun Vithanage <alan...@gmail.com > <javascript:>> wrote: > >> Hi all, >> >> I've experience implementing event buses in Java. >> In Java, I used a singleton where I can register callbacks to methods and >> fire event from a publisher(maybe from another thread) and propagate it to >> subscribers. >> >> In Go what would be the best pattern to implement a pub/sub event bus? >> Are channels are a better choice than using callbacks in this scenario(*one >> to many* event propagation)? >> Or callbacks are better for this? >> >> (I need to propagate events *only* to subscribers of the topic) >> >> Regards, >> Kasun >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.