How to implement a concurrent pub-sub system using channels and sync in Golang?

To implement a concurrent pub-sub system using channels and sync in Golang, you can follow the steps below:

  1. Import the required packages from the standard library:
import ( "sync" "fmt" )
  1. Create a struct to represent the pub-sub system:
type PubSub struct { subscribers map[string][]chan string mutex sync.Mutex }
  1. Implement a method to subscribe to a specific topic:
func (ps *PubSub) Subscribe(topic string, subscriber chan string) { ps.mutex.Lock() defer ps.mutex.Unlock() // Check if topic exists, if not create a new one if ps.subscribers[topic] == nil { ps.subscribers[topic] = []chan string{} } // Add the subscriber to the topic ps.subscribers[topic] = append(ps.subscribers[topic], subscriber) }
  1. Implement a method to publish a message to a specific topic:
func (ps *PubSub) Publish(topic string, message string) { ps.mutex.Lock() defer ps.mutex.Unlock() // Check if topic exists and has subscribers if subscribers, ok := ps.subscribers[topic]; ok { // Send the message to each subscriber in a separate goroutine for _, subscriber := range subscribers { go func(s chan string) { s <- message }(subscriber) } } }
  1. Implement a method to unsubscribe from a specific topic:
func (ps *PubSub) Unsubscribe(topic string, subscriber chan string) { ps.mutex.Lock() defer ps.mutex.Unlock() // Check if topic exists if subscribers, ok := ps.subscribers[topic]; ok { // Remove the subscriber from the topic's list for i, sub := range subscribers { if sub == subscriber { ps.subscribers[topic] = append(subscribers[:i], subscribers[i+1:]...) break } } } }
  1. Create an instance of the PubSub struct to use the pub-sub system:
func main() { pubSub := &PubSub{ subscribers: make(map[string][]chan string), } // Create a subscriber channel subscriber := make(chan string) // Subscribe to a topic pubSub.Subscribe("myTopic", subscriber) // Publish a message to the topic pubSub.Publish("myTopic", "Hello, World!") // Receive the message from the subscriber channel receivedMessage := <-subscriber fmt.Println(receivedMessage) // Unsubscribe from the topic pubSub.Unsubscribe("myTopic", subscriber) }

By following these steps, you can implement a concurrent pub-sub system using channels and sync in Golang.