75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/simonfxr/pubsub"
|
|
)
|
|
|
|
var eventBus = pubsub.NewBus()
|
|
|
|
// Event represents a published event with topic and payload.
|
|
type Event struct {
|
|
Topic string
|
|
Payload string
|
|
}
|
|
|
|
// PublishEvent publishes an event to a specific topic.
|
|
// Topic hierarchy:
|
|
//
|
|
// session.{sid}.new/kill/pause/resume/rename
|
|
// session.{sid}.agent.{aid}.new/kill/state
|
|
//
|
|
// Wildcard routing publishes to all ancestor wildcards:
|
|
//
|
|
// session.{sid}.agent.{aid}.state -> also publishes to:
|
|
// session.{sid}.agent.{aid}.*
|
|
// session.{sid}.agent.*
|
|
// session.{sid}.*
|
|
// session.*
|
|
// *
|
|
func PublishEvent(topic, payload string) {
|
|
ev := Event{Topic: topic, Payload: payload}
|
|
eventBus.Publish(topic, ev)
|
|
|
|
// Publish to hierarchical wildcards
|
|
parts := strings.Split(topic, ".")
|
|
for i := len(parts) - 1; i >= 1; i-- {
|
|
wildcard := strings.Join(parts[:i], ".") + ".*"
|
|
eventBus.Publish(wildcard, ev)
|
|
}
|
|
eventBus.Publish("*", ev)
|
|
}
|
|
|
|
// SubscribeEvents returns a channel that receives all events matching the topic.
|
|
// Use "*" for all events, "session.*" for all session events, etc.
|
|
func SubscribeEvents(ctx context.Context, topic string) <-chan Event {
|
|
ch := make(chan Event, 64)
|
|
sub := eventBus.SubscribeChan(topic, ch, pubsub.KeepOpen)
|
|
go func() {
|
|
<-ctx.Done()
|
|
eventBus.Unsubscribe(sub)
|
|
close(ch)
|
|
}()
|
|
return ch
|
|
}
|
|
|
|
// WaitEvent blocks until an event is available. Returns the event as "topic payload\n".
|
|
func WaitEvent(ctx context.Context, _ string) ([]byte, string, error) {
|
|
ch := SubscribeEvents(ctx, "*")
|
|
select {
|
|
case ev, ok := <-ch:
|
|
if !ok {
|
|
return nil, "", nil
|
|
}
|
|
line := ev.Topic
|
|
if ev.Payload != "" {
|
|
line += " " + ev.Payload
|
|
}
|
|
return []byte(line + "\n"), "", nil
|
|
case <-ctx.Done():
|
|
return nil, "", nil
|
|
}
|
|
}
|