Go (Golang) में Event Bus और Observer पैटर्न: pub/sub की पूरी गाइड

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Go (Golang) में Event Bus और Observer पैटर्न: थ्योरी से प्रैक्टिस तक

Observer पैटर्न और इसका Event Bus (इवेंट बस) के रूप में इम्प्लीमेंटेशन, लूजली-कपल्ड और स्केलेबल सिस्टम बनाने के लिए बेहद ज़रूरी टूल्स हैं। Go में, जहाँ "चैनल्स के ज़रिए कम्युनिकेट करें, शेयर्ड मेमोरी से नहीं" का फिलॉसफी है, ये पैटर्न और भी खूबसूरत बन जाते हैं। इस आर्टिकल में हम Go में goroutines और channels का उपयोग करके अपना खुद का Event Bus बनाएंगे और इसके सामान्य उपयोग के मामलों को समझेंगे।

Observer पैटर्न: मूल अवधारणा और समस्या

मान लीजिए आपके पास एक सिस्टम है जहाँ एक ऑब्जेक्ट (Publisher) को अपनी स्थिति में बदलाव के बारे में कई दूसरे ऑब्जेक्ट्स (Subscribers) को सूचित करना है। Observer पैटर्न के बिना, आपको Publisher को हर Subscriber से सीधे जोड़ना होगा। Observer पैटर्न एक सब्सक्रिप्शन इंटरफ़ेस पेश करके इस समस्या को हल करता है: Publisher सब्सक्राइबर्स की एक लिस्ट रखता है और इवेंट होने पर उनका Update() मेथड कॉल करता है।

Event Bus एक सेंट्रलाइज्ड बस है जो मध्यस्थ की भूमिका निभाती है। कोई भी कम्पोनेंट एक इवेंट पब्लिश कर सकता है, और कोई भी दूसरा कम्पोनेंट उस इवेंट को सब्सक्राइब कर सकता है, बिना एक-दूसरे के बारे में जाने।

Go Event Bus के लिए क्यों परफेक्ट है?

  • Goroutines और Channels: बिना ब्लॉकिंग के एसिंक्रोनस इवेंट हैंडलिंग।
  • Interfaces: हैंडलर्स के लिए कॉन्ट्रैक्ट आसानी से डिफाइन करना।
  • कोई इनहेरिटेंस नहीं: क्लासिकल OOP इम्प्लीमेंटेशन की तुलना में चैनल्स और फंक्शन्स के ज़रिए कम्पोज़िशन ज़्यादा नेचुरल है।

Go में Event Bus की सरल इम्प्लीमेंटेशन

चलिए एक बेसिक वर्जन से शुरू करते हैं, जहाँ इवेंट्स स्ट्रिंग्स हैं और सब्सक्राइबर्स फंक्शन-हैंडलर्स हैं।

package main

import (
    "fmt"
    "sync"
    "time"
)

// EventBus — हमारी इवेंट बस
type EventBus struct {
    subscribers map[string][]func(string)
    mu          sync.RWMutex
}

// NewEventBus एक नई बस बनाता है
func NewEventBus() *EventBus {
    return &EventBus{
        subscribers: make(map[string][]func(string)),
    }
}

// Subscribe एक हैंडलर को इवेंट पर सब्सक्राइब करता है
func (eb *EventBus) Subscribe(event string, handler func(string)) {
    eb.mu.Lock()
    defer eb.mu.Unlock()
    eb.subscribers[event] = append(eb.subscribers[event], handler)
}

// Publish इवेंट को पब्लिश करता है और सभी सब्सक्राइबर्स को सिंक्रोनसली कॉल करता है
func (eb *EventBus) Publish(event string, data string) {
    eb.mu.RLock()
    defer eb.mu.RUnlock()
    if handlers, ok := eb.subscribers[event]; ok {
        for _, handler := range handlers {
            handler(data)
        }
    }
}

func main() {
    bus := NewEventBus()
    
    bus.Subscribe("user.login", func(data string) {
        fmt.Printf("लॉगिन: %s\n", data)
    })
    
    bus.Subscribe("user.login", func(data string) {
        fmt.Printf("ऑडिट: %s ने सिस्टम में प्रवेश किया\n", data)
    })
    
    bus.Publish("user.login", "alice@example.com")
    // आउटपुट:
    // लॉगिन: alice@example.com
    // ऑडिट: alice@example.com ने सिस्टम में प्रवेश किया
}

यह कोड काम करता है, लेकिन इसमें एक खामी है: हैंडलर्स सिंक्रोनसली कॉल होते हैं। अगर एक हैंडलर हैंग हो जाता है, तो यह पूरी बस को ब्लॉक कर देगा।

चैनल्स के साथ एसिंक्रोनस वर्जन

अब हम बफ़र्ड चैनल्स के ज़रिए एसिंक्रोनसी जोड़ते हैं। हर सब्सक्राइबर को अपना चैनल मिलेगा।

type AsyncEventBus struct {
    subscribers map[string][]chan string
    mu          sync.RWMutex
}

func NewAsyncEventBus() *AsyncEventBus {
    return &AsyncEventBus{
        subscribers: make(map[string][]chan string),
    }
}

func (eb *AsyncEventBus) Subscribe(event string, buffer int) <-chan string {
    eb.mu.Lock()
    defer eb.mu.Unlock()
    ch := make(chan string, buffer)
    eb.subscribers[event] = append(eb.subscribers[event], ch)
    return ch
}

func (eb *AsyncEventBus) Publish(event string, data string) {
    eb.mu.RLock()
    defer eb.mu.RUnlock()
    if channels, ok := eb.subscribers[event]; ok {
        for _, ch := range channels {
            select {                    

अनुशंसाएँ