Skip to content

Instantly share code, notes, and snippets.

@jblebrun
Created March 17, 2018 21:44
Show Gist options
  • Save jblebrun/e2d8703843de7063bd2565bc7dc6378a to your computer and use it in GitHub Desktop.
Save jblebrun/e2d8703843de7063bd2565bc7dc6378a to your computer and use it in GitHub Desktop.
MultiContext: Contexts with sibling relationship
// MultiContext allows you to use multiple contexts for cancellation
// allowing for sibling relationship, as well as parent-child relationship.
// This is an experiment, and likely not a good approach.
type MultiContext struct {
ctxs []context.Context
done chan struct{}
err error
}
func NewMultiContext(ctxs []context.Context) *MultiContext {
done := make(chan struct{})
mc := &MultiContext{ctxs, done, nil}
for _, ctx := range ctxs {
go func(ctx context.Context) {
<-ctx.Done()
mc.err = ctx.Err()
close(done)
}(ctx)
}
return mc
}
func (mc *MultiContext) Done() <-chan struct{} {
return mc.done
}
func (mc *MultiContext) Err() error {
return mc.err
}
func (mc *MultiContext) Deadline() (deadline time.Time, ok bool) {
for _, ctx := range mc.ctxs {
dl, ok := ctx.Deadline()
if ok {
return dl, ok
}
}
return time.Time{}, false
}
func (mc *Multicontext) Value(key interface{}) interface{} {
for _, ctx := range mc.ctxs {
if val := ctx.Value(key); val != nil {
return val
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment