github.com/CyCoreSystems/ari@v4.8.4+incompatible/bus.go (about) 1 package ari 2 3 import ( 4 "context" 5 "sync" 6 ) 7 8 // Bus is an event bus for ARI events. It receives and 9 // redistributes events based on a subscription model. 10 type Bus interface { 11 Close() 12 Sender 13 Subscriber 14 } 15 16 // A Sender is an entity which can send event bus messages 17 type Sender interface { 18 Send(e Event) 19 } 20 21 // A Subscriber is an entity which can create ARI event subscriptions 22 type Subscriber interface { 23 Subscribe(key *Key, n ...string) Subscription 24 } 25 26 // A Subscription is a subscription on series of ARI events 27 type Subscription interface { 28 // Events returns a channel on which events related to this subscription are sent. 29 Events() <-chan Event 30 31 // Cancel terminates the subscription 32 Cancel() 33 } 34 35 // Once listens for the first event of the provided types, 36 // returning a channel which supplies that event. 37 func Once(ctx context.Context, bus Bus, key *Key, eTypes ...string) <-chan Event { 38 s := bus.Subscribe(key, eTypes...) 39 40 ret := make(chan Event) 41 42 // Stop subscription after one event 43 go func() { 44 select { 45 case ret <- <-s.Events(): 46 case <-ctx.Done(): 47 } 48 close(ret) 49 s.Cancel() 50 }() 51 return ret 52 } 53 54 // NewNullSubscription returns a subscription which never returns any events 55 func NewNullSubscription() *NullSubscription { 56 return &NullSubscription{ 57 ch: make(chan Event), 58 } 59 } 60 61 // NullSubscription is a subscription which never returns any events. 62 type NullSubscription struct { 63 ch chan Event 64 closed bool 65 mu sync.RWMutex 66 } 67 68 func (n *NullSubscription) Events() <-chan Event { 69 if n.ch == nil { 70 n.mu.Lock() 71 n.closed = false 72 n.ch = make(chan Event) 73 n.mu.Unlock() 74 } 75 return n.ch 76 } 77 78 func (n *NullSubscription) Cancel() { 79 if n.closed { 80 return 81 } 82 83 n.mu.Lock() 84 n.closed = true 85 if n.ch != nil { 86 close(n.ch) 87 } 88 n.mu.Unlock() 89 90 }