Documentation
¶
Overview ¶
Package chain: a Chain of Responsibility on channels — steps that run concurrently, connected by typed channels. A chain has one input, its entry point; a pass (Process) runs every step until its input closes: the entry closes its output when it is done, a step that read its input to the end gives what it holds (Flusher) and returns, and an output closes once every step that writes to it has returned (a WaitGroup per output: where branches join, the joint closes after the last of them). Process returns when every step has.
Example ¶
A pass: words → lengths (on 4 workers) → split by parity → two ends. Process returns once every value went through every step.
package main
import (
"context"
"fmt"
"slices"
"strings"
chain "github.com/eggs-gd/go-chain"
)
// words: the chain's entry — every word of a text, then it is done
type words string
func (w words) Start(ctx context.Context, emit func(string) bool) error {
for _, word := range strings.Fields(string(w)) {
if !emit(word) {
return ctx.Err()
}
}
return nil
}
// length: a decorator — a word into its length (empty ones skipped, not an error)
type length struct{}
func (length) Decorate(w string) (int, error) {
if w == "-" {
return 0, chain.ErrSkippedItem
}
return len(w), nil
}
// parity: a switch — even lengths to output 0, odd ones to output 1
type parity struct{}
func (parity) Switch(n int) (int, error) { return n % 2, nil }
// collect: a chain's end
type collect struct{ got *[]int }
func (c collect) Consume(n int) error { *c.got = append(*c.got, n); return nil }
// A pass: words → lengths (on 4 workers) → split by parity → two ends. Process
// returns once every value went through every step.
func main() {
in, lengths := make(chan string), make(chan int)
even, odd := make(chan int), make(chan int)
var evens, odds []int
c := chain.NewChainProcessor(nil)
c.AddStep(chain.NewEntryPoint(in, words("a chain of - small steps")))
c.AddStep(chain.NewDecoratorN(in, lengths, length{}, 4))
c.AddStep(chain.NewSwitch(lengths, []chan<- int{even, odd}, parity{}))
c.AddStep(chain.NewEnd(even, collect{&evens}))
c.AddStep(chain.NewEnd(odd, collect{&odds}))
c.Process(context.Background())
slices.Sort(evens) // 4 workers: the order may change
slices.Sort(odds)
fmt.Println(evens, odds)
}
Output: [2] [1 5 5 5]
Index ¶
- Variables
- type ChainProcessor
- type Consumer
- type Decorator
- type EntryPoint
- type Flusher
- type Processor
- func NewDecorator[Ti, To any](in <-chan Ti, out chan<- To, logic Decorator[Ti, To]) Processor
- func NewDecoratorN[Ti, To any](in <-chan Ti, out chan<- To, logic Decorator[Ti, To], n int) Processor
- func NewEnd[T any](in <-chan T, logic Consumer[T]) Processor
- func NewEntryPoint[T any](out chan<- T, logic EntryPoint[T]) Processor
- func NewSwitch[T any](in <-chan T, outs []chan<- T, logic Switcher[T]) Processor
- func NewSwitchDecorator[Ti, To any](in <-chan Ti, outs []chan<- To, logic SwitchDecorator[Ti, To]) Processor
- func NewSwitchDecoratorN[Ti, To any](in <-chan Ti, outs []chan<- To, logic SwitchDecorator[Ti, To], n int) Processor
- func NewSwitchN[T any](in <-chan T, outs []chan<- T, logic Switcher[T], n int) Processor
- type Stopper
- type SwitchDecorator
- type Switcher
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrSkippedItem = errors.New("skipped item")
ErrSkippedItem: a step drops the value on purpose — not an error, never reported
Functions ¶
This section is empty.
Types ¶
type ChainProcessor ¶
ChainProcessor: steps that run together, one pass (Process); a chain is a step too (a sub-chain)
func NewChainProcessor ¶
func NewChainProcessor(errch chan<- error) ChainProcessor
NewChainProcessor: errch gets the steps' errors (nil: the errors of the chain this one runs in)
type Decorator ¶
Decorator: a step's logic — one value in, one out (or an error). Optional: Stopper, Flusher.
type EntryPoint ¶
EntryPoint: the logic of a chain's entry — one pass: every value it finds, emitted (emit is false once the chain stops). Optional: Stopper.
type Processor ¶
type Processor interface {
// contains filtered or unexported methods
}
Processor: a step, or a chain of steps
func NewDecorator ¶
NewDecorator: every value of in through the logic, to out
func NewDecoratorN ¶
func NewDecoratorN[Ti, To any](in <-chan Ti, out chan<- To, logic Decorator[Ti, To], n int) Processor
NewDecoratorN: the same on n workers (the logic safe for concurrent use; the order may change)
func NewEntryPoint ¶
func NewEntryPoint[T any](out chan<- T, logic EntryPoint[T]) Processor
NewEntryPoint: the chain's one input, an output only; when it is done, its output closes
func NewSwitchDecorator ¶
func NewSwitchDecorator[Ti, To any](in <-chan Ti, outs []chan<- To, logic SwitchDecorator[Ti, To]) Processor
NewSwitchDecorator: a value, turned into another, to one output
func NewSwitchDecoratorN ¶
func NewSwitchDecoratorN[Ti, To any](in <-chan Ti, outs []chan<- To, logic SwitchDecorator[Ti, To], n int) Processor
NewSwitchDecoratorN: the same on n workers (the order may change)
type Stopper ¶
type Stopper interface{ Stop() }
Stopper: a step's logic may have one; it is called once, when the step ends
type SwitchDecorator ¶
SwitchDecorator: a switch's logic that also turns the value into another (the output's index and the new value). Optional: Stopper.