github.com/CyCoreSystems/ari@v4.8.4+incompatible/context.go (about) 1 package ari 2 3 import "context" 4 5 // ChannelContextOptions describes the set of options to be used when creating a channel-bound context. 6 type ChannelContextOptions struct { 7 ctx context.Context 8 cancel context.CancelFunc 9 10 hangupOnEnd bool 11 12 sub Subscription 13 } 14 15 // ChannelContextOptionFunc describes a function which modifies channel context options. 16 type ChannelContextOptionFunc func(o *ChannelContextOptions) 17 18 // ChannelContext returns a context which is closed when the provided channel leaves the ARI application or the parent context is closed. The parent context is optional, and if it is `nil`, a new background context will be created. 19 func ChannelContext(h *ChannelHandle, opts ...ChannelContextOptionFunc) (context.Context, context.CancelFunc) { 20 21 o := new(ChannelContextOptions) 22 for _, opt := range opts { 23 opt(o) 24 } 25 26 if o.ctx == nil { 27 o.ctx, o.cancel = context.WithCancel(context.Background()) 28 } 29 30 if o.sub == nil { 31 o.sub = h.Subscribe(Events.StasisEnd) 32 } 33 34 go func() { 35 defer o.cancel() 36 37 select { 38 case <-o.ctx.Done(): 39 case <-o.sub.Events(): 40 } 41 42 if o.hangupOnEnd { 43 h.Hangup() // nolint 44 } 45 }() 46 47 return o.ctx, o.cancel 48 } 49 50 // WithParentContext requests that the generated channel context be created from the given parent context. 51 func WithParentContext(parent context.Context) ChannelContextOptionFunc { 52 return func(o *ChannelContextOptions) { 53 if parent != nil { 54 o.ctx, o.cancel = context.WithCancel(parent) 55 } 56 } 57 } 58 59 // HangupOnEnd indicates that the channel should be terminated when the channel context is terminated. Note that this also provides an easy way to create a time scope on a channel by putting a deadline on the parent context. 60 func HangupOnEnd() ChannelContextOptionFunc { 61 return func(o *ChannelContextOptions) { 62 o.hangupOnEnd = true 63 } 64 }