package main import ( "context" "fmt" "log" "os" "os/signal" "syscall" "time" "github.com/anthonyrawlins/bzzz/sdk/bzzz" "github.com/anthonyrawlins/bzzz/sdk/decisions" "github.com/anthonyrawlins/bzzz/sdk/elections" ) // Real-time event streaming example // Shows how to listen for events and decisions in real-time func main() { fmt.Println("šŸŽ§ BZZZ SDK Event Streaming Example") // Set up graceful shutdown ctx, cancel := context.WithCancel(context.Background()) defer cancel() sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) // Initialize BZZZ client client, err := bzzz.NewClient(bzzz.Config{ Endpoint: "http://localhost:8080", Role: "observer", // Observer role for monitoring Timeout: 30 * time.Second, }) if err != nil { log.Fatalf("Failed to create BZZZ client: %v", err) } defer client.Close() // Get initial status status, err := client.GetStatus(ctx) if err != nil { log.Fatalf("Failed to get status: %v", err) } fmt.Printf("āœ… Connected as observer: %s\n", status.AgentID) // Start event streaming eventStream, err := client.SubscribeEvents(ctx) if err != nil { log.Fatalf("Failed to subscribe to events: %v", err) } defer eventStream.Close() fmt.Println("šŸŽ§ Subscribed to system events") // Start decision streaming decisionsClient := decisions.NewClient(client) decisionStream, err := decisionsClient.StreamDecisions(ctx, decisions.StreamRequest{ Role: "backend_developer", ContentType: "decision", }) if err != nil { log.Fatalf("Failed to stream decisions: %v", err) } defer decisionStream.Close() fmt.Println("šŸ“Š Subscribed to backend developer decisions") // Start election monitoring electionsClient := elections.NewClient(client) electionEvents, err := electionsClient.MonitorElections(ctx) if err != nil { log.Fatalf("Failed to monitor elections: %v", err) } defer electionEvents.Close() fmt.Println("šŸ—³ļø Monitoring election events") fmt.Println("\nšŸ“” Listening for events... (Ctrl+C to stop)") fmt.Println("=" * 60) // Event processing loop eventCount := 0 decisionCount := 0 electionEventCount := 0 for { select { case event := <-eventStream.Events(): eventCount++ fmt.Printf("\nšŸ”” [%s] System Event: %s\n", time.Now().Format("15:04:05"), event.Type) switch event.Type { case "decision_published": fmt.Printf(" šŸ“ New decision: %s\n", event.Data["address"]) fmt.Printf(" šŸ‘¤ Creator: %s\n", event.Data["creator_role"]) case "admin_changed": fmt.Printf(" šŸ‘‘ Admin changed: %s -> %s\n", event.Data["old_admin"], event.Data["new_admin"]) fmt.Printf(" šŸ“‹ Reason: %s\n", event.Data["election_reason"]) case "peer_connected": fmt.Printf(" 🌐 Peer connected: %s (%s)\n", event.Data["agent_id"], event.Data["role"]) case "peer_disconnected": fmt.Printf(" šŸ”Œ Peer disconnected: %s\n", event.Data["agent_id"]) default: fmt.Printf(" šŸ“„ Data: %v\n", event.Data) } case decision := <-decisionStream.Decisions(): decisionCount++ fmt.Printf("\nšŸ“‹ [%s] Decision Stream\n", time.Now().Format("15:04:05")) fmt.Printf(" šŸ“ Task: %s\n", decision.Task) fmt.Printf(" āœ… Success: %t\n", decision.Success) fmt.Printf(" šŸ‘¤ Role: %s\n", decision.Role) fmt.Printf(" šŸ—ļø Project: %s\n", decision.Project) fmt.Printf(" šŸ“Š Address: %s\n", decision.Address) case electionEvent := <-electionEvents.Events(): electionEventCount++ fmt.Printf("\nšŸ—³ļø [%s] Election Event: %s\n", time.Now().Format("15:04:05"), electionEvent.Type) switch electionEvent.Type { case elections.ElectionStarted: fmt.Printf(" šŸš€ Election started: %s\n", electionEvent.ElectionID) fmt.Printf(" šŸ“ Candidates: %d\n", len(electionEvent.Candidates)) case elections.CandidateProposed: fmt.Printf(" šŸ‘Øā€šŸ’¼ New candidate: %s\n", electionEvent.Candidate.NodeID) fmt.Printf(" šŸ“Š Score: %.1f\n", electionEvent.Candidate.Score) case elections.ElectionCompleted: fmt.Printf(" šŸ† Winner: %s\n", electionEvent.Winner) fmt.Printf(" šŸ“Š Final score: %.1f\n", electionEvent.FinalScore) case elections.AdminHeartbeat: fmt.Printf(" šŸ’— Heartbeat from: %s\n", electionEvent.AdminID) } case streamErr := <-eventStream.Errors(): fmt.Printf("\nāŒ Event stream error: %v\n", streamErr) case streamErr := <-decisionStream.Errors(): fmt.Printf("\nāŒ Decision stream error: %v\n", streamErr) case streamErr := <-electionEvents.Errors(): fmt.Printf("\nāŒ Election stream error: %v\n", streamErr) case <-sigChan: fmt.Println("\n\nšŸ›‘ Shutdown signal received") cancel() case <-ctx.Done(): fmt.Println("\nšŸ“Š Event Statistics:") fmt.Printf(" System events: %d\n", eventCount) fmt.Printf(" Decisions: %d\n", decisionCount) fmt.Printf(" Election events: %d\n", electionEventCount) fmt.Printf(" Total events: %d\n", eventCount+decisionCount+electionEventCount) fmt.Println("\nāœ… Event streaming example completed") return } } }