mirror of
https://github.com/status-im/status-go.git
synced 2025-01-09 14:16:21 +00:00
118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
package goprocessctx
|
|
|
|
import (
|
|
"context"
|
|
|
|
goprocess "github.com/jbenet/goprocess"
|
|
)
|
|
|
|
// WithContext constructs and returns a Process that respects
|
|
// given context. It is the equivalent of:
|
|
//
|
|
// func ProcessWithContext(ctx context.Context) goprocess.Process {
|
|
// p := goprocess.WithParent(goprocess.Background())
|
|
// CloseAfterContext(p, ctx)
|
|
// return p
|
|
// }
|
|
//
|
|
func WithContext(ctx context.Context) goprocess.Process {
|
|
p := goprocess.WithParent(goprocess.Background())
|
|
CloseAfterContext(p, ctx)
|
|
return p
|
|
}
|
|
|
|
// WithContextAndTeardown is a helper function to set teardown at initiation
|
|
// of WithContext
|
|
func WithContextAndTeardown(ctx context.Context, tf goprocess.TeardownFunc) goprocess.Process {
|
|
p := goprocess.WithTeardown(tf)
|
|
CloseAfterContext(p, ctx)
|
|
return p
|
|
}
|
|
|
|
// WaitForContext makes p WaitFor ctx. When Closing, p waits for
|
|
// ctx.Done(), before being Closed(). It is simply:
|
|
//
|
|
// p.WaitFor(goprocess.WithContext(ctx))
|
|
//
|
|
func WaitForContext(ctx context.Context, p goprocess.Process) {
|
|
p.WaitFor(WithContext(ctx))
|
|
}
|
|
|
|
// CloseAfterContext schedules the process to close after the given
|
|
// context is done. It is the equivalent of:
|
|
//
|
|
// func CloseAfterContext(p goprocess.Process, ctx context.Context) {
|
|
// go func() {
|
|
// <-ctx.Done()
|
|
// p.Close()
|
|
// }()
|
|
// }
|
|
//
|
|
func CloseAfterContext(p goprocess.Process, ctx context.Context) {
|
|
if p == nil {
|
|
panic("nil Process")
|
|
}
|
|
if ctx == nil {
|
|
panic("nil Context")
|
|
}
|
|
|
|
// Avoid a goroutine for both context.Background() and goprocess.Background().
|
|
if ctx.Done() == nil || p.Closed() == nil {
|
|
return
|
|
}
|
|
|
|
go func() {
|
|
select {
|
|
case <-ctx.Done():
|
|
p.Close()
|
|
case <-p.Closed():
|
|
}
|
|
}()
|
|
}
|
|
|
|
// WithProcessClosing returns a context.Context derived from ctx that
|
|
// is cancelled as p is Closing (after: <-p.Closing()). It is simply:
|
|
//
|
|
// func WithProcessClosing(ctx context.Context, p goprocess.Process) context.Context {
|
|
// ctx, cancel := context.WithCancel(ctx)
|
|
// go func() {
|
|
// <-p.Closing()
|
|
// cancel()
|
|
// }()
|
|
// return ctx
|
|
// }
|
|
//
|
|
func WithProcessClosing(ctx context.Context, p goprocess.Process) context.Context {
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
p.AddChildNoWait(goprocess.WithTeardown(func() error {
|
|
cancel()
|
|
return nil
|
|
}))
|
|
return ctx
|
|
}
|
|
|
|
// WithProcessClosed returns a context.Context that is cancelled
|
|
// after Process p is Closed. It is the equivalent of:
|
|
//
|
|
// func WithProcessClosed(ctx context.Context, p goprocess.Process) context.Context {
|
|
// ctx, cancel := context.WithCancel(ctx)
|
|
// go func() {
|
|
// <-p.Closed()
|
|
// cancel()
|
|
// }()
|
|
// return ctx
|
|
// }
|
|
//
|
|
func WithProcessClosed(ctx context.Context, p goprocess.Process) context.Context {
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
p.AddChildNoWait(goprocess.WithTeardown(func() error {
|
|
select {
|
|
case <-p.Closed():
|
|
case <-ctx.Done():
|
|
}
|
|
cancel()
|
|
return nil
|
|
}))
|
|
return ctx
|
|
}
|