Documentation
¶
Overview ¶
Package shot provides concurrency primitives for managing the execution of instances.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrRunning = errors.New("already running") ErrClosed = errors.New("closed") )
Functions ¶
This section is empty.
Types ¶
type G ¶
type G struct {
// contains filtered or unexported fields
}
G allows to manage execution of a goroutine and get the error returned from the goroutine.
func Go ¶
Go runs a function in a goroutine with a managed context.
Returns G, which can be used to manage the goroutine execution and get the error returned from the goroutine.
func GoCtx ¶
GoCtx runs a function in a goroutine with a managed context derived from the parent context ctx.
Returns G, which can be used to manage the goroutine execution and get the error returned from the goroutine.
func (*G) Close ¶
Close stops the goroutine and waits for it to exit with the given context.
Context passed to this method can be canceled to pass control back to the caller if waiting for the goroutine to exit takes too much time. Context cancellation only affects the wait time, not the goroutine itself.
type Many ¶
type Many struct {
// contains filtered or unexported fields
}
Many ensures that only one instance runs at a time.
Example ¶
package main import ( "context" "fmt" "time" "codeberg.org/go-toolbox/shot" ) type FibMany struct { values [2]int idx int output chan int state shot.Many } func NewFibMany(ctx context.Context) *FibMany { return &FibMany{ values: [2]int{-1, 1}, idx: 0, output: make(chan int, 1), state: shot.NewMany(ctx), } } func (e *FibMany) Run() error { stop, err := e.state.Start() if err != nil { return err } defer stop() ticker := time.NewTicker(10 * time.Millisecond) defer ticker.Stop() for { select { case <-e.state.Context().Done(): return e.state.Context().Err() case <-ticker.C: sum := e.values[0] + e.values[1] e.values[e.idx] = sum e.idx = (e.idx + 1) % 2 e.output <- sum if sum == 13 || sum == 89 { return nil } if sum == 144 { ticker.Stop() } } } } func (e *FibMany) Close() error { if err := e.state.Close(context.Background()); err != nil { return err } close(e.output) return nil } func (e *FibMany) Output() <-chan int { return e.output } func (e *FibMany) Done() <-chan struct{} { return e.state.Done() } func main() { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() fib := NewFibMany(ctx) go fib.Run() defer fib.Close() for { select { case <-ctx.Done(): return case <-fib.Done(): go fib.Run() case msg := <-fib.Output(): fmt.Print(msg, " ") } } }
Output: 0 1 1 2 3 5 8 13 21 34 55 89 144
func (*Many) Close ¶
Close shuts down the instance and cancels its context.
If not started, prevents instance from being started at all. If running, waits for completion with the given context.
Context passed to this method can be canceled to pass control back to the caller if waiting for completion takes too much time. Context cancellation only affects the wait time, not the instance itself.
func (*Many) Context ¶
Context returns the instance's context.
The context is cancelled when:
- The instance exits normally
- Close is called
- The parent context is cancelled
This context must be used to exit when it has been cancelled.
func (*Many) Done ¶
func (m *Many) Done() <-chan struct{}
Done returns a channel that is closed when the instance instance exits or is closed.
type One ¶
type One struct {
// contains filtered or unexported fields
}
One ensures that only one instance runs at a time and runs only once.
Example ¶
package main import ( "context" "fmt" "time" "codeberg.org/go-toolbox/shot" ) type FibOne struct { output chan int state shot.One } func NewFibOne(ctx context.Context) *FibOne { return &FibOne{ output: make(chan int, 1), state: shot.NewOne(ctx), } } func (e *FibOne) Run() error { stop, err := e.state.Start() if err != nil { return err } defer stop() ticker := time.NewTicker(10 * time.Millisecond) defer ticker.Stop() values := [2]int{-1, 1} idx := 0 for { select { case <-e.state.Context().Done(): return e.state.Context().Err() case <-ticker.C: sum := values[0] + values[1] values[idx] = sum idx = (idx + 1) % 2 e.output <- sum if sum == 144 { ticker.Stop() } } } } func (e *FibOne) Close() error { if err := e.state.Close(context.Background()); err != nil { return err } return nil } func (e *FibOne) Output() <-chan int { return e.output } func main() { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() fib := NewFibOne(ctx) go fib.Run() defer fib.Close() for { select { case <-ctx.Done(): return case msg := <-fib.Output(): fmt.Print(msg, " ") } } }
Output: 0 1 1 2 3 5 8 13 21 34 55 89 144
func (*One) Close ¶
Close shuts down the instance and cancels its context.
If not started, prevents instance from being started at all. If running, waits for completion with the given context.
Context passed to this method can be canceled to pass control back to the caller if waiting for completion takes too much time. Context cancellation only affects the wait time, not the instance itself.
func (*One) Context ¶
Context returns the instance's context.
The context is cancelled when:
- The instance exits normally
- Close is called
- The parent context is cancelled
This context must be used to exit when it has been cancelled.
func (*One) Done ¶
func (s *One) Done() <-chan struct{}
Done returns a channel that is closed when the instance instance exits or is closed.
type Xor ¶
type Xor struct {
// contains filtered or unexported fields
}
Xor ensures only one instance runs at a time, but allows replacing the running instance.
Example ¶
package main import ( "context" "fmt" "time" "codeberg.org/go-toolbox/shot" ) type FibXor struct { output chan int state shot.Xor } func NewFibXor(ctx context.Context) *FibXor { return &FibXor{ output: make(chan int, 1), state: shot.NewXor(ctx), } } func (e *FibXor) Run(values [2]int, idx int) error { stop, err := e.state.Start(context.Background()) if err != nil { return err } defer stop() ticker := time.NewTicker(10 * time.Millisecond) defer ticker.Stop() for { select { case <-e.state.Context().Done(): return e.state.Context().Err() case <-ticker.C: sum := values[0] + values[1] values[idx] = sum idx = (idx + 1) % 2 e.output <- sum if sum == 377 { ticker.Stop() } } } } func (e *FibXor) Close() error { if err := e.state.Close(context.Background()); err != nil { return err } close(e.output) return nil } func (e *FibXor) Output() <-chan int { return e.output } func main() { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() fib := NewFibXor(ctx) go fib.Run([2]int{-1, 1}, 0) defer fib.Close() for { select { case <-ctx.Done(): return case msg := <-fib.Output(): if msg == 13 { go fib.Run([2]int{13, 21}, 0) } if msg == 89 { go fib.Run([2]int{89, 144}, 0) } fmt.Print(msg, " ") } } }
Output: 0 1 1 2 3 5 8 13 34 55 89 233 377
func (*Xor) Close ¶
Close shuts down the instance and cancels its context.
If not started, prevents instance from being started at all. If running, waits for completion with the given context.
Context passed to this method can be canceled to pass control back to the caller if waiting for completion takes too much time. Context cancellation only affects the wait time, not the instance itself.
func (*Xor) Context ¶
Context returns the instance's context.
The context is cancelled when:
- The instance exits normally
- Close is called
- Stop is called
- The parent context is cancelled
This context must be used to exit when it has been cancelled.
func (*Xor) Done ¶
func (x *Xor) Done() <-chan struct{}
Done returns a channel that is closed when the instance instance exits or is closed.
func (*Xor) Start ¶
Start starts or replaces the running instance and returns a stop function. Call stop to signal completion and allow restarting. The stop function must be called.
Context passed to this method can be canceled to pass control back to the caller if waiting for stopping the running instance takes too much time. In such case, the instance will eventually stop, but will not start.
Returns ErrClosed if already closed.
func (*Xor) Stop ¶
Stop shuts down the instance, allowing future restarts, and cancels its context.
If running, waits for completion with the given context.
Context passed to this method can be canceled to pass control back to the caller if waiting for completion takes too much time. Context cancellation only affects the wait time, not the instance itself.
Returns ErrClosed if already closed.