Skip to content

[Context]: add MaxConcurrency ExecutionOptions with caller-supplied semaphore #17

Description

@rian-be

Summary

Add a bounded-concurrency extension: ExecutionOptions with MaxConcurrency and a caller-supplied SemaphoreSlim, limiting how many context-scoped operations run at once (async-only).

Goal

Prevent resource exhaustion (SQL connection-pool starvation, external API rate limits, memory pressure) when running context-scoped batches, following the caller-supplied-resources principle.

Problem

ExecuteAllInContext (the parallel-run issue) launches all tasks at once; on real workloads that dangerously saturates connection pools and external quotas. There is no uniform limit, and users currently hand-roll SemaphoreSlim wrapping around each ExecuteInContext.

Scope

  • ExecutionOptions with MaxConcurrency and strategy token.
  • Caller-supplied SemaphoreSlim option (enables one global limit shared across many IContextManager calls).
  • ExecuteParallelAsync(ctx, source, options, work) that awaits on the semaphore before each work item.
  • Unit tests simulating concurrency cap (SQL pool / API quota scenarios).
  • Async-only; never blocks a thread (no sync-over-async).

Design Expectations

  • Caller-supplied resources: Core does not manage global semaphore state; an instance may be passed in ExecutionOptions.
  • Resource ownership stays with the caller/integrator.
  • No global lock in Core; each invocation works from the provided options.
  • Safe under connect-pool, external-API, and memory-pressure scenarios (Performance section 2.2).

Acceptance Criteria

  • No more than MaxConcurrency operations run simultaneously.
  • A single shared SemaphoreSlim silimits the combined throughput of several calls when supplied.
  • Implementations are fully async (no thread blocking).
  • Works together with the base fork-join extension (ExecuteAll) as an alternative path.

Non-Goals

  • No global registry or library-owned semaphore.
  • No ordering guarantee; ordering is a separate issue (Ordered/Unordered).
  • No chunking (partitioned batches live in the MapParallel issue).
  • No work-visualization / aggregation logic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    concurrencyParallel / batch / async executionenhancementNew feature or requestextensionExtension behaviors / helpers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions