package main import ( "fmt" "time" ) func main() { eb := NewEventBus() fmt.Println("=== EventBus Demo ===") // Subscribe to specific topic ch1 := eb.Subscribe("orders.created") // Subscribe to wildcard ch2 := eb.Subscribe("orders.*") // Subscribe using a callback eb.SubscribeCallback("payments.*", func(topic string, data Data) { fmt.Printf("[Callback] Payment event received: %s -> %+v\n", topic, data) }) // Run listener goroutines go func() { for evt := range ch1 { fmt.Printf("[Listener 1] Topic=%s Data=%v\n", evt.Topic, evt.Data) time.Sleep(50 * time.Millisecond) // simulate work evt.Done() } }() go func() { for evt := range ch2 { fmt.Printf("[Listener 2] Wildcard match for %s Data=%v\n", evt.Topic, evt.Data) evt.Done() } }() // ---- PUBLISH SYNCHRONOUS EVENTS ---- fmt.Println("\n--- Publish Sync ---") eb.Publish("orders.created", Data{"id": 42, "customer": "Alice"}) eb.Publish("orders.updated", Data{"id": 42, "status": "shipped"}) // ---- PUBLISH ASYNC EVENTS ---- fmt.Println("\n--- Publish Async ---") eb.PublishAsync("payments.received", Data{"id": 1001, "amount": 99.50}) eb.PublishAsync("payments.refunded", Data{"id": 1002, "amount": 20.00}) // Give async events time to deliver time.Sleep(200 * time.Millisecond) // ---- PUBLISH ONCE semantics ---- fmt.Println("\n--- Publish Once ---") eb.PublishOnce("orders.once", Data{"msg": "first time"}) eb.PublishOnce("orders.once", Data{"msg": "second time (ignored)"}) eb.PublishAsyncOnce("payments.once", Data{"msg": "async first"}) eb.PublishAsyncOnce("payments.once", Data{"msg": "async second (ignored)"}) time.Sleep(100 * time.Millisecond) // ---- UNSUBSCRIBE ---- fmt.Println("\n--- Unsubscribe Listener 2 (orders.*) ---") eb.Unsubscribe("orders.*", ch2) close(ch2) eb.Publish("orders.updated", Data{"id": 42, "status": "delivered"}) time.Sleep(100 * time.Millisecond) // ---- PRINT STATS ---- fmt.Println("\n--- Stats ---") for _, ts := range eb.Stats().GetTopicStats() { fmt.Printf("Topic: %-20s | Published: %-3d | Subscribers: %-3d\n", ts.Name, ts.PublishedCount.Value(), ts.SubscriberCount.Value()) } fmt.Println("\n=== Done ===") }