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  }