Documentation
¶
Overview ¶
Package parallel is a utility package for running parallel/concurrent tasks.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Go ¶
func Go(run func()) (wait func())
Go is like the 'go' keyword but returns a function that blocks until the goroutine exits. Its safe to call the returned wait function multiple times
Example ¶
x := 3 wait := Go(func() { x++ }) // do some other work wait() log.Print(x) // Outputs: 3
Output:
func GoCaptureError ¶
GoCaptureError is like the go keyword but returns a function that blocks until the goroutine exits, the returned error from the goroutine function is available as the result of calling the retuned wait() function. Its safe to call the returned wait function mutliple times, it'll always report the same result
func Invoke ¶
Invoke runs the given callbacks concurrently. All the callbacks are run in a child of 'ctx'. If any of the callbacks returns an error, Invoke cancels this child context, waits for the remaining callbacks to complete, and returns the first error. Otherwise, Invoke waits for all the callbacks to complete, then returns nil.
func InvokeN ¶
InvokeN runs the given callback 'n' times concurrently. It invokes the callbacks with i=0, i=1, ..., i=n-1 in a child of 'ctx'. If any of the callbacks returns an error, InvokeN cancels this child context, waits for the remaining callbacks to complete, and returns the first error. Otherwise, InvokeN waits for all the callbacks to complete, then returns nil.
Example (Map) ¶
It's easy to implement a concurrent map operation using InvokeN.
ctx := context.Background() // A concurrent map: res = map(in, isEven). isEven := func(x int) bool { return x%2 == 0 } in := []int{5, 6, 7} res := make([]bool, 3) _ = InvokeN(ctx, len(in), func(ctx context.Context, i int) error { res[i] = isEven(in[i]) return nil }) fmt.Printf("result: %v\n", res)
Output: result: [false true false]
Example (MapRPC) ¶
More realistically, we'll want to call some server(s) for the results.
type Request struct { x int replyCh chan bool } requestCh := make(chan Request) go func() { // server for req := range requestCh { isEven := req.x%2 == 0 req.replyCh <- isEven } }() rpc := func(ctx context.Context, x int) (bool, error) { req := Request{x: x, replyCh: make(chan bool, 1)} select { case requestCh <- req: select { case res := <-req.replyCh: return res, nil case <-ctx.Done(): return false, ctx.Err() } case <-ctx.Done(): return false, ctx.Err() } } in := []int{10, 11, 12} res := make([]bool, 3) ctx := context.Background() err := InvokeN(ctx, len(res), func(ctx context.Context, i int) error { var err error res[i], err = rpc(ctx, in[i]) return err }) close(requestCh) // stop the server if err != nil { panic("Unexpected error: " + err.Error()) } fmt.Printf("result: %v\n", res)
Output: result: [true false true]
Types ¶
This section is empty.