The workflow runner executes one action at a time per node
- Dominant language
- C#
- Stars
- 6
- Forks
- 7
- Avg merge
- 4h 42m
- Merged PRs (30d)
- 307
Description
`WorkflowRunner.RunOnceAsync` returns as soon as it claims and executes a single attempt:
```csharp
foreach (var candidate in due)
{
if (await TryRunAsync(store, candidate.Id, tenantId, ct)) return true;
}
```
`ExecuteAsync` loops and calls it again, so a node runs attempts strictly in series. Every action is a call to a third party: `EmailAction`, `SmsAction`, `WebhookAction`, `RequestAction`. At two seconds per webhook that is half an action per second per node, and adding CPU or memory changes nothing.
`WorkflowRunTests` confirms the shape rather than contradicting it. It drains with `while (await runner.RunOnceAsync(...))`, one attempt per call.
### What to change
Claim a batch of attempts and execute them under bounded concurrency, with the degree read from configuration.
The lease model already supports this. `WorkflowActionAttempt.LeasedBy` and `LeaseExpiresAt` exist so two nodes can hold different attempts at once, and nothing in the claim path assumes one attempt in flight per node. What changes is the loop, not the durability model.
Two constraints to keep:
- Attempts within one run stay ordered. `NextDue` returns at most one attempt per run and that is deliberate: "post to Facebook, then email, then tweet" reads as a sequence and an operator who wrote it that way means it. Concurrency goes across runs, not within one.
- The bound is per node and configured, defaulting low. Unbounded parallelism turns a burst into a self-inflicted rate limit against a provider, which is the failure `WorkflowRetryPolicy.Backoff` already carries jitter to avoid.
### How it should be tested
Queue N runs against a handler with a known delay and assert elapsed time, so serial and concurrent execution differ visibly. A test that only asserts every run eventually completes passes today and would pass after a change that did nothing.
### Where I checked
`barakoCMS/Features/Workflows/WorkflowRunner.cs`, `BarakoCMS.Tests/Features/Workflows/WorkflowRunTests.cs`. Searched open issues for runner throughput and concurrency. #329 designed the current projection/runner split and is closed. Nothing open covers this.
Contributor guide
Research direction
Start in barakoCMS/Features/Workflows/WorkflowRunner.cs by reading RunOnceAsync, ExecuteAsync, and the existing claim path; then run BarakoCMS.Tests/Features/Workflows/WorkflowRunTests.cs. Add a timing-based test with N delayed runs and make the configured concurrency visible while preserving ordering within each run and bounded execution per node.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend, performance, testing
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100