Documentation
¶
Overview ¶
Package concurrent provides utilities for executing multiple functions concurrently with error propagation, context cancellation, and panic recovery.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExecuteConcurrently ¶
func ExecuteConcurrently[T any](ctx context.Context, funcs map[string]Func[T]) (map[string]T, error)
ExecuteConcurrently executes multiple functions concurrently and collects their results.
All functions receive a shared cancellable context. When any function returns an error or panics, the context is canceled to signal other goroutines to stop.
Returns a map of results indexed by the provided keys, and the first causal error encountered (preferring real errors over context cancellation errors). If a function panics, the panic is recovered and converted to an error.
Note: Only the first causal (non-context) error is returned. Secondary errors from other goroutines are discarded.
Example ¶
ExecuteConcurrently runs named functions in parallel and returns their results keyed by name.
package main
import (
"context"
"fmt"
"github.com/jasoet/pkg/v3/concurrent"
)
func main() {
funcs := map[string]concurrent.Func[string]{
"greeting": func(ctx context.Context) (string, error) {
return "hello", nil
},
"name": func(ctx context.Context) (string, error) {
return "world", nil
},
}
results, err := concurrent.ExecuteConcurrently(context.Background(), funcs)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(results["greeting"], results["name"])
}
Output: hello world
func ExecuteConcurrentlyTyped ¶
func ExecuteConcurrentlyTyped[R any, T any]( ctx context.Context, resultBuilder func(map[string]T) (R, error), funcs map[string]Func[T], ) (R, error)
ExecuteConcurrentlyTyped executes multiple functions concurrently and transforms the results into a typed value using the provided resultBuilder function.
This is a more type-safe alternative to ExecuteConcurrently when you know the exact structure of the results.
Type parameters are result-first: instantiate as ExecuteConcurrentlyTyped[Output, Input].
Example ¶
ExecuteConcurrentlyTyped adds a result builder on top of ExecuteConcurrently. Type parameters are result-first: ExecuteConcurrentlyTyped[Output, Input].
package main
import (
"context"
"fmt"
"github.com/jasoet/pkg/v3/concurrent"
)
func main() {
funcs := map[string]concurrent.Func[int]{
"users": func(ctx context.Context) (int, error) {
return 10, nil
},
"orders": func(ctx context.Context) (int, error) {
return 32, nil
},
}
summary, err := concurrent.ExecuteConcurrentlyTyped[string, int](
context.Background(),
func(results map[string]int) (string, error) {
return fmt.Sprintf("users=%d orders=%d", results["users"], results["orders"]), nil
},
funcs,
)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(summary)
}
Output: users=10 orders=32