* feat(workflows-runtime): add quiescence machinery foundation for graceful shutdown
Introduces the container-scoped quiescence signal, ingress-source contract,
burst registry, and the Interrupted workflow sub-status — the foundational
primitives the drain orchestrator and admin endpoints will build on. No
behaviour change yet: workflows continue to run and shut down exactly as
before. The new types are registered but no host-stop or pause path drives
them.
Highlights:
* IQuiescenceSignal — composable Drain + AdministrativePause flags;
forward-only drain, reversible pause, idempotent transitions, optional
persistence via IKeyValueStore.
* IIngressSource + IForceStoppable — uniform contract for components that
inject external events (HTTP, schedulers, message consumers, internal
workers, third-party modules); IIngressSourceRegistry collects and
surfaces their states.
* IBurstRegistry — atomic counter for in-flight workflow execution
bursts, with per-burst ingress attribution and FR-018 inconsistency
detection (a source claiming Paused but starting bursts is flipped to
PauseFailed).
* WorkflowSubStatus.Interrupted — new value distinct from Suspended,
Cancelled, Faulted; semantics: "last burst force-cancelled by graceful
drain; resumable on next runtime generation". Mirrored on the API client
enum.
* GracefulShutdownOptions — drain deadline, per-source pause timeout,
stimulus-queue back-pressure policy, pause-persistence policy.
Configurable via UseWorkflowRuntime(...).ConfigureGracefulShutdown(...).
* PermissionNames.ManageWorkflowRuntime — single permission for the
forthcoming admin pause/resume/status/force endpoints.
Implements 31 of 77 tasks for the graceful-shutdown feature
(specs/002-graceful-shutdown). Subsequent commits add the drain
orchestrator (US1 / MVP), Interrupted recovery scan (US3), admin
endpoints (US2), and first-party ingress adapters.
Tests: 25 new xUnit unit tests; 100/100 runtime unit tests pass; all
existing tests continue to pass on net8.0/net9.0/net10.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(workflows-runtime): add drain orchestrator + host-stop integration (US1, MVP)
When the host receives a stop signal (SIGTERM, Ctrl+C, orchestrator
rollout), the runtime now drains gracefully: ingress sources are paused
in parallel, in-flight workflow bursts run to their next natural
persistence boundary within a configurable deadline, and any burst that
breaches the deadline is force-cancelled and persisted with the
Interrupted sub-status plus a forensic WorkflowInterrupted log entry.
This is the MVP — without the activation-time recovery scan (PR 3) the
existing timeout-based RestartInterruptedWorkflowsTask still picks up
Interrupted instances, just on its periodic cadence. No regression in
that recovery path (SC-008).
Highlights:
* IDrainOrchestrator + DrainOrchestrator — protocol per the contract:
BeginDrainAsync → parallel ingress pause with per-source timeouts +
IForceStoppable escalation → poll BurstRegistry.ActiveCount until zero
or deadline → on breach iterate live handles, cancel, persist
Interrupted, write log entry. All exceptions are captured into the
returned DrainOutcome; only second-invocation throws.
* Deadline clamping: effective deadline is min(GracefulShutdownOptions.
DrainDeadline, HostOptions.ShutdownTimeout - 500ms safety epsilon),
so the runtime never outlives its host process.
* DrainOrchestratorHostedService — IHostedService.StopAsync wakes the
orchestrator on host stop. Registered AFTER the heartbeat
(Elsa.Hosting.Management) so reverse-order shutdown keeps the
heartbeat alive throughout drain. Prevents sibling-node crash recovery
from false-positive-recovering instances we are gracefully handling
here (FR-029).
* BurstTrackingMiddleware — workflow-execution-pipeline middleware that
registers a BurstHandle for the lifetime of every burst. All nine
IWorkflowRunner.RunAsync overloads ultimately funnel into
pipeline.ExecuteAsync(context), so this single middleware covers the
three "burst choke points" the spec references without nine separate
decorators. Added to UseDefaultPipeline().
* Ingress attribution: optional IngressSourceName property on
DispatchStimulusRequest, DispatchWorkflowDefinitionRequest, and
DispatchWorkflowInstanceRequest. Adapters set it; the middleware reads
it via WorkflowExecutionContext.TransientProperties (helpers in
IngressAttributionExtensions). The BurstRegistry uses the name to
detect the FR-018 invariant violation — a source that reports Paused
but starts a burst is flipped to PauseFailed.
* InterruptedLogExtensions — the LogWorkflowInterruptedAsync helper
that the orchestrator calls when persisting the forensic record.
Tests: 11 new unit tests (DrainOrchestrator parallel-pause +
wait-for-bursts + idempotency + persistence-failure path); 5 new
integration tests (full DI graph resolves, burst-tracking middleware
registers handles end-to-end, no-op drain returns
CompletedWithinDeadline). 100/100 runtime unit tests pass; all
existing tests continue to pass on net8.0/net9.0/net10.0.
Implements 14 of 77 tasks (T032–T045). Subsequent commits add
Interrupted recovery scan (US3), admin endpoints (US2), and
first-party ingress adapters.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(admin-endpoints): add admin endpoints for workflow runtime control
Introduced admin endpoints to manage workflow runtime: `/pause`, `/resume`, `/status`, and `/force` with full authentication and audit logging. Integrated idempotency checks and error handling to ensure reliable runtime control. Added corresponding integration tests for verification.
* fix(workflows-runtime): propagate drain cancellation into running workflows + initialize persisted pause + fix log-comment
Addresses three findings from the PR #7424 code review:
1. **HIGH — Cancellation now propagates into the running workflow.**
`BurstHandle.Cancel()` previously cancelled only its own linked CTS,
which the workflow runner never observes (the runner reads from
`WorkflowExecutionContext.CancellationToken`, captured at context
construction and not part of the linked chain). On deadline breach
the orchestrator would persist `Interrupted`, but the workflow
continued executing and could overwrite the sub-status with whatever
terminal state it eventually reached.
Fix: `BurstHandle` accepts an optional cancel callback at construction.
`BurstTrackingMiddleware` wires it to `context.Cancel()` so the burst's
cancellation triggers the workflow's own cancellation chain — the
workflow transitions to `Cancelled` and stops scheduling new
activities. The orchestrator then awaits `BurstHandle.Disposed` (with
a 2 s settle timeout) before persisting `Interrupted`, ensuring the
runner's terminal commit completes BEFORE the orchestrator overwrites
the sub-status. Race resolved.
The settle timeout is bounded so a non-cancellable activity (genuinely
pathological case) does not block drain — on timeout the orchestrator
logs and proceeds, accepting the runner-clobber for that one
instance, which the existing timeout-based RestartInterruptedWorkflows
recovery picks up afterwards.
2. **MEDIUM — Pause persistence is now actually wired.**
`QuiescenceSignal.InitializePersistedStateAsync` was implemented but
nothing called it on host startup. A host configured with
`PausePersistence = AcrossReactivations` would write the persisted
key on pause, but on subsequent activation the new
`QuiescenceSignal` instance would never read it, so the runtime would
resume dispatching despite the operator having paused.
Fix: `InitializePauseStateStartupTask : IStartupTask` reads the policy
and calls `InitializePersistedStateAsync` once per activation when the
policy demands it. Registered in both `WorkflowRuntimeFeature`
flavours alongside the other graceful-shutdown services.
3. **MEDIUM — Comment in `DrainOrchestrator.PersistInterruptedAsync` no
longer lies.** The previous comment promised a "synthetic log entry"
that the next statement (`return`) prevented from being written. The
comment is now honest about what actually happens: when no instance
row exists, no log entry is emitted, but the burst metadata is still
captured in the drain outcome's logged warning so operators have a
forensic trail.
Tests:
* New unit tests on `BurstRegistry` (now 9, was 6): cancel-callback is
invoked, callback exceptions are swallowed (drain remains best-effort),
`BurstHandle.Disposed` completes on dispose.
* Full suites continue to pass: 103/103 runtime unit tests; 247/247
workflow integration tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime): address PR review feedback + close runner-clobber race + add e2e drain test
Six issues raised in PR #7424 review (one e2e gap, five comments inline):
1. **Runner-clobber race closed via ICommitStateHandler decorator.**
The previous fix wired `BurstHandle.Cancel()` to `WorkflowExecutionContext.Cancel()`
so the workflow's cancellation chain fires on deadline breach, but the e2e
test exposed that `BurstHandle` disposed at the END of the pipeline middleware
(i.e., BEFORE `WorkflowRunner` calls `commitStateHandler.CommitAsync`). The
orchestrator's `await handle.Disposed` therefore returned too early, the
instance row didn't yet exist, and the orchestrator's Interrupted write was
either a no-op (no row) or got clobbered by the runner's subsequent Cancelled
commit.
Fix: `BurstAwareCommitStateHandler` decorates `ICommitStateHandler`. The
middleware no longer disposes the handle in the success path — it stores
the handle in `WorkflowExecutionContext.TransientProperties`, and the
decorator disposes it AFTER `inner.CommitAsync` completes. The exception
path in the middleware still disposes for safety. Result: the orchestrator's
await-disposed sequencing now correctly lands the Interrupted write last.
2. **C1: Null-instance log entry.** `DrainOrchestrator.PersistInterruptedAsync`
now writes a synthetic `WorkflowInterrupted` log entry directly when no
instance row exists, populating only the fields it knows. Previously the
forensic trail was lost.
3. **C2: Force endpoint cached-outcome audit.** Added `WasCached` flag to
`DrainOutcome` (default false). The orchestrator sets it on the cached
return path (`_previousOutcome with { WasCached = true }`). The force
endpoint now skips the audit notification when the flag is true, so
repeated force calls no longer emit spurious `RuntimeForceRequested` events
(SC-007 idempotency restored).
4. **C3: `StateChanged` raised under lock — deadlock risk closed.**
`QuiescenceSignal.BeginDrainAsync`/`PauseAsync`/`ResumeAsync` now do their
transitions under the lock, capture whether a transition occurred, release
the lock, and only then invoke `RaiseStateChanged`. Subscribers that
synchronously call back into the signal can no longer deadlock.
5. **C4: Scheduling source name.** Renamed `scheduling.cron` → `scheduling.triggers`
to honestly reflect the four trigger types the adapter covers (Cron, Timer,
StartAt, Delay). The name is surfaced verbatim in admin status responses.
6. **C5: Hardcoded Retry-After.** `HttpWorkflowsMiddleware`'s 503 response now
sets a reason-aware `Retry-After`: 5 s during drain (host is exiting and
will be replaced shortly), 60 s during administrative pause (indefinite,
so a longer back-off avoids tight retry loops).
Tests:
* New e2e `DeadlineBreachEndToEndTests` (2 tests): verifies that drain
against a real running workflow detects the in-flight burst, force-cancels
it, persists the instance as `Interrupted`, and writes a `WorkflowInterrupted`
log entry — closing the test gap that hid the cancellation-propagation
issue identified in the previous review pass.
* Updated `OperatorForceAfterPreviousReturnsCachedOutcome` to assert
value-equality + the `WasCached` flag instead of reference-equality
(records use `with` for the cached return path).
Full suites pass: 103/103 runtime unit, 249/249 workflow integration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(workflows-api): move runtime admin endpoints into Elsa.Workflows.Api
Per PR review feedback: rather than introducing a new sub-module
(Elsa.Workflows.Runtime.Admin) for the four pause/resume/status/force
endpoints, fold them into the existing Elsa.Workflows.Api project. That
project already references both Elsa.Workflows.Runtime and
Elsa.Api.Common (FastEndpoints) and is the established home for
client-facing workflow APIs — so the admin endpoints belong there.
Changes:
* New folder src/modules/Elsa.Workflows.Api/Endpoints/RuntimeAdmin/ with
Models.cs and Pause/Resume/Status/Force/Endpoint.cs. Namespaces moved
from `Elsa.Workflows.Runtime.Admin` → `Elsa.Workflows.Api.Endpoints.RuntimeAdmin`.
* Deleted src/modules/Elsa.Workflows.Runtime.Admin/ entirely and removed
it from Elsa.sln. The ShellFeature marker class
(WorkflowRuntimeAdminFeature) is no longer needed — the existing
WorkflowsApiFeature already discovers FastEndpoints in the Workflows.Api
assembly.
* No consumer changes: the endpoints sit in the same routes
(/admin/workflow-runtime/*) and behave identically.
Note on the second architectural point ("update IShellFeature if cleaner"):
the IShellFeature contract is defined in the external CShells NuGet
package, not in this repo, so we cannot add a DeactivateAsync hook
without an upstream CShells change. The current IHostedService.StopAsync
hook continues to work correctly for the host-stop path; per-shell
deactivation would require either a CShells upstream addition or a
separate Elsa-owned shell-feature variant — neither lighter than what we
have today.
Tests: 103/103 runtime unit + 249/249 workflow integration pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(common): introduce IsFatal exception extension + apply to drain best-effort catches
Per PR review feedback on the static-analyzer "Generic catch clause"
comments: rather than catching ALL exceptions in best-effort drain code
paths, narrow the swallow to non-fatal exceptions. Process-fatal
conditions (StackOverflowException, AccessViolationException,
SEHException, ThreadAbortException, OutOfMemoryException) propagate so
the host's failure-fast policy can act on them, while normal failures
(InvalidOperationException, IOException, etc.) continue to be logged
and allowed through so a single misbehaving ingress source / activity
cannot abort the overall drain.
Highlights:
* New `Elsa.Common.Extensions.ExceptionExtensions.IsFatal` utility:
classifies fatal conditions, unwraps reflection-style wrappers
(TypeInitializationException, TargetInvocationException) before
classification, and treats InsufficientMemoryException (the
recoverable OOM subclass) as non-fatal.
* Applied as a `when (!ex.IsFatal())` filter to:
- BurstHandle.Cancel (cancel callback try/catch)
- DrainOrchestrator.PauseOneSourceAsync (per-source exception path)
- DrainOrchestrator.TryForceStopAsync
- DrainOrchestrator.ForceCancelActiveBurstsAsync (per-burst loop)
- DrainOrchestrator.PersistInterruptedAsync (orphan log write,
instance save, log write)
- DrainOrchestrator.DrainAsync outer catch (existing
`not InvalidOperationException` filter extended)
- InterruptedRecoveryScan (per-instance restart loop)
Tests: 7 new unit tests for IsFatal classification (fatal types,
recoverable types, wrapped causes, null tolerance). Full suites:
103/103 runtime unit (incl. 14/14 in Common.UnitTests including new
tests) + 249/249 workflow integration pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(workflows-runtime): integrate CShells 0.0.15 lifecycle hooks (IDrainHandler + IShellInitializer)
CShells 0.0.15 ships the lifecycle framework needed for first-class per-shell
graceful shutdown — IDrainHandler / IShellInitializer / IShellLifecycleSubscriber.
This commit bumps the package, migrates Elsa's existing usage of the removed
0.0.14 API, and registers the runtime drain orchestrator + pause-state initializer
through the new primitives.
Highlights:
* `ElsaShellDrainHandler : IDrainHandler` — bridges per-shell drain into
`IDrainOrchestrator.DrainAsync(DrainTrigger.ShellDeactivation, ct)`. Invoked
by CShells when a shell enters `ShellLifecycleState.Draining`; the drain
handler's CancellationToken is signalled when the per-shell deadline elapses,
so the orchestrator's own deadline-bounded protocol nests cleanly.
Coexists with the host-stop `DrainOrchestratorHostedService`; the
orchestrator's `DrainAsync` is idempotent — second invocations log and skip.
* `InitializePauseStateShellInitializer : IShellInitializer` — replaces the
IStartupTask variant in shell-aware deployments. IShellInitializer fires on
EVERY shell (re)activation, including reactivations after a reload — exactly
what FR-028 requires. The IStartupTask remains for IModule consumers where
there is no shell platform.
Migrations (CShells 0.0.14 → 0.0.15 breaking changes):
* `ActivateShellTenants`: was `IShellActivatedHandler` + `IShellDeactivatingHandler`,
now `IShellInitializer` + `IDrainHandler`.
* `MultitenancyFeature`: registrations updated to the new transient interface,
`using CShells.Hosting` → `using CShells.Lifecycle`.
* `Reload/Endpoint`, `ReloadAll/Endpoint`: `IShellManager` → `IShellRegistry`,
`ReloadShellAsync` → `ReloadAsync` (returns `ReloadResult` with `Error`),
`ReloadAllShellsAsync` → `ReloadActiveAsync` (returns
`IReadOnlyList<ReloadResult>` with per-shell errors aggregated into 503).
Build + restore:
* `Directory.Packages.props`: all CShells.* packages bumped to 0.0.15.
* `NuGet.Config`: added `cshells-feedz` source
(https://f.feedz.io/sfmskywalker/cshells/nuget/index.json) and split the
package-source-mapping pattern into `CShells` (exact) + `CShells.*`
(prefix). Single-pattern `CShells*` does NOT match correctly under
PackageSourceMapping.
Tests: 103/103 runtime unit + 249/249 workflow integration pass on the new
package version.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(workflows-runtime): apply PR #7424 review feedback
Consolidates the architectural fixes asked for during /review:
- Extract IWorkflowRuntimeAdminService to back the four /admin/workflow-runtime endpoints with a single domain service; thin Pause/Resume/Status/Force endpoints to delegating shells.
- Remove StateChanged C# event from IQuiescenceSignal (Constitution VII: no external subscribers existed; mediator was suggested as the alternative if/when it's needed).
- Promote InitializePersistedStateAsync to IQuiescenceSignal, dropping the concrete-cast in both InitializePauseStateStartupTask and InitializePauseStateShellInitializer.
- Invert ingress-source DI to Lazy<IEnumerable<IIngressSource>> to break the cycle through IQuiescenceSignal; ingress adapters take the signal directly via primary constructor.
- Replace Guid.NewGuid().ToString("N") with IIdentityGenerator in InterruptedLogExtensions and DrainOrchestrator.
- Switch admin-audit timestamps to ISystemClock in WorkflowRuntimeAdminService.
- Make GracefulShutdownOptions.StimulusQueueMaxDepthWhilePaused nullable (null = unlimited).
- Rename RuntimeForceRequested → RuntimeForceDrainRequested.
- Apply IsFatal exception filter to drain best-effort catches.
- Rename IBurstRegistry.EnumerateActive → ListActiveBursts.
- Refresh "Phase X" comments to user-story (USx) references.
- Delete unused IngressAttributionExtensions, IngressSourceServiceCollectionExtensions, IngressSourceRegistrationOptions.
- Migrate Elsa.Shells.Api.Tests to CShells 0.0.15 IShellRegistry / ReloadResult surface.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(graceful-shutdown): apply IsFatal filter to deadline-breach test catch
Aligns the test scaffolding's swallow-everything catch with the project standard introduced in c00eee80c so the analyzer no longer flags the bare `catch` clause. The semantics are unchanged — non-fatal exceptions (OCE, TimeoutException, workflow exceptions) are still acceptable test outcomes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime): close IngressSourceRegistry first-access race + spelling
Replaces the non-atomic `_entries.Count > 0` early-return guard in
EnsureMaterialized with a double-checked lock against a volatile
`_materialized` flag, so concurrent first callers can no longer both
iterate the source factory and crash one of them with a "Duplicate ingress
source registration" InvalidOperationException. Adds a regression test that
launches 16 readers behind a TaskCompletionSource gate and asserts every
reader observes the full source set without throwing.
Also flips the British spellings introduced in this PR's scope to American
English (materialize/behavior) — project convention going forward.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(constitution): require American English for new code (v1.0.1)
Adds a "Spelling & language" bullet under principle III (Convention-Driven Design): every newly-introduced symbol, comment, identifier, error message, XML doc, commit message, and Speckit artifact uses American English. Established public API symbols (e.g. WorkflowSubStatus.Cancelled) are not renamed retroactively. PATCH bump because this is a clarification of an existing principle, not a new principle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add Greploop skill and workflow for GitLab, GitHub, and Perforce integration
- Introduced Greploop, an iterative optimization and review workflow for GitLab MRs, GitHub PRs, and Perforce changelists.
- Added API and GraphQL references for fetching and resolving review skill.
* Remove GenerateWorkflowVariableAccessorsTests; redundant ExpandoObject type check in handlers
* Potential fix for pull request finding 'CodeQL / Untrusted Checkout TOCTOU'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix(graceful-shutdown): apply PR #7424 review feedback round 2
Two P1 findings from Greptile:
1. DrainOrchestrator.ForceCancelActiveBurstsAsync was sequential — each
burst was cancelled, awaited up to ForceCancelSettleTimeout (2 s), and
persisted before the next burst's Cancel() ran. Total wall time was
O(N × 2 s) and bursts 2..N kept executing at full speed during prior
bursts' settle waits, defeating the intent of force-cancel under
concurrency.
Refactored to three phases:
- Phase A — cancel every handle synchronously (cheap CTS.Cancel calls)
so all runners observe cancellation simultaneously.
- Phase B — await every Disposed signal in parallel under a single
shared ForceCancelSettleTimeout. Total wall time bounded regardless
of N.
- Phase C — persist Interrupted for each handle sequentially (keeps
DbContext usage single-threaded; per-handle work is small).
Per-phase failures are caught with !ex.IsFatal() and logged so a single
misbehaving handle doesn't abort the rest of the batch.
2. ShellFeatures/WorkflowRuntimeFeature.ConfigureServices was missing the
IWorkflowRuntimeAdminService registration that Features/WorkflowRuntimeFeature
already had. Any CShells deployment that includes the Pause / Resume /
Status / Force admin endpoints (in Elsa.Workflows.Api) would throw
InvalidOperationException at endpoint construction. Added the singleton
alongside the other graceful-shutdown registrations with a comment
pointing out the symmetry with the IModule path.
17/17 graceful-shutdown integration tests pass; 103/103 runtime unit tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Potential fix for pull request finding 'CodeQL / Untrusted Checkout TOCTOU'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix(ci): harden greploop.yml against CodeQL Actions findings
CodeQL flagged 12 findings on .github/workflows/greploop.yml after the
prior commit (c08183a3c) addressed an earlier round. Two distinct issue
classes remain:
1. Code injection (× ~10): step-output values
(steps.pr_head.outputs.head_sha / head_repo_owner / head_repo_name /
head_ref) and inputs.pr_number were interpolated directly into shell
`run:` blocks via `${{ ... }}`. Because PR author controls the branch
name and the manual-dispatch input, those values can carry shell
metacharacters. Standard fix: route every such interpolation through
an `env:` block on the step, then reference $VAR inside the script.
Applied to the Resolve, Resolve PR head metadata, and Checkout PR
branch steps.
2. Untrusted Checkout TOCTOU + Checkout of untrusted code in trusted
context: the workflow runs on `issue_comment` (a privileged trigger)
and checks out PR-author code. Mitigations stacked here:
- Author-association gate already restricts the trigger to OWNER /
MEMBER / COLLABORATOR (existing).
- Step-output values now travel via env vars (above).
- Resolve step rejects pr_number that isn't ^[0-9]{1,10}$ — so
downstream `gh pr view` and the prompt argument can't be hijacked.
- Checkout step now validates HEAD_SHA matches ^[0-9a-f]{40}$ and the
repo owner/name match ^[A-Za-z0-9_.-]+$ before either reaches a
URL or a git command.
- Existing TOCTOU guard preserved: re-fetch head SHA at checkout
time and abort if it changed since the initial resolve.
These match the canonical "Securing your GitHub Actions workflows"
patterns recommended by CodeQL.
No functional change to greploop's runtime behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(graceful-shutdown): drop [SingleNodeTask] from InitializePauseStateStartupTask
Greptile P1: [SingleNodeTask] gates the task to a single cluster winner via
distributed lock, but IQuiescenceSignal is a singleton scoped to each node's
DI container — each node holds its own in-memory QuiescenceState. With the
attribute, only the winning node restored the persisted pause; every other
node started with QuiescenceReason.None and accepted new work, silently
defeating PausePersistence = AcrossReactivations.
Removed [SingleNodeTask] (and the corresponding using) so the task runs on
every node. Expanded the doc <remarks> to call out the per-node requirement
and point at the shell-aware counterpart (InitializePauseStateShellInitializer)
which is correctly per-node by virtue of being an IShellInitializer.
17/17 graceful-shutdown integration tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Potential fix for pull request finding 'CodeQL / Code injection'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* chore(deps): bump CShells 0.0.15 → 0.0.17
0.0.17 ships our blueprint-aware-routing PR (valence-works/cshells#93) plus
four follow-up fixes the maintainer added on top:
- e56ebd8 — PreWarmShells removed entirely; ShellMiddleware now does
cold-start endpoint matching (re-runs endpoint resolution after lazy
activation so the very first request to a cold shell hits its endpoint).
- cbe5ee2 — GetCandidateSnapshot returns a bounded ShellRouteCandidateSnapshot
with accurate total counts; sensitive-data redaction in routing logs;
DefaultShellRouteIndex implements IDisposable.
- cd7d4f5 — Last-good snapshot served on rebuild failure (the deferred
Copilot review concern); root-path fallback when path-by-name misses.
- c3679d9 — Cold-start endpoint matching respects inline route constraints;
path-name convention tightening; dead duplicate-detection cleanup.
Net effect for elsa-core:
- Cold blueprints serve their first request via lazy activation, with
endpoints correctly resolved post-activation.
- Reloaded shells re-activate and serve on the next matched request.
- Non-name-mode routing keeps serving the previous snapshot during a
transient blueprint-provider outage.
- No need to call PreWarmShells from Elsa.ModularServer.Web — removed.
The only API removal that touches elsa-core is PreWarmShells. No code
references IShellRouteIndex / ShellRouteCriteria / GetCandidateSnapshot
directly, so the API-shape changes in cbe5ee2 don't ripple here.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(graceful-shutdown): persist Interrupted under non-drain bounded token
Greptile P? finding on the prior force-cancel two-phase fix: Phase B's
inner catch on OperationCanceledException ("drain CT fired — proceed to
persist anyway") was a lie in practice. Phase C immediately passed the
same already-cancelled drain token into PersistInterruptedAsync; the
first DB call (instanceStore.FindAsync) observed the cancellation and
threw OperationCanceledException; the outer non-fatal Exception filter
swallowed it and only logged an error. Net effect: on host shutdown
deadline breach, every burst after cancellation could fail to be
persisted as Interrupted, leaving instances in an unrecovered executing
state.
Phase C now creates a per-handle CancellationTokenSource bounded to a
new PersistInterruptedTimeout (5 s) that is NOT linked to the drain CT.
Each persist gets up to 5 s to land the row update + forensic log entry
even after the drain CT has fired. The bound prevents a stuck DB from
hanging shutdown indefinitely (per-handle worst case is small; total
Phase C upper bound is N × 5 s, but typical persists are millisecond
scale).
Comment expanded to call out why the persist token is independent of
the drain token, so the rationale doesn't drift again.
17/17 graceful-shutdown integration tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(graceful-shutdown): extract PassiveIngressSource base class
The three IIngressSource implementations that ship with this PR
(InternalBookmarkQueueIngressSource, HttpTriggerIngressSource,
ScheduledTriggerIngressSource) were ~25 lines each and ~22 lines of
those were verbatim copies of each other:
- ctor signature `(IQuiescenceSignal signal)`
- `PauseTimeout => TimeSpan.FromMilliseconds(50)`
- `CurrentState => signal.IsAcceptingNewWork ? Running : Paused`
- `PauseAsync` / `ResumeAsync` returning `ValueTask.CompletedTask`
The shared trait is that none of them does any work at pause time —
the actual pause enforcement lives in another layer
(`HttpWorkflowsMiddleware` short-circuits to 503,
`BookmarkQueueProcessor` consults the signal at the top of each
invocation, scheduled triggers dispatch through the bookmark queue and
inherit that behaviour transitively). The IIngressSource adapter is
purely diagnostic: it makes the source visible in
`DrainOutcome.Sources` and the admin status endpoint.
Extracted that pattern into `PassiveIngressSource` (abstract base in
`Elsa.Workflows.Runtime.IngressSources`). Subclasses now provide only
`Name`; `PauseTimeout` is `virtual` with a 50 ms default; everything
else is fixed by the base. The three concretes drop from ~25 lines to
~12 lines each.
The base's XML `<remarks>` calls out when to use it ("your component
already cooperates with IQuiescenceSignal at its hot path") and when
to implement IIngressSource directly ("the source owns concrete
pause/resume behaviour — e.g. a message-queue consumer that calls
Pause() on its underlying client"), so future contributors don't
mis-extend the base for sources that need real work at pause time.
No behavioural change. 18 graceful-shutdown integration + 39 runtime
unit tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(graceful-shutdown): align IIngressSource name to singular
The three IIngressSource names were inconsistent:
http.trigger (singular)
internal.bookmark-queue-worker (singular)
scheduling.triggers (PLURAL — outlier)
The plural slipped in when addressing Greptile's earlier comment to
avoid `scheduling.cron` (which would imply Cron-only coverage). The
right move was to pick a generic word and stay singular like the rest
of the suite — the suite's mental model is "the X source", one
instance per registry slot, regardless of how many triggers or items
it dispatches internally.
Renamed to `scheduling.trigger`. The `<remarks>` block keeps the
"covers Cron, Timer, StartAt, Delay" explanation and now also
explicitly notes the singular convention so future contributors don't
re-pluralize.
Zero test fallout — the literal "scheduling.triggers" only appeared in
the source file itself. Tests of the other two sources all use
singular forms.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(runtime-admin): rename Force endpoint to ForceDrain
"Force" alone is meaningless out of context — force what? — and it
sits oddly next to the verb-named siblings Pause / Resume / Status.
The matching admin service method is already IWorkflowRuntimeAdminService.
ForceDrainAsync, so ForceDrain is the natural pair.
Renamed:
- src/modules/Elsa.Workflows.Api/Endpoints/RuntimeAdmin/Force/ → ForceDrain/
- namespace ...Endpoints.RuntimeAdmin.Force → ...ForceDrain
- class ForceEndpoint → ForceDrainEndpoint
- class ForceRequest → ForceDrainRequest
- class ForceResponse → ForceDrainResponse
- route POST /admin/workflow-runtime/force → /force-drain
Zero external references — no tests, docs, or OpenAPI clients used the
old symbols or the old route literal, so this is a contained pre-ship
rename. Directory move went through `git mv` so commit history follows
the file.
17/17 graceful-shutdown integration tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(ci): correct formatting in checkout step within greploop.yml
Adjusted indentation of environment variables in the checkout step for improved consistency and readability.
* fix(ci): repair malformed Checkout repository step in greploop.yml
The step accumulated stray env keys, an extra `uses:`, and bash commands
that didn't belong inside it (line 65 onward), causing a YAML parse
error on push. The valid structure has two distinct checkout steps:
- Checkout repository : actions/checkout@v4 with fetch-depth: 0
- Checkout PR branch : env: + run: with SHA validation + git fetch
+ git checkout --detach
The PR-branch step (line 78+) was already correct and unchanged. This
fix restores the first step to its intended single-purpose shape (just
checks out the workflow file's commit so the greploop skill is on disk
before the run-greploop step uses it).
No functional change to runtime behaviour or to the security posture
established in the prior hardening commit (0db4ca23e). The PR-branch
checkout still validates HEAD_SHA / HEAD_REPO_OWNER / HEAD_REPO_NAME
shape before they reach a URL or git command.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(ci): remove literal `${{ }}` from greploop.yml comment
GitHub Actions parses `${{ ... }}` workflow expressions across the entire
YAML file, including inside `run:` script comments. The comment that
explained the env-var hardening pattern contained the literal sequence
`${{ }}` (with a space, intended as an English-language description),
which the expression parser rejected as "An expression was expected"
(line 81 col 14).
Reworded the comment to describe the substitution form in prose without
the literal token sequence. Functional behaviour unchanged.
* refactor(graceful-shutdown): rename burst → execution cycle
The graceful-shutdown work introduced "burst of execution" as a
first-class domain concept. The term arrived without rationale and
isn't standard in the workflow-engine domain. Renamed to
"execution cycle" — reads more naturally as the loop-with-commit unit,
is more idiomatic in workflow vocabulary, pairs cleanly with the
existing WorkflowExecutionContext, and avoids collisions with Elsa's
existing terms (Run, Execution, Dispatch, Invocation, Stimulus, Step).
Renamed types
- IBurstRegistry → IExecutionCycleRegistry
- BurstRegistry → ExecutionCycleRegistry
- BurstHandle → ExecutionCycleHandle
- BurstTrackingMiddleware → ExecutionCycleTrackingMiddleware
- BurstAwareCommitStateHandler → ExecutionCycleAwareCommitStateHandler
Renamed members
- BeginBurst → BeginCycle
- ListActiveBursts → ListActiveCycles
- BurstHandleKey constant + value → ExecutionCycleHandleKey
- ActiveBurstCount (IQuiescenceSignal,
RuntimeAdminStatus, StatusResponse) → ActiveExecutionCycleCount
- WaitForBurstsAsync (private) → WaitForCyclesAsync
- ForceCancelActiveBurstsAsync (priv) → ForceCancelActiveCyclesAsync
- UseBurstTracking → UseExecutionCycleTracking
- DrainOutcomeDto.BurstsForceCancelledCount → ExecutionCyclesForceCancelledCount
- _burstRegistry / burstRegistry → _cycleRegistry / cycleRegistry
Backwards-compatibility preservation (the only persisted JSON key)
- WorkflowInterruptedPayload.BurstDuration property → ExecutionCycleDuration
with [JsonPropertyName("BurstDuration")] so the persisted JSON wire
key stays "BurstDuration" forever. Pre-merge testers' log records
still deserialise correctly. The contract test on
WorkflowInterruptedPayloadContractTests still asserts the wire key
"BurstDuration" appears in the serialised JSON — confirms the
guarantee is enforced.
Other unstructured surfaces
- WorkflowExecutionLogRecord.Message text "Workflow burst was force-
cancelled..." now says "Workflow execution cycle was force-cancelled
..." for new records. Old rows keep their old text — purely cosmetic
free-text field.
- Structured log placeholder {BurstId} in DrainOrchestrator log lines
→ {ExecutionCycleId}.
- Lowercase prose / XML doc comments updated throughout.
Test renames
- BurstRegistryTests → ExecutionCycleRegistryTests
- BurstTrackingMiddlewareTests → ExecutionCycleTrackingMiddlewareTests
- Test method names + DisplayName strings updated.
Spec docs (specs/002-graceful-shutdown/) updated to match the new
vocabulary; the historical task records in tasks.md keep the old names
as-is to preserve the audit trail of what was originally built.
Verification
- dotnet build: clean across net8.0 / net9.0 / net10.0.
- 103/103 Elsa.Workflows.Runtime.UnitTests pass.
- 17/17 GracefulShutdown integration tests pass.
- 4/4 WorkflowInterruptedPayloadContractTests pass — confirms the
"BurstDuration" JSON wire-key preservation is intact.
No changes to migrations or DB column names — confirmed via grep.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(ci): give greploop.yml gh-cli a repo context before checkout
The "Resolve PR head metadata" step runs `gh pr view` before
actions/checkout, so there is no `.git` directory and gh's "current
repo" detection fails with `fatal: not a git repository`. The
prior commits to this file masked the runtime failure because the
workflow itself was YAML-invalid — once it became valid, the
workflow_dispatch trigger surfaced this real-world execution bug.
Set GH_REPO=${{ github.repository }} on both `gh pr view` steps. The
gh CLI honours GH_REPO as an explicit repo override, so it no longer
needs git context. Same fix on the "Checkout PR branch" validation
call which also uses gh pr view before the manual fetch.
The error reported as "Invalid workflow file: ... (Line 81 Col 14)"
on PR #7424 was stale from commit ed580682a (which had the bad
comment with literal `${{ }}`); commit 3a8ad0d08 fixed the YAML, but
because greploop's `if:` condition only matches workflow_dispatch /
issue_comment events, push events on later commits were skipped
without re-running validation, so the GitHub UI kept showing the
old error. A workflow_dispatch run on the current SHA now passes
validation and reaches "Resolve PR head metadata", which is what
this commit fixes.
* fix(graceful-shutdown): wire IngressPauseTimeout option to drain orchestrator
GracefulShutdownOptions.IngressPauseTimeout was documented as "Default
per-ingress-source pause timeout" but DrainOrchestrator.PauseOneSourceAsync
read source.PauseTimeout directly and never consulted the option. The
configured value was silently ignored — operators who set
GracefulShutdownOptions:IngressPauseTimeout = 10s were getting whatever
each source's hardcoded value was (50 ms for the three PassiveIngressSource
subclasses we ship), with no way to tune it globally.
Precedence (per the spec's intent of "overridable at registration and by
configuration"):
1. Per-source positive value wins (source.PauseTimeout > Zero).
2. Otherwise fall back to the configured GracefulShutdownOptions.
IngressPauseTimeout default.
3. Resolved value is capped at the overall drain deadline so a single
misbehaving source cannot exceed the host's shutdown budget.
4. 1 ms safety floor remains so a misconfigured zero default still
produces a non-zero CancelAfter.
Changes:
- DrainOrchestrator.PauseOneSourceAsync — adds the precedence above with
a comment block explaining each step.
- IIngressSource.PauseTimeout — XML doc clarifies the Zero-defers-to-
config semantics.
- GracefulShutdownOptions.IngressPauseTimeout — XML doc says it's the
fallback when the source returns Zero; <remarks> spells out the
precedence and the overall-deadline cap.
- PassiveIngressSource.PauseTimeout — virtual property now returns Zero
(was 50 ms). The three shipped subclasses (HttpTriggerIngressSource,
ScheduledTriggerIngressSource, InternalBookmarkQueueIngressSource)
consequently defer to the configured default — flipping the wire-up
bug from "configured value silently ignored" to "configured value
honoured by default for passive sources". Passive subclasses that
want a specific value can still override.
103/103 runtime unit + 17/17 graceful-shutdown integration tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(graceful-shutdown): rename IInterruptedRecoveryScan → IInterruptedRecoveryScanner
The interface had a single verb-method (`ScanAndRequeueAsync`) and its
XML doc described what it *does* ("Scans the workflow instance store
for instances..."). That's an agent role — a scanner that performs a
scan — but the noun-shaped name `IInterruptedRecoveryScan` read as
"the scan itself", which is misleading because the scan results /
event are not first-class types in the codebase.
Renamed to `IInterruptedRecoveryScanner` / `InterruptedRecoveryScanner`
to match the existing `-er` convention in this codebase (Restarter,
Generator, Resolver, etc.). The method stays `ScanAndRequeueAsync` —
the scanner *performs* a scan-and-requeue.
Also renamed the constructor parameter `scan` → `scanner` in
RecoverInterruptedWorkflowsStartupTask, and the local variable `scan`
→ `scanner` in InterruptedRecoveryIntegrationTests, so the "scanner
does the scan" mental model is consistent throughout.
Surface impact (all internal — no API or persistence touch points):
- 2 source files renamed via git mv (interface + implementation)
- 1 test file renamed (InterruptedRecoveryScanTests → ScannerTests)
- DI registrations in both Features/ and ShellFeatures/ WorkflowRuntimeFeature
- 1 startup-task constructor parameter
- Spec doc references under specs/002-graceful-shutdown/
103/103 runtime unit + 17/17 graceful-shutdown integration tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(graceful-shutdown): extract DrainTriggerExecutor
ElsaShellDrainHandler (CShells IDrainHandler) and
DrainOrchestratorHostedService (.NET IHostedService.StopAsync) inlined
near-identical try/catch/log shapes around IDrainOrchestrator.DrainAsync:
- call DrainAsync(<trigger>, ct)
- branch on outcome: DeadlineExceeded/AbortedByUnhandledException →
Warning, otherwise Information
- catch InvalidOperationException (parallel-drain rejected by the
orchestrator) → log Information and swallow
The two had already drifted: host-stop's success log omitted the
paused/waited durations the shell-handler version included, and the
"skipped" message disagreed on the trigger label ("Host-stop drain
skipped" vs "Shell drain skipped"). Centralised the shape in a small
internal static helper so the two — and any future trigger source —
stay uniform.
Both call sites collapse to a single line. Net diff drops 22 lines from
the two consumers and adds a 25-line helper that they both delegate to.
The unified log copy now consistently includes paused/waited durations
on the success path and uses the caller-supplied contextLabel
("Shell drain", "Graceful drain") in all three messages so operators
can attribute log entries by trigger source.
Files:
- src/modules/Elsa.Workflows.Runtime/Services/DrainTriggerExecutor.cs (new)
- src/modules/Elsa.Workflows.Runtime/Lifecycle/ElsaShellDrainHandler.cs
- src/modules/Elsa.Workflows.Runtime/HostedServices/DrainOrchestratorHostedService.cs
103/103 runtime unit + 17/17 graceful-shutdown integration tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(workflows-runtime): drop redundant DrainOrchestratorHostedService from CShells path
In CShells deployments, host stop already drives drain via CShellsStartupHostedService → IDrainHandler →
ElsaShellDrainHandler, scoped per shell (FR-027). The additional .AddHostedService<DrainOrchestratorHostedService>()
in ShellFeatures/WorkflowRuntimeFeature was firing a second non-force DrainAsync that the orchestrator rejected
with InvalidOperationException — silently swallowed by DrainTriggerExecutor, but logged on every host stop and
semantically muddled (IHostedService is host-level, not per-shell).
Keep the registration on the IModule path (Features/WorkflowRuntimeFeature) where there is no shell platform
and host-stop is the only available drain trigger. Update ElsaShellDrainHandler XML docs to reflect the now-clean
single-trigger model in CShells.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime): always dispose ExecutionCycleHandle in tracking middleware
Previously the success path relied on ExecutionCycleAwareCommitStateHandler to dispose the handle after the
runner's commit completed. If a custom dispatcher or test double exited the pipeline without invoking commit
(by design or by accident), the handle stayed registered, IExecutionCycleRegistry.ActiveCount never reached
zero, and drain spun in WaitForExecutionCyclesAsync until the deadline fired — incorrectly force-cancelling
instances that had already finished cleanly.
Collapse the existing try/catch(rethrow) into try/finally so the middleware itself disposes the handle for
both exception and commit-elided paths. Disposal remains idempotent via the ExecutionCycleHandle._disposed
Interlocked guard, so the normal-path dispose by ExecutionCycleAwareCommitStateHandler is a harmless no-op.
Adds an integration regression test that drives the middleware with a stub Next that returns without invoking
commit and asserts ActiveCount returns to zero.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime): serialize QuiescenceSignal pause-state persistence
Both PauseAsync and ResumeAsync used to release the inner lock before issuing the persistence I/O. A rapid
Pause → Resume sequence could leave the persisted state inconsistent: PauseAsync's slow SaveAsync could land
AFTER ResumeAsync's DeleteAsync, leaving the key present in the store while in-memory state was None. On host
restart, InitializePersistedStateAsync would find the stale key and start the runtime in the paused state
the operator had already cancelled.
Introduce a dedicated SemaphoreSlim that serializes persistence I/O, with each I/O re-reading the live
in-memory state inside the semaphore. N racing Pause/Resume calls now produce N serialized writes, each
reflecting the most recent in-memory transition — so the final persisted state always matches final
in-memory state.
Adds a regression test that gates SaveAsync, races a Resume behind it, and asserts the store is empty after
both complete.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(workflows-runtime): trim verbose comment in ExecutionCycleTrackingMiddleware finally block
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(workflows-runtime): use 'using var' for ExecutionCycleHandle in tracking middleware
Replace the explicit try/finally that only existed to call handle.Dispose() with a `using var` declaration —
identical semantics (compiler-emitted finally with idempotent dispose), more idiomatic. The regression test
HandleReleasedWhenCommitIsElided continues to validate the leak-free property.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime,api): proper 409 conflict shape + shell-scoped pause-persistence key
ForceDrain endpoint: the 409 path returned `new ForceDrainResponse()` whose `Outcome` was null at runtime
despite the `= null!` annotation, so any strongly-typed client deserializing the conflict body and reading
`Outcome.OverallResult` got an NRE. Switch to the existing `ConflictResponse` shape with
`Code = "DrainInProgress"` and the current runtime status. Routed via HttpContext.Response.WriteAsJsonAsync
because Send.ResponseAsync is constrained to the endpoint's TResponse and cannot send a sibling DTO.
QuiescenceSignal persistence key: the DI-registered `IQuiescenceSignal` was constructed with
`shellName = null` (DI doesn't inject `string?` defaults), so every shell shared the key
`elsa.quiescence.pause.default`. In a CShells multi-shell deployment under
PausePersistencePolicy.AcrossReactivations this caused cross-shell contamination — pausing shell A would
re-pause shell B on its next activation. Replace the simple AddSingleton<IQuiescenceSignal,...> registration
in ShellFeatures/WorkflowRuntimeFeature with a factory that injects `CShells.ShellSettings` and forwards
`Settings.Id` as the shell name. The IModule registration is unchanged (no shell platform; null shellName
remains correct there).
Adds a unit regression test that two QuiescenceSignal instances with different shellNames write to disjoint
persistence keys and never to the legacy "default" key.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(quiescence): use TryGetValue for ContainsKey+indexer assertions
Combines existence check and value retrieval into a single dictionary lookup, addressing the code-quality
bot's repeated suggestion. No behavior change — both PauseWritesKey and PersistenceKeyIncludesShellName
still assert the same keys exist with the same content.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Update specs/002-graceful-shutdown/contracts/admin-endpoints.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix(workflows-runtime): decouple QuiescenceSignal persistence from caller cancellation
PersistAsync used to forward the caller's CancellationToken to both _persistenceMutex.WaitAsync and the
store I/O. If an HTTP request was cancelled between the in-memory transition (already committed under
_sync) and the persistence call, the I/O was silently skipped — leaving AdministrativePause set in memory
with no persisted record. The idempotent fast-path on subsequent PauseAsync calls (transitioned == false)
meant no retry would happen, so on host restart InitializePersistedStateAsync would find no key and the
runtime would come back unpaused, defeating PausePersistencePolicy.AcrossReactivations.
Drop the parameter from PersistAsync entirely; use CancellationToken.None for both the semaphore wait and
the store I/O. The in-memory transition is already committed by the time PersistAsync runs, so persistence
must complete to keep the store consistent with memory. The public PauseAsync/ResumeAsync methods still
accept a CancellationToken (interface contract) — it just no longer reaches the persistence layer.
Adds a regression test that calls PauseAsync with a pre-cancelled token and asserts both in-memory pause
and the persisted key land correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime,api,docs): apply Copilot review feedback batch
Code:
- DrainOrchestrator.TryForceStopAsync now bounds force-stop with the *remaining* drain budget
(deadlineAt - now), not the full overall TimeSpan. A per-source pause that already burned the
shutdown window can no longer get another full deadline's worth of force-stop runway.
- DrainOrchestrator catch filter narrowed: drop `ex is not InvalidOperationException` exclusion.
The "drain already in progress / completed" IOEs are thrown outside the protocol's try block,
so they bubble out without entering this handler. Any IOE that lands here is incidental
(e.g., from a store inside the drain) and should now be captured into the outcome rather
than escaping the whole drain.
- ResumeEndpoint 409 path now returns the discriminated ConflictResponse shape (matching
ForceDrain) instead of a plain StatusResponse. Routed via HttpContext.Response.WriteAsJsonAsync
because Send.ResponseAsync is constrained to TResponse.
- Conflict codes aligned to kebab-case across both endpoints to match the contract spec
(`runtime-draining` and `drain-in-progress`).
Spelling sweep — American English per constitution v1.0.1 III:
- DrainOrchestrator.cs: "serialised" → "serialized"
- WorkflowInterruptedPayload.cs: "serialised" / "deserialise" → "serialized" / "deserialize"
- PassiveIngressSource.cs: "behaviour" → "behavior"
- DeadlineBreachEndToEndTests.cs: "serialisable" → "serializable"
- specs/002-graceful-shutdown/quickstart.md: "behaviour" → "behavior"
- specs/002-graceful-shutdown/checklists/requirements.md: "behaviour" → "behavior"
Doc/contract alignment:
- quickstart.md: force route corrected from /force to /force-drain.
- quiescence-signal.md: removed StateChanged event from contract (interface doesn't define it);
corrected persistence section to describe InitializePersistedStateAsync via shell initializer
/ startup task rather than constructor read; added the per-shell key discriminator.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime): correct DI lifetimes for ExecutionCycleTrackingMiddleware and WorkflowRuntimeAdminService
Two strict-DI-validation failures surfaced in tests using BuildServiceProvider with validate-on-build:
1. ExecutionCycleTrackingMiddleware was registered as AddSingleton<>, but its constructor takes
WorkflowMiddlewareDelegate next — supplied by the workflow execution pipeline builder via
UseMiddleware<>(), not from DI. The registration was both unused (no consumer resolves it through
the container) and broken (DI fails to construct it because next is unregistered). Removing both
registrations.
2. IWorkflowRuntimeAdminService was registered as AddSingleton<> but depends on the scoped
INotificationSender (mediator) — captive-dependency violation. All consumers (Pause/Resume/
Status/ForceDrain endpoints) are FastEndpoints, which are scoped per request, so AddScoped is
the correct alignment. The other deps (IQuiescenceSignal / IIngressSourceRegistry /
IDrainOrchestrator / ISystemClock) are singletons and resolve fine from a scoped consumer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(workflows-runtime): restore commit-handler-only success disposal + true Cancel idempotency
Two issues raised by Copilot's latest review on commit 32a9c0519:
1. ExecutionCycleTrackingMiddleware was disposing the handle at the end of InvokeAsync (via `using var`),
but WorkflowRunner runs commit AFTER the pipeline returns (WorkflowRunner.cs:235). That meant the handle
was disposed BEFORE the runner's terminal commit, and the drain orchestrator's
`await handle.Disposed` would unblock too early — reintroducing the runner-clobber race the original
design protected against (see ExecutionCycleAwareCommitStateHandler XML doc).
Revert to the original shape: only dispose on exception path. ExecutionCycleAwareCommitStateHandler
remains the SOLE success-path disposer, running in its finally block AFTER the inner commit lands.
The earlier "leak when commit is elided" concern was a non-issue in production (the standard runner
always commits); the buggy `HandleReleasedWhenCommitIsElided` test that specified the wrong contract
is removed. The existing `ActiveCountReturnsToZero` test (which uses the real runner end-to-end)
already verifies success-path disposal.
2. ExecutionCycleHandle.Cancel() was documented as idempotent but only short-circuited via the
_disposed flag. Repeated Cancel() calls before Dispose could trigger the cancel callback multiple
times — easy to accidentally fire non-idempotent cancellation side effects more than once. Add an
Interlocked _cancelled guard so callback + CTS cancellation run at most once. Existing test that
documented the leaky behavior is updated to assert the now-truly-idempotent contract.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Update logging levels and remove unused features in appsettings files
* refactor(workflows-runtime): improve graceful shutdown options handling and cleanup solution
Refactor the handling of `GracefulShutdownOptions` to ensure options are applied correctly without directly invoking the delegate. Update DI registrations to use appropriate lifetimes and remove redundant wrapper services. Additionally, clean up the solution by removing unused projects and documentation folders.
* feat(identity, workflows-runtime): add validation for identity and graceful shutdown options
Introduce validation capabilities for `IdentityTokenOptions` and `GracefulShutdownOptions`. Implement extension methods for option validation, enhance service registration, and add unit tests to ensure configurations are validated at startup. Update solution to include new unit test projects.
* update(docs): clarify shutdown log message expectations and levels in quickstart.md
Optimize explanation of expected log message sequence during graceful shutdown and specify logging levels.
* docs: amend constitution to v1.1.0 (SRP, DRY, KISS, conciseness under Principle VII)
* refactor(multitenancy): rename and restructure TenantTaskManager to TenantTaskLifecycleCoordinator
Rename `TenantTaskManager` to `TenantTaskLifecycleCoordinator` and relocate to a new directory structure, enhancing code organization and test consistency. Retain functional behaviors with no logic alterations. Update unit tests to reflect the naming changes, ensuring consistency with the refactored code structure.
* Update logging levels and dependencies
- Set default logging level to Debug in appsettings.Development.json
- Add missing using directives for Elsa workflows management and runtime features
- Update CShells package versions to 0.0.18-preview.104
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Isolate background workflow dispatches from caller's cancellation token
When dispatching multiple child workflows, early child completions cancel the parent activity's token while dispatches are still in progress. This creates a race condition where remaining dispatches fail with OperationCanceledException.
* Make BackgroundWorkflowDispatcher & BackgroundStimulusDispatcher caller Cts-independent
* Add idempotency tests for trigger indexing and fix serialization mismatch in WorkflowTriggerEqualityComparer
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Refactor `WorkflowTriggerEqualityComparerTests`: streamline trigger creation with helper methods and extract serializer options to static fields for clarity.
* Enhance `WorkflowTriggerEqualityComparer`: add converters for enum, TimeSpan, and polymorphic objects in serializer options.
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Adds activity execution call stack support
Implements a call stack mechanism to track the execution chain, enabling visibility into the invocation hierarchy.
Introduces new fields to scheduling models and runtime contexts to store call stack information.
Includes EF Core migrations for various database providers to support new columns in `ActivityExecutionRecords`.
Provides an API to query and reconstruct the call stack for a given activity execution.
* Refactor: Replace `PagedCallStackResult` with `Page<T>` for execution chain pagination
* Remove ambient scheduling scope logic and related methods
Simplifies scheduling logic by removing ambient scope mechanisms, refactoring scheduling context handling, and updating affected classes accordingly.
* Add `GetCallStackAsync` to `IActivityExecutionsApi` for querying activity execution call stack
* Add new properties to `ActivityExecutionRecord` for scheduling and execution tracking
Introduce fields for aggregated fault count, scheduling context, workflow instance details, and call stack depth to enhance execution monitoring and debugging capabilities.
* Add call stack visualization for activity executions
Introduced components and models to display a call stack for activity executions in the Workflow Instance Viewer. This includes UI elements for call stack rendering, error handling, and data integration with activity execution records.
* Remove obsolete ambient scheduling properties from WorkflowExecutionContext
* Fix infinite loop issues in activity execution chain traversal
Added cycle detection using a `HashSet` to prevent infinite loops when traversing activity execution chains in multiple storage implementations. Updated unit tests to validate correct handling of circular references and chain traversal.
* Refactor activity execution chain retrieval logic
Centralized the `GetExecutionChainAsync` method into an extension class to streamline and unify its implementation across stores. Removed redundant implementations from individual stores and updated interfaces to utilize the new extension method. This reduces code duplication and simplifies future maintenance.
* Add CallStackDepth property to activity contexts
Integrated the `CallStackDepth` property into `ActivityExecutionContext`, `ActivityExecutionContextState`, and related classes to track and manage the call stack depth of activity executions. Removed obsolete depth calculation logic to streamline the process.
* Add unit tests for call stack depth calculations and persistence
- Add `WorkflowExecutionContextTests` to verify correct calculation of call stack depth during activity execution.
- Add `WorkflowStateExtractorTests` to ensure call stack depth is preserved during state extraction and application.
* Update src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions/GetCallStack/Endpoint.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions/GetCallStack/Endpoint.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Enhance activity execution handling with ID filter and task completion logic
- Implement `ActivityExecutionRecordFilter` for precise query matching by ID.
- Add await logic for task completion in command handler middleware.
* Add missing indexes for call stack columns in V3_7 migrations (#7250)
* Initial plan
* Add missing indexes for call stack columns in all provider migrations
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Optimize migrations by creating columns with correct indexable types
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add unit tests for ActivityExecutionStoreExtensions
- Introduce tests for `GetExecutionChainAsync` covering scenarios of empty results, single records, multi-level chain traversal, workflow boundary constraints, pagination, and circular references.
* Refactor tests for `ActivityExecutionStoreExtensions`
- Replace mock setup with `CreateStore` helper for clean and clear test arrangements.
- Remove unused imports and clean up test setup for improved readability and maintenance.
* Remove unused imports from ActivityExecutionLogStore in Elsa.Persistence.EFCore module.
* Removes obsolete planning document
Removes the activity execution call stack planning document
as the feature has been implemented.
* Remove DefaultActivityExecutionMapperTests
- Deleted `DefaultActivityExecutionMapperTests.cs` as the test class is no longer in use and redundant.
* Address review feedback: Fix corrupted test, Oracle migrations, and call stack depth calculation (#7272)
* Initial plan
* Fix corrupted DefaultActivityExecutionMapperTests.cs test file
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Fix Oracle migration snapshot to use NCLOB for large text fields
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Optimize GetExecutionChainAsync to avoid loading all workflow instance records
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Fix CallStackDepth calculation to support cross-workflow invocations
- Add SchedulingCallStackDepth to ActivityInvocationOptions
- Update WorkflowExecutionContext to use provided depth when scheduling context not found
- Remove problematic test that reveals pre-existing bug with duplicate contexts
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Improve documentation for CallStackDepth calculation
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add WorkflowStateExtractor to ActivityTestFixture services
* Refactor `DefaultActivityExecutionMapperTests` with `ActivityTestFixture` and add project reference for shared testing utilities.
* Propagate SchedulingCallStackDepth through cross-workflow invocation chain (#7273)
* Initial plan
* Add SchedulingCallStackDepth propagation through cross-workflow invocation chain
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add unit tests for CallStackDepth propagation across workflow boundaries
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Initial plan (#7274)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* Reduce NVARCHAR2 column sizes in Oracle migrations to optimize storage and improve performance.
* Change column types to NCLOB for large text fields in Oracle migrations to enhance data storage capacity.
* Update GitHub Actions to use .NET 10.x and refactor setup classes for consistency
* Improve test project detection in GitHub Actions by handling non-csproj files and updating project sorting mechanism.
* Enhance GitHub Actions to display .NET environment info and enforce .NET 10 toolchain for test execution.
* Update GitHub Actions to use .NET SDK 10.0.1xx and enforce its usage for builds and tests.
* Refine GitHub Actions workflow by narrowing test project search to the `test/unit` directory and removing unnecessary script checks.
* Remove redundant build step from GitHub Actions workflow.
* Enhance GitHub Actions workflow by adding multiple test directories and handling ignored failed sources in .NET restore.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Enhance `DefaultRegistriesPopulator`: add notification support for workflow definition reloads.
* Add unit tests for `DefaultRegistriesPopulator` to verify workflow definition reload notifications.
* Update multitenancy logic and improve `Result` handling:
- Introduce `TenantsOptions` with `IsEnabled` flag to conditionally apply tenant-specific logic.
- Refactor `Result` class to support strongly-typed operations and async handlers.
- Implement tenant filters respecting multitenancy enablement.
- Enhance error logging for workflow definition addition, upgrading error handling.
- Refactor tests and storage drivers to use `IsSuccess` from `Result`.
* Update src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowDefinitionStorePopulator.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add exception handling when accessing `Value` on failed results; introduce `ValueOrDefault` property for better null support.
* Add `ThrowIfFailure` method to handle exceptions in `Result` model and use it in `DefaultWorkflowRegistry` to ensure operation success.
* Normalize tenant ID handling by using `NormalizeTenantId()` in `DefaultWorkflowDefinitionStorePopulator`.
* Normalize tenant ID usage in unit tests by returning `tenantId.NormalizeTenantId()` in `DefaultWorkflowDefinitionStorePopulatorTests`.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Enable multitenancy support and normalize tenant ID handling.
- Activate multitenancy in `Program.cs`.
- Introduce `NormalizeTenantId` method for consistent tenant ID usage.
- Update tenant-related classes and features to support normalization logic.
* Add ADR for adopting empty string as the default tenant ID
- Standardized the tenant ID for the default tenant to use an empty string (`""`) instead of `null`.
- Documented the rationale and migration considerations in ADR 0007.
- Updated ADR table of contents and graph for new entry.
* Apply suggestion from @sfmskywalker
* Update doc/adr/graph.dot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Normalize spacing and improve readability in `Program.cs`. Fix multitenancy condition formatting.
* Fix ADR numbering and update TOC
* Add ADRs for flowchart execution model, tenant deletion event, merge modes, and default tenant ID
- Introduced ADR 0005: Token-centric flowchart execution model for improved loop and join handling.
- Added ADR 0006: Tenant Deleted event for distinct handling of tenant removal.
- Documented ADR 0007: Explicit merge modes for flowchart joins, improving reliability and configurability.
- Included ADR 0008: Standardization of empty string as the default tenant ID for consistency and clarity.
* Add unit tests for tenant ID normalization and multitenancy pipeline invoker
- Added comprehensive unit tests for tenant ID normalization to ensure consistent handling of null, empty, and valid IDs.
- Introduced tests for the multitenancy pipeline invoker covering various tenant resolution scenarios.
- Updated solution to include new unit testing projects for `Elsa.Tenants` and `Elsa.Common`.
* Update unit tests for `ActivityConstructionResult`
- Refactor test parameterization to verify `HasExceptions` property more explicitly.
- Simplify exception creation logic in helper methods.
- Improve test assertions by combining act and assert phases where applicable.
* Enable configuration-based multitenancy with tenant-specific settings
- Introduced a configuration-based tenant provider to streamline tenant initialization and customization.
- Added tenant ID handling filters to ensure tenant ID is applied and filtered automatically.
- Deprecated the `CommonPersistenceFeature` in favor of modular persistence feature extension.
* Update database indexes to include `TenantId` for multitenancy support
- Added `TenantId` to unique constraints on `Triggers` table across all EFCore providers.
- Adjusted index names to reflect the updated constraints.
- Updated trigger configuration to ensure uniqueness includes `TenantId`.
* Add tenant filtering to `DefaultWorkflowDefinitionStorePopulator`
- Introduced `ITenantAccessor` to support tenant-specific filtering of workflow definitions.
- Updated logic to skip workflows not matching the current tenant.
* Update doc/adr/toc.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove `CommonPersistenceFeature` as it has been deprecated
* Add tenant-specific filtering to workflow import logic in `DefaultWorkflowDefinitionStorePopulator`
* Replace hardcoded tenant ID with `Tenant.DefaultTenantId` in integration tests
* Update database indexes and migration logic to support `TenantId` for multitenancy
- Added `TenantId` to unique constraints on the `Triggers` table and updated index names.
- Included logic to drop outdated indexes without `TenantId` during migration.
- Adjusted tests to account for `TenantId` in workflow identity and indexing scenarios.
* Remove `TenantId` from workflow identity construction in concurrent trigger indexing tests
* Introduce `SelectiveMockLockProvider` for precise lock mocking in tests
- Added `SelectiveMockLockProvider` to allow targeted lock mocking without affecting unrelated background operations.
- Updated test services to use `SelectiveMockLockProvider` in place of `TestDistributedLockProvider`.
- Refactored `DistributedLockResilienceTests` to support selective mocking for deterministic and reliable assertions.
* Update Elsa.sln
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Normalize tenant ID handling in `DefaultWorkflowDefinitionStorePopulator` for consistent filtering
* Refactor `TenantResolverResult` to support explicit resolved/unresolved state handling
- Updated `TenantResolverResult` to include an explicit `_isResolved` property.
- Adjusted `ResolveTenantId()` and `IsResolved` logic for improved clarity and robustness.
- Simplified tenant resolution invocation in `TenantResolverBase`.
- Removed redundant normalization in `DefaultTenantResolverPipelineInvoker`.
* Normalize tenant ID handling in `DefaultWorkflowDefinitionStorePopulator` and `ClrWorkflowsProvider`.
* Refactor `DefaultWorkflowDefinitionStorePopulatorTests`: streamline object initializations and add tenant-specific test coverage for `PopulateStoreAsync`.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add tenant headers support to BackgroundWorkflowCancellationDispatcher (#7040)
* Add tenant headers support to BackgroundWorkflowCancellationDispatcher
* Fix 'CreateHeaders' call
* Fix memory leak: Dispose IronCompressResult in Zstd codec (#7193)
* Initial plan
* Fix memory leak: Dispose IronCompressResult in Zstd codec and add tests
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Refactor tests to be more DRY using Theory and InlineData
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Introduce `IMaterializerRegistry` to manage workflow materializers and ensure availability checks.
* Extend `IWorkflowDefinitionService` and `CachingWorkflowDefinitionService` with workflow graph lookup methods (`TryFindWorkflowGraphAsync`). Refactor caching and materialization logic for consistency.
* Refactor caching interface and implementation: add `FindOrCreateAsync`, update `GetOrCreateAsync` to ensure non-null results, and improve exception handling.
* Refactor `GetWorkflowGraphAsync` to use `TryFindWorkflowGraphAsync` and improve exception handling for missing workflow definitions and materializers.
* Refactor caching logic to replace `GetOrCreateAsync` with `FindOrCreateAsync` for improved clarity and consistency.
* Update workflow model, add event, and mark exception obsolete
Updated `TimestampFilter.Column` to use a `null!` default value for clarity. Added `Event1` in the `hello-world.elsa` workflow and removed an unused folder entry from the project. Marked `WorkflowGraphNotFoundException` as obsolete with guidance to use `WorkflowDefinitionNotFoundException` instead.
* Add new workflow files and exception classes for Elsa
Introduced a workflow definition file "eventing.json" and new exception classes (`WorkflowDefinitionNotFoundException` and `WorkflowMaterializerNotFoundException`) to enhance handling of workflow-related errors. Also added a `WorkflowGraphFindResult` model for better workflow graph management. These changes improve the structure and functionality of the workflow system.
* Add unit tests for `CachingWorkflowDefinitionService` and related helpers
Introduce comprehensive unit tests to validate caching logic, workflow graph/materialization behavior, and cache key generation in `CachingWorkflowDefinitionService`. Add `WorkflowDefinitionServiceTests` and helper methods for streamlined test setup.
* Enable `UseElsaScriptBlobStorage` in workflow server configuration
* Refactor `BackgroundWorkflowCancellationDispatcher` to simplify object initialization and clean up XML documentation comments
* Address PR #7195 review feedback: optimize caching, improve exceptions, add test coverage (#7196)
* Initial plan
* Apply PR review feedback: Fix exceptions, optimize caching, improve error handling
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add unit tests for MaterializerRegistry and LocalWorkflowClient exception handling
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Add unit tests for BackgroundWorkflowCancellationDispatcher tenant headers
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
* Refactor `WorkflowMaterializerNotFoundException` to improve structure and usability, update related references, and simplify object initialization in test cases.
* Update `WorkflowDefinitionServiceTests` to use `WorkflowMaterializerNotFoundException` in place of `InvalidOperationException` for materializer not found scenario
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* Potential fix for pull request finding 'Inefficient use of ContainsKey'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Refactor tests and services: simplify object initialization, use target-typed `new()` syntax, and replace `CancellationToken` with `CancellationToken.None` where applicable.
* Refactor tests in `BackgroundWorkflowCancellationDispatcherTests`: improve tenant initialization and optimize header checks by replacing `TryGetValue` with `ContainsKey`.
---------
Co-authored-by: Sverre Winkelmans <69142682+Sverre-W@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Add code coverage configuration and adjust test projects
- Introduced `Include` and `Threshold` properties across test project files for improved code coverage tracking.
- Added `coverlet.collector` as a dependency for coverage data collection.
- Removed unused `global using` directives and redundant imports for cleaner test codebases.
* Update GitHub Actions workflows for pull request triggers
- Adjusted `pr.yml` to include `patch/*` and `develop/*` branches.
- Removed redundant pull request triggers in `packages.yml` for cleaner configuration.
* Expand pull request triggers in GitHub Actions
- Renamed `PR` workflow to `pr` for consistency.
- Included `patch/*` and `develop/*` branches in `pr.yml` and `Build.CI.GitHubActions.cs`.
* Remove pack target from pull request workflows
- Updated `pr.yml` to exclude the pack step.
- Adjusted `Build.CI.GitHubActions.cs` to reflect the removal of the pack target.
* Remove `Elsa.Workflows.Api` from integration test project references
- Updated `Elsa.Workflows.IntegrationTests.csproj` to exclude `Elsa.Workflows.Api` from the `Include` list and project references for cleanup and simplification.
Eliminated the `Elsa.Labels`, `Elsa.Environments`, and `Elsa.OpenTelemetry` modules along with their handlers, contracts, models, and related functionality. This cleanup improves maintainability and aligns the codebase with recent architectural changes.
Consolidate imports by replacing Elsa.Common.Contracts with Elsa.Common and Elsa.Common.Multitenancy. This update streamlines import statements across various modules, improving code readability and maintainability.
* Update package versions and add PrivateAssets attributes
Updated multiple package versions to the latest releases and added the `PrivateAssets="All"` attribute to several dependencies to improve project isolation. This ensures that the specified packages will not be propagated as transitive dependencies.
* Fix incorrect serializer and generator references.
Replaced `_payloadSerializer` and `_identityGenerator` with `payloadSerializer` and `identityGenerator` respectively. This resolves potential null reference issues and ensures the correct instances are used during workflow and definition processing.
* Refactor background activity scheduling logic
Moved the state commit outside of the deferred task to ensure workflow state is saved before scheduling activities. This change ensures the workflow instance is updated promptly, preventing potential concurrency issues.
* Add bookmark queue management system
Introduced a comprehensive bookmark queue system to manage and process bookmarks efficiently. This includes entities, stores, filters, processors, and workers for both in-memory and distributed environments. Additionally, added notifications to signal bookmark queue workers and updated related contracts.
* Add state commit handler with various implementations
Introduced ICommitStateHandler for committing workflow state. Provided NoopCommitStateHandler and StoreCommitStateHandler implementations. Updated namespaces and dependencies across the project to incorporate these changes.
* Fix order in CommitAsync method for proper task execution
Reorder `ExecuteDeferredTasksAsync` after `SaveAsync` in `CommitAsync` method to ensure that deferred tasks execute correctly after the state is saved, addressing potential issues with task execution dependencies.
* Remove unused and deprecated middleware and annotations
Deleted unused classes `ExecuteDeferredActivityTasks` and `ScheduleBackgroundActivitiesMiddleware`. Removed unnecessary summary tags and unused usings across multiple files to clean up the codebase.
* Remove unnecessary initial migration files
Deleted initial migration files for alterations, management, and identity contexts. These files are no longer needed and their removal helps keep the repository clean and maintainable.
* Add delay in TriggerBookmarkQueueWorker loop
Introduced a 10-second delay within the while loop of TriggerBookmarkQueueWorker. This change aims to alleviate potential tight loop issues, ensuring better performance and resource management.
* Enable all database providers in migration script
Uncomment the providers array and add previously commented database providers (SqlServer, Sqlite, PostgreSql, Oracle). This ensures compatibility with multiple database systems during the migration process.
* Remove unused Microsoft.Extensions.DependencyInjection import
The import statement for `Microsoft.Extensions.DependencyInjection` was not being utilized and has been removed. This cleanup helps in maintaining cleaner and more readable code without unnecessary imports.
* Add Dapper persistence support for bookmark queue
Introduced a new Dapper-based bookmark queue store and related classes for handling bookmark queue items. Various migrations were added to support the new `BookmarkQueueItems` table with tenant-specific columns. Refactored existing EF Core and in-memory bookmark queue item stores to use a unified interface.
* Add MongoBookmarkQueueStore implementation
Added a MongoDB-based BookmarkQueueStore to handle CRUD operations for bookmark queue items. Updated the workflow runtime persistence feature to include and utilize this new store for managing bookmark queue items.
* Add migration helper for altering columns and update keys
Introduced MigrationHelper to simplify altering DateTime and Boolean columns. Updated keys in KeyValueStore and KeyValueFilter classes to use 'Id' instead of 'Key'. Revised migration scripts to utilize the new helper methods for modifying column types.
* Prevent BookmarkQueueWorker.Stop from cancelling when not running
Previously, the Stop method would always cancel the token source regardless of the worker's state. By checking if the worker is running before cancelling, we avoid unnecessary operations and potential errors related to an already cancelled token source.
* Update database schema and bookmark handling logic
Refactored various database migration scripts to allow nullable `WorkflowInstanceId` fields and added new fields such as `ActivityInstanceId` and `CorrelationId`. Enhanced bookmark queue and bound workflow handling logic to support these new fields, ensuring precise and efficient workflow execution and queuing.
* Refactor BookmarkHash to StimulusHash and introduce ActivityTypeName
Renamed BookmarkHash to StimulusHash across multiple components and added ActivityTypeName to enhance traceability. Updated indices, filters, and entities for this change, ensuring consistent naming and improved functionality.
* Remove unnecessary timeouts in AzureServiceBusTests.
Eliminated redundant timeout parameters in _signalManager.WaitAsync calls to streamline test execution and reduce potential waiting time. This change ensures more efficient and accurate testing synchronization.
* Rename and refactor BookmarkQueueWorkerSignaler
Renamed IBookmarkQueueWorkerSignaler to IBookmarkQueueSignaler across the project for clarity. Updated related classes and methods to reflect this change. Added bookmark queue signaling to ensure new items are processed, and renamed BookmarkQueueStore to EFBookmarkQueueStore for consistency.
* Refactor EF Core stores and add migration field
Refactored EF Core store classes to simplify field usage and constructors. Added "CorrelationId" field and created corresponding index in SQLite and PostgreSQL migration files to support new functionality.
* Update workflow context ID and optimize Task handling
Added `ParentInstanceId` to `BulkDispatchWorkflowsStimulus` for context propagation. Also, reset `TaskCompletionSource` in `BookmarkQueueSignaler` to reduce memory usage and ensure proper task lifecycle management.
* Update async method signature and fix variable usage
Modified `AddAsync` to include the `OnSaveAsync` parameter. Corrected the variable used for `parentInstanceId` and utilized `ActivityTypeNameHelper` for generating type names.
* Reset migrations to 3.2
* Generate 3.3 migrations
* Feature/multitenancy (#4739)
* feat(multi-tenancy): add tenantId to entities and additionnal configuration to dbContext
* feat(multi-tenancy): split code in a Elsa.Tenants project, add some configuration to the DbContext for strategies
* feat(multi-tenancy): fix queryfilter to split data between tenants
* feat(multi-tenancy): add tenantId to entity, generate migrations and create a sample
* feat(multi-tenancy): add strategies to always have tenantId when saving
* feat(multi-tenancy): add external user provider support for tenant
* feat(multi-tenancy): fix dbcontext filter on tenantid
* feat(multi-tenancy): manage background execution of workflows
* feat(multi-tenancy): change tenant accessor and middlewares
* feat(multi-tenancy): fix tenantId missing in some cases
* feat(multitenancy): fix efcore store for multitenant
* feat(multi-tenancy): fix some comment of the pullrequest (naming, use Sqlite for example, etc.) and split efcore from tenant project
* Move Elsa.Samples.AspNet.Tenants and Elsa.Samples.AspNet.Tenants.External projects
* Refactor tenant middleware and enhance code documentation
Multiple files including middleware and entity classes related to tenants have been refactored for more straightforward implementation. Unnecessary code has been removed and constructor parameters have been directly utilized, increasing the code's readability and efficiency. Moreover, documentation for classes and interfaces has been enhanced providing better understanding of their role and function.
* Refactor tenant-related classes and move to Elsa.Tenants module
Moved ITenantAccessor and related classes from Elsa.Common to Elsa.Tenants module. Adjusted necessary references in files where these classes were used. Made corresponding changes to the various services where these classes were instantiated or used. Updated project references accordingly.
* Refactor DbContext strategies and streamline code
The DbContextStrategy interfaces were moved from Abstractions to Contracts for better semantics. Async methods in ElsaDbContextBase and IBeforeSavingDbContextStrategy were made synchronous to simplify usage. This included the alteration of methods in related classes to reflect the changes. Unnecessarily complex lines of code were also rewritten for better readability and standardization.
* Refactor multi-tenancy feature and rename workflow provider interfaces
The update refers to multi-tenancy and workflow providers. For the multi-tenancy feature, the 'ConfigurationTenantProvider' was refactored to 'ConfigurationTenantsProvider' and used in 'TenantsFeature'. It was consolidated into one function 'UseConfigurationBasedTenantsProvider'. Middleware to handle this scenario was also adjusted. Regarding workflow providers, the 'IWorkflowProvider' has been renamed to 'IWorkflowsProvider' and corresponding changes made in classes consuming this interface. Name adjustments also affected functions and configuration options. Various non-related code cleanups and removals have also been made.
* Replace initial migration files for various databases
The replacement ensures that TenantId columns will be added when users migrate to 3.1.
* Remove old migration files
This commit removes multiple old database migration files from the source. These files are related to the Elsa.EntityFrameworkCore module and they cover database alterations and management. They are no longer needed due to changes in the application's data structure and updates in the database schema.
* Update database model and migration snapshot
This commit updates the database model and migration snapshot in Elsa.EntityFrameworkCore.MySql. The "ProductVersion" annotation has been updated, and the "Status" property's type has been changed from int to string. Furthermore, a "TenantId" property has been added which is indexed for faster lookups.
* Add TenantId to app settings
This update modifies the appsettings.json file to include a "TenantId" for Administrators, Users, and Applications. Moreover, the key names are updated to follow the PascalCase convention consistently.
* Refactored workflow command handler and added indexes to entities
The DispatchWorkflowRequestHandler has been replaced with DispatchWorkflowCommandHandler in the WorkflowRuntimeFeature. Also removed the DispatchTenantWorkflowRequestHandler from the TenantsFeature. In the entity framework, added indexes to SerializedKeyValuePair's Key and TenantId in the Configurations. The SerializedKeyValuePair class now inherits from Entity.
* Reset migrations to Initial
* "Added TenantId column and altered status column type in AlterationPlans and AlterationJobs tables"
This commit introduces new TenantId columns to the AlterationPlans and AlterationJobs tables across different DB contexts (MySql, SqlServer, Sqlite, PostgreSql). The type of the Status column has also been changed from int to string in both tables. Indexes for the new TenantId column are also created as part of this change.
* Update authentication settings and improve code structure
Several modifications have been made to improve our code and update our authentication setup. Made changes to disable Dapper and utilize JWT Bearer for authentication in the Elsa.Server.Web program settings. Additionally, we've updated a method on IdentityTokenOptions to be internal and adjusted token option assignments in ModuleExtensions. Syntax improvements were also made in ApplicationProviderExtensions for better consistency with best practices.
* Remove V3_1 migration from different databases
The V3_1 migration from MySql, SqlServer, Sqlite, and PostgreSQL databases has been removed. This includes alterations such as the addition of the "TenantId" column and changes in the "Status" column type within Elsa's schema.
* Remove old and add new tenant handling components
Removed files related to the old way of handling tenants in the application and added new ones for improved management. This change introduces a tenant resolution strategy pipeline, allowing different strategies to be used in sequence to resolve the current tenant. Various schemes have been implemented, including resolving tenants based on route prefixes, the currently authenticated user, and the user's claims. The update also enhances the way entities are handled when working with SQLite and Oracle databases.
* Added SQLite setup to PersistenceFeatureBase
The code now adds a line to include SetupForSqlite in PersistenceFeatureBase's services list. The SetupForOracle class was removed from the SetupForSqlite file - it is possibly now dedicated to SQLite setup only.
* Add CommonPersistenceFeature, refactor related classes
Implemented a new class, CommonPersistenceFeature, which handles aspects previously managed in PersistenceFeatureBase. ServiceScope registrations were removed from PersistenceFeatureBase and added to the new CommonPersistenceFeature. In addition, the tenant filter in SetTenantIdFilter has been simplified for more direct accessibility. Changes were also made in WorkflowManagementPersistenceFeature to accommodate these implementations.
* Refactor multi-tenancy configuration and resolution
Updated the code to use "MultiTenancy" section instead of "Tenants" section in all configuration files. Also, refactored the Store class to use IServiceProvider instead of IDbContextFactory and added tenant resolution logic. Renamed classes and variables accordingly to better represent multi-tenancy.
* Add Tenant Dymanic Filter options for Workflow Definition
Tenant Dymanic Filter provides the ability to include or exclude tenant matching in the filter. The corresponding queries and method signatures were modified to account for this new feature. Added `HttpContextTenantExtensions` and `HttpContextTenantResolver` classes to enable tenant-based filtering of HTTP context.
---------
Co-authored-by: Jean-Baptiste Dalle <jean-baptiste.dalle@stereograph.fr>
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* Remove authenticating services and activities
The AuthenticatingMediator, GetPlacedCallHubSpotId activity, and IAuthenticatingMediator interface have been removed. Middleware for authorization context workflow execution and tenant providers have been added to enhance multi-tenancy support.
* Add tenant resolution strategies and update namespaces
Introduce tenant resolution strategies in the Identity module and refactor namespaces across modules to align with the new multi-tenancy structure. This includes moving various tenant-related classes from the Tenants module to Common and Identity, adjusting references, and consolidating tenant constants and options.
* Remove IdentityOptions and refactor token claims
Deleted `IdentityOptions` and moved `TenantIdClaimsType` to `IdentityTokenOptions`. Renamed `ClaimConstants` to `CustomClaimTypes` and updated references across multiple services and samples accordingly. Adjusted `ClaimsTenantResolver` to use `IdentityTokenOptions` and removed deprecated method `Deconstruct` from `IdentityTokenOptions`.
* Update SystemClock registration to singleton
Changed the dependency injection scope for ISystemClock from scoped to singleton to ensure a single instance is used application-wide. This ensures consistent time references across different components and enhances performance by reducing the number of instances created.
* Change service registrations to singleton
The `IQueueProvider`, `ITopicProvider`, and `ISubscriptionProvider` are now registered as singletons to ensure single instances throughout the application. Additionally, dependency resolution for `ITriggerStore` and `IBookmarkStore` is moved to a scoped lifetime within `StartWorkers` to maintain correct scope per operation.
* Refactor tenant ID claim retrieval
Simplify the extraction of tenant ID from claims by removing the fallback to a default type, given that it is non-nullable.
* Remove unused Constants import in ClaimsTenantResolver
The import of Elsa.Identity.Constants was removed as it was not used in the ClaimsTenantResolver class. This cleanup helps maintain code clarity and reduces unnecessary dependencies.
* Remove outdated workflow activities
Removed several deprecated workflow activities pertaining to lead and deal updates in preparation for new workflow structure implementation.
* Reset EF Core migrations to 3.0
* Add missing default value in constructor
A default value was added to the WorkflowDefinitionModel constructor to align with the expected parameter count. Additionally, removed unused tenant-related code from ElsaDbContextBase and redundant entity configurations from DbContext specific to Oracle, simplifying the model setup.
* Fix interface list type in store populator
Adjusted the type passed to the DefaultWorkflowDefinitionStorePopulator constructor to use the correct IWorkflowsProvider interface. This change aligns the type expectation with the implemented providers list, ensuring proper dependency resolution.
* Update model snapshots to v7.0.14 and add new properties
The model snapshots for various database providers have been updated to reflect the new product version 7.0.14. Additionally, new properties and indices for `IsSystem`, `TenantId`, and compression information have been introduced across entities such as `WorkflowDefinition`, `WorkflowInstance`, `Label`, and others to support multi-tenancy and system-level workflows.
* Add tenant ID and alter status column
Migration V3_1 adds a tenant ID column and indexes, and changes the status column's type to a string across all database providers. It also renames the SerializedWorkflowInstanceIds to SerializedWorkflowInstanceFilter.
* Refactor Dapper integration for multi-tenancy support
Updated migration versions and internalized records to extend from a new base Record class with tenant ID property for multi-tenancy. Added TenantId across stores and migrations to support tenant-specific data isolation within the Dapper module.
* Add multi-tenancy support to Dapper provider
Introduced TenantId to various tables and records to enable multi-tenancy. Migration scripts have been added across modules for managing TenantId columns effectively.
* Introduce multi-tenancy support for MongoDB provider
Optimized TenantResolver for caching current tenant, refactored MongoDB stores to include tenant resolution, and updated index creation to add tenant-specific indices. Enforced multi-tenancy across various Elsa modules ensuring tenant isolation and efficient data retrieval.
* Refactor bookmark ID references to use 'Id' property
Changed usage of BookmarkId to Id across several files, ensuring consistent referencing of the bookmark identifier for clarity and future deprecation of obsolete properties.
* Refactor MongoDB store to support tenant-agnostic queries
Provide an option for tenant-agnostic operations across all MongoDB store methods, including Find, Count, Any, and Delete operations. Default behavior respects tenant boundaries, but adding a flag allows operations to ignore tenant constraints. Removed unnecessary using directive.
* Add Dapper persistence stores and refactorings
Added Dapper persistence stores for various entities and refactored existing stores for better maintainability.
* Add tenant-agnostic query support to Elsa Dapper
Introduced an option to perform tenant-agnostic queries in Elsa Dapper, allowing retrieval of records without tenant filtering. Refactored query methods to include a tenantAgnostic parameter and applied tenant filters conditionally based on this flag. This supports scenarios where tenant-specific data isolation is not required.
* Refactor tenant resolution in Store.cs
Changed the code to asynchronously resolve the tenant and handle possible null values before assigning the tenant ID. This improvement ensures tenant resolution is done properly and enhances code reliability by checking for nulls.
* Switch Mongo collections to IMongoCollection
Refactored Mongo collection references to use IMongoCollection interface across various modules. This change allows for more consistent and flexible database operations. Additionally, updated program configuration to enable MongoDB and disable Dapper.
* Remove ac-call-ring-group workflow
The workflow file ac-call-ring-group.json has been deleted, as it is no longer needed in our project. This may be due to changes in requirements or workflow optimizations.
* Reset EF Core migrations to 3.1
* Update migration scripts and clean up Elsa.Tenants dependencies
Removed outdated migration scripts (efcore-3.0.sh, efcore-3.1.sh, efcore-3.1-sql.sh) and added new versions (generate.sh, generate-sql.sh). Also optimized the dependency list in Elsa.Tenants.csproj - switched individual package references into a single reference to Microsoft.AspNetCore.App. This streamlined the project's dependencies and reduced redundancy.
* Add TenantId to multiple tables and update primary keys
The commit introduces a 'TenantId' column to several tables in the database schema including 'WorkflowInboxMessages', 'WorkflowExecutionLogRecords', 'Triggers', 'KeyValuePairs', 'Bookmarks', and 'ActivityExecutionRecords'. Additionally, the primary key for the 'KeyValuePairs' table was updated and the 'BookmarkId' column in the 'Bookmarks' table was renamed to 'Id'. These changes were necessary to support new functionality and requirements in the application.
* Update "MultiTenancy" to "Multitenancy"
This change reflects the renaming of "MultiTenancy" to "Multitenancy" in multiple instances throughout the codebase. This update is made in the 'appsettings.json' configuration file and also in 'Program.cs' where the renamed section is being accessed.
* Remove generate-migrations-initial copy.sh script
This commit deletes the generate-migrations-initial copy.sh script from the project. The script was previously used for managing database migrations across different providers but it's no longer needed. This change simplifies the codebase and reduces maintenance work.
* Fix typo in configuration key of Multitenancy
The typo in the configuration key "MultiTenancy" has been corrected to "Multitenancy" in both Program.cs and appsettings.json files. This ensures that the program correctly reads the multitenancy configuration from the appsettings.json file.
* Remove unused imports in ElsaStudioWebAssembly
The unnecessary namespaces Elsa.Studio.Workflows.Extensions and System.Text.Json have been removed from the ElsaStudioWebAssembly Program.cs file. This change helps to keep the code concise and increase readability.
* Simplify comment
* Update TenantResolutionStrategyBase class description
The class summary for TenantResolutionStrategyBase has been updated to more accurately reflect its purpose. It is now described as a base class intended for implementing a tenant resolution strategy, providing a more clear understanding of its functionality.
* Remove GetTenantId method from WorkflowInstanceStore
This update removes the unused GetTenantId method from the WorkflowInstanceStore.cs file. Additionally, minor formatting changes have been made to clean up extra spaces and align the syntax for better readability.
* Update ApplyTenantId class description
The class description in the ApplyTenantId file has been updated for clarity. This handler is designed to apply the tenant ID to an entity before changes are saved.
* Refactor TenantId filter application in Elsa module
The SetTenantIdFilter class in the Elsa.EntityFrameworkCore.Common module has been refactored to improve readability and performance. Flattening of control blocks has been done for better comprehensibility. Additionally, the logic has been revised to apply a TenantId filter only if an entity is assignable to the shared Entity base class.
* Remove MustHaveTenantException
The file MustHaveTenantException has been deleted. This exception is no longer needed in the project, due to changes in tenant handling.
* Remove unused Migrations\Alterations folder reference
The reference to the Migrations\Alterations folder in the Elsa.EntityFrameworkCore.MySql project file has been removed. This folder is not being used anywhere in the project hence the reference was unnecessary. This change simplifies the project structure.
* Refactor code and annotate methods in WorkflowInstanceStore
The update includes adding 'System.Diagnostics.CodeAnalysis' namespace and a number of attributes 'RequiresUnreferencedCode' to various methods because they call 'Elsa.Workflows.Contracts.IWorkflowStateSerializer.SerializeAsync(WorkflowState, CancellationToken)'. Additionally, removed the 'GetTenantId' method as it is no longer used.
* Refactor MongoWorkflowInstanceStore for cleaner code
The constructor of MongoWorkflowInstanceStore has been simplified and the use of a private MongoDbStore<WorkflowInstance> has been removed. This results in the use of mongoDbStore directly in calls instead of referencing a private instance, leading to a leaner and more readable implementation. The method GetTenantId has also been removed as well.
* Rename 'strategies' to 'resolvers' in TenantResolution code
The term 'strategies' has been replaced with 'resolvers' throughout the TenantResolution code, to better reflect its purpose. All references, variable names and comments have been changed accordingly. The change also includes error messages and function inputs, making the codebase more consistent and understandable.
* Rename MultiTenancyOptions to MultitenancyOptions
All references to MultiTenancyOptions have been changed to MultitenancyOptions as part of a codebase-wide renaming effort. This is done to ensure consistent naming conventions across the project.
* Update attribute message in ConfigurationTenantsProvider
The attribute message associated with the FindAsync method in the ConfigurationTenantsProvider class has been changed. It now indicates that the caller of the method may require dynamic access to the tenant properties.
* Remove tenant ID method from IWorkflowDefinitionStore
This commit removes the GetTenantId method from the IWorkflowDefinitionStore interface. The method, which used to find the tenant ID of a workflow definition for a specified ID, is no longer necessary in the updated design.
* Remove tenantId retrieval methods
The methods for retrieving tenantId have been removed from several modules across the application. This decision was based on a shift in architecture design, thus limiting the need for these specific methods.
* Refactor EFCoreWorkflowDefinitionStore constructor parameters
The EFCoreWorkflowDefinitionStore constructor parameters are refactored to no longer be private field properties. This change streamlines the code by eliminating redundancy. Also, now all method calls within the class use these directly passed parameters.
* Refactor MemoryBookmarkStore for code simplification
Revised MemoryBookmarkStore to remove the private field and directly use the constructor parameter instead, achieving a more straightforward structure. This modification simplifies the code, making it easier to understand and maintain.
* Refactor ServiceBus integration tests for readability
This commit simplifies and improves the readability of the code in ServiceBus integration tests. The changes primarily involve reformatting method call arguments for better visibility and removing superfluous white space. Additionally, a null-check operator has been added for safety.
* Remove redundant release configurations
The commit removes duplicate lines for the release configuration of the project with ID {99F2B1DA-2F69-4D70-A2A3-AC985AD91EC4}. The project solution (.sln) file is now cleaner and easier to read, reducing potential confusion when reviewing or modifying configurations.
* Remove Debug build configuration for project
This commit removes the debug build configuration setting from the Elsa.sln. The unnecessary setting for Debug Any CPU build for the specific project has been deleted, aiming to streamline and maintain only needed configurations.
* Update NuGet.Packaging and NuGet.Protocol versions
The versions of NuGet.Packaging and NuGet.Protocol packages were updated from 6.8.0 to 6.9.1. This update is aimed at keeping compatibility in our project with the latest updates and features available in these packages.
* Add caching to workflow runtime and workflow management stores
The update introduces caching to workflow runtime and workflow management stores to enhance performance. This is achieved by adding decorators for several stores, which cache records to reduce database fetches. Additionally, a signaler for change tokens allows for cache invalidation when changes occur. The MemoryCache feature has also been updated to include Scrutor for decoration and the caching duration can be configured through the new CachingOptions class.
* Refactor WorkflowsMiddleware for HTTP Endpoint bookmarks and triggers
The WorkflowsMiddleware has been extensively refactored to handle HTTP Endpoint bookmarks and triggers. This involves breaking down the InvokeAsync method by extracting parts of its functionality into separate helper methods such as FindTriggersAsync and FindBookmarksAsync. Moreover, Assist with authorization checks, workflow execution within request timeout, and handling of workflow faults has been improved to be more efficient and clearly segmented.
* Update HTTP endpoint authorization to use Workflow context
The authorization process in the AuthenticationBasedHttpEndpointAuthorizationHandler class has been updated to use the Workflow context instead of the WorkflowInstanceId string. The AuthorizeHttpEndpointContext model has been correspondingly changed to include a Workflow property, thereby strengthening the link between authorization and specific workflows.
* Add FindAsync methods to trigger and bookmark stores
The code adjustments add new FindAsync methods to the trigger and bookmark store contracts as well as all their concrete implementations (MongoDb, Memory and EFCore). These methods support fetching the first record matching a given filter. The adjustments also include minor syntax improvements and the addition of [UsedImplicitly] attributes where needed.
* Refactor WorkflowsMiddleware for improved workflow handling
The code was refactored to simplify the flow of handling workflows in the WorkflowsMiddleware class. Specifically, the methods to start and resume a workflow have been extracted to improve code readability. Further, handleErrorMiddlewares was also updated to better manage instances where no valid workflows or base paths are found.
* Add caching functionality to WorkflowsMiddleware
Added IMemoryCache usage in the WorkflowsMiddleware to cache lookup results for workflows and their associated triggers. This will reduce the number of database operations required when searching for workflows, thus improving performance. The cache is maintained for one minute before it is refreshed.
* Implement dynamic cache duration for workflows
The code has been updated to have a dynamic cache duration for the workflows instead of a hardcoded one minute. By using the CachingOptions service, the cache duration can now be set in the configuration making it more flexible and adaptable to different performance needs.
* Add HttpWorkflowsCacheManager for caching HTTP workflows
This commit includes the implementation of IHttpWorkflowsCacheManager for caching of HTTP workflows. New handlers have been added to invalidate cache on workflow updates. Additionally, WorkflowsMiddleware has been renamed to HttpWorkflowsMiddleware.
* Refactor workflow trigger handling and caching
The refactoring includes deletion of `IndexWorkflowTriggersHandler.cs` and creation of `IndexTriggers.cs` thus revising the workflow trigger indexing approach. Also, revamped the `ITriggerIndexer` interface which now handles deletion of triggers with specific workflow and filter. Furthermore, the caching mechanism in `HttpWorkflowsCacheManager.cs` is modified to handle eviction of workflow definitions and triggers separately boosting its efficiency.
* Add summary to IndexedWorkflowTriggers
A summary has been added to the 'IndexedWorkflowTriggers' class, providing a brief description. This description outlines that it represents a collection of indexed workflow triggers, promoting clearer understanding for future reference.
* Refactor memory caching feature into separate module
This commit separates the memory caching feature from the Elsa.Common module into a distinct Elsa.Caching module. This includes moving and renaming related files, such as the MemoryCacheFeature class and associated dependencies. The references in other modules and in the main solution file have been updated accordingly to include the new Elsa.Caching module.
* Add distributed caching and update async methods
Introduced a distributed caching feature with extensible change token signal publishing. Updated various cache-related methods to be asynchronous for improved performance and responsiveness. Also updated some workflow identity references for clarity.
* Add distributed caching with MassTransit support
This addition includes the implementation of a distributed caching system with MassTransit transport. The changes introduce necessary interfaces and services, new distributed caching feature along with the support for MassTransit as a transport option. Moreover, the instance management feature has been renamed to clustering feature for better clarity.
* Refactor queue naming and scope of MassTransitChangeTokenSignalPublisher
Queue name construction is adjusted in the RabbitMqServiceBusFeature and AzureServiceBusFeature modules for better organization and readability. MassTransitChangeTokenSignalPublisher is now a singleton service, ensuring the signal publisher can be shared across the application, increasing efficiency and performance. Also, introduced use of DistributedCacheFeature in MassTransitDistributedCacheFeature module for better modularization.
* Add caching capabilities to workflow definition service
This commit introduces caching to the workflow definition service, improving the performance for retrieving workflow definitions. 4 new classes have been created (`CachingWorkflowDefinitionService`, `EvictWorkflowDefinitionServiceCache`, `WorkflowDefinitionCacheManager`, and `IWorkflowDefinitionCacheManager`), and several existing classes have been updated to support caching. The caching also includes invalidation mechanisms, ensuring data consistency.
* Refactor caching mechanism in workflow definition
In the workflow definition module, the explicit caching functionality related to workflow definition versioning has been removed in favor of a more streamlined approach. Additionally, the manner in which services are registered has been altered. As a result, the caching now directly involves the overall workflow definition rather than individual versions, simplifying the caching logic and potentially improving the performance.
* Update MassTransitBroker and enable RealTimeWorkflows and SignalRHubs
The MassTransitBroker has been updated to Memory from RabbitMq. In addition, the RealTimeWorkflows and UseWorkflowsSignalRHubs features are now enabled in the code. This change will impact how the service communicates and processes real-time requests for workflow operations.
* Reformat variable types in HttpFeature
The reformatting involves a list of variable types in the HttpFeature module. Each type now appears on a new line for improved readability, making the code easier to maintain and review.
* Update HTTP workflows cache invalidation handler XML comment
* Remove unnecessary using directives
Unnecessary using directives were deleted across several files in the Elsa.Http module. This simplifies the code and will possibly improve execution speed. Specific deletions include those for Encoding, Unicode, Extensions, Collections.Generic, Linq, Text, and Tasks namespaces.
* Refactor HttpWorkflowsMiddleware constructor
This commit simplifies the HttpWorkflowsMiddleware class constructor. It removes the intermediary variables `_next` and `_options` and directly uses the passed arguments in the constructor. Now, the `next` and `options` parameters are used directly throughout the middleware.
* Simplify workflow retrieval in HttpWorkflowsMiddleware
This refactoring replaces the use of FindWorkflowDefinitionAsync and MaterializeWorkflowAsync with a single method, FindWorkflowAsync. This simplifies the middleware code and likely improves performance by reducing the number of database queries or service calls required to retrieve a workflow.
* Refactor workflow retrieval in HttpBookmarkProcessor
Simplified the workflow retrieval process in HttpBookmarkProcessor.cs. Replaced FindWorkflowDefinitionAsync and MaterializeWorkflowAsync methods with a single FindWorkflowAsync call. This reduces the complexity and improves efficiency in retrieving workflow.
* Optimize FindWorkflowAsync method in HttpWorkflowsCacheManager
Removed redundant lines of code to simplify workflow search functionality. This change simplified the FindWorkflowAsync method by directly calling the FindWorkflowAsync function in the workflowDefinitionService, thus increasing code readability and efficiency.
* Refactor Endpoint.cs for workflow retrieval
The method for obtaining a workflow in the Endpoint.cs script has been refactored and streamlined. The 'GetWorkflowDefinition' method is replaced by the 'GetWorkflowAsync' method which directly retrieves the workflow, without the intermediate step of materializing the workflow definition. This shortens the code and simplifies the process.
* Refactor InputFunctionsDefinitionProvider constructor
The constructor for InputFunctionsDefinitionProvider has been simplified by removing unnecessary private fields. Services are now directly used in the method instead of being stored in fields. This improves readability and reduces complexity in the class structure.
* Refactor WorkflowInstance with improved state handling
Simplified the methods for handling workflow and workflow state in the WorkflowInstance class. The refactoring also included some code clean-ups and variable renaming. The new implementation provides better readability and maintainability of the code by reducing unnecessary lines and improving structuring of objects and responses.
* Remove unused IBookmarkManager and update workflow functions
IBookmarkManager from ProtoActorWorkflowRuntime.cs file is removed due to its redundant status. Additionally, the "FindAsync" method has been updated to use a cancellation token. Also, annotations were added to the "ExportWorkflowStateAsync" and "ImportWorkflowStateAsync" methods to flag calls to functions that require unreferenced code.
* Remove unused ReSharper directive
Unused ReSharper directive in the file IndexTriggers.cs was identified and therefore removed. This change makes the code cleaner and easier to read.
* Update activity invocation in workflow runtime
Updated the DefaultBackgroundActivityInvoker service in the Elsa.Workflows.Runtime module to annotate the ExecuteAsync method with "RequiresUnreferencedCode" attribute. This change is made considering the potential code trimming issue. Additionally, simplified the process of fetching workflow by directly using FindWorkflowAsync method instead of FindWorkflowDefinitionAsync and MaterializeWorkflowAsync methods.
* Refactor code to simplify workflow definition loading
The code for finding and materializing workflow definitions has been simplified. Instead of loading the definition and materializing it into a workflow in separate steps, a new method called FindWorkflowAsync has been introduced to perform both actions at once. This reduces redundancy and makes the code more readable.
* Refactor WorkflowHostFactory to streamline workflow creation
This commit simplifies the workflow creation process in WorkflowHostFactory. It removes redundant code and extraneous methods, specifically the overloaded CreateAsync method which used WorkflowDefinition. Now, it directly finds and uses the Workflow instance, thereby simplifying the code base and improving maintainability.
* Refactor workflow retrieval in WorkflowInstance.cs
Changed the way workflow instances are retrieved from the WorkflowDefinitionService. Instead of obtaining the workflow definition and then materializing the workflow from it, the workflow is directly retrieved using the FindWorkflowAsync function. This simplifies the code and avoids unnecessary null-checks.
* Remove unnecessary whitespace in WorkflowInstance.cs
An extraneous whitespace character was identified and removed in the WorkflowInstance.cs file. This change contributes towards maintaining clean and readable code in the Elsa.ProtoActor module.
* Remove unnecessary comment in ProtoActorWorkflowRuntime
The unnecessary comment ("Load the workflow definition.") in the method TryStartWorkflowAsync of the ProtoActorWorkflowRuntime.cs file was removed. This is part of an ongoing effort to keep the codebase clean and readable.
* Update workflow management features and handlers
Added explicit notification handlers for DeleteWorkflowInstances and RefreshActivityRegistry in WorkflowManagementFeature.cs. Also, renamed RefreshActivityRegistryHandler.cs to RefreshActivityRegistry.cs for better clarity.
* Add multiple log record support to workflow execution log stores
The major change of this commit is the addition of methods to add multiple log records in the WorkflowExecutionLogStore, across different storage modules such as EntityFramework, MongoDB, Dapper, Elasticsearch and Memory. This ensures consistency and uniform behavior across different storage types. Furthermore, some reformatting and tidying up of the code were undertaken to maintain readability and clarity.
* Remove redundant workflow definition check
The workflow definition existence check and related service retrieval were removed from HttpWorkflowsMiddleware.cs. It was determined that this check was unnecessary as the workflow definition's existence is guaranteed at this point in the process, reducing redundancy in the code.
* Improve cancellation token usage in workflow execution
This commit refines the usage of cancellation tokens during the execution of workflows in Elsa.Server and HttpWorkflowsMiddleware. Previously, a cancellation token pair was created before ExecuteWithinTimeoutAsync was called, which limited duration control solely to that method. Now, cancellation tokens are included within ExecuteWithinTimeoutAsync method. This allows the method to observe any cancellation initiated by outer scopes, enhancing control over the timeout of operations.
* Remove unused EntityFrameworkCore import
The Microsoft.EntityFrameworkCore namespace was included but not used in ElsaDbContextOptions.cs. This commit removes that unnecessary import to simplify the code and improve clarity.
* Add PersistStateAsync method to WorkflowHost
A new PersistStateAsync method has been added to the WorkflowHost, which enables the host to directly persist its own state. The method has been integrated into the DefaultWorkflowRuntime and HttpWorkflowsMiddleware. This update eliminates the need to continuously get instances of IWorkflowInstanceManager to save state, which improves efficiency and code readability.
* Refactor DefaultAlterationRunner service
This update simplifies the DefaultAlterationRunner service, reducing the number of code lines and removing unnecessary references. The workflow materialization step has been merged with the find workflow step, and unused namespaces have been dropped.
* Refine wording in IWorkflowHost interface documentation
The documentation for the 'CanStartWorkflowAsync' method in the IWorkflowHost interface has been cleaned up. The superfluous "or not" verbiage has been removed, making it easier to understand the method's function.
* Remove CancellationTokens struct and simplify cancellation handling
Removed the CancellationTokens struct and all its references across the code base. Simplified cancellation handling by using standard CancellationToken only. Also cleaned up redundant usages and unnecessary namespaces across various modules. This simplification better aligns with standard .NET conventions and reduces the code complexity.
* Implement ActivityHandle for better activity identification
The ActivityHandle class has been introduced to consolidate various activity identification parameters such as ActivityId, ActivityNodeId, ActivityInstanceId, and ActivityHash. This makes it easier to track and manage activities by reducing the number of parameters needed for identification. Adoption of ActivityHandle has been implemented across the codebase.
* Remove AzureContainerApps related code
This commit includes the removal of all the AzureContainerApps associated code from the ProtoActor Cluster. The deletion includes multiple files which had housed the AzureContainerApps cluster provider and all its supporting services, util functions, options, contracts, and models. This move might be towards refactoring the structure or removal of unwanted dependencies.
* Add distributed execution runtime and client
Removed some unused classes and created a distributed execution runtime using distributed locking and persistence. Introduced an interface for workflow clients and implemented two versions, a local one and one using `Proto.Actor`. Made some changes in other modules to add the necessary interfaces and methods. Also, added `DistributedLockingRuntime` module to implement distributed execution.
* Remove WorkflowClient.cs from Elsa.Workflows.Runtime
The WorkflowClient.cs file was removed from the Elsa.Workflows.Runtime project. It held placeholder methods that had not yet been implemented, making it unnecessary in the current codebase.
* Add ProtoActor implementation for workflow execution
Added ProtoActor implementation for executing workflow instances. This includes ProtoBuf message definitions, grain interfaces and implementations, and various ProtoActor services. Extended WorkflowHost and related components to provide more execution details in order to better support distributed processing via ProtoActor.
* Refactor workflow parameters to workflow requests
The refactor includes renaming old 'WorkflowParams' classes to 'WorkflowRequest' to better represent their usage. The changes have been made across all the involved modules ensuring that the project maintains consistency. New properties, methods, and class names were updated accordingly.
* Add ProtoActor implementation for data mappers
This update adds the ProtoActor implementation for data mappers and updates the DI configuration accordingly. It also updates the client interfaces for a more streamlined usage, and refactors the WorkflowHost to adapt to these changes. All changes were implemented in accordance with the new bookmark information model.
* Add functionality to create a new workflow instance
This commit introduces the capability to create a new workflow instance in the Elsa Workflow Runtime by enhancing existing workflow classes and creating the WorkflowClientFactoryExtensions class, in addition to adding the "IsNewInstance" parameter to multiple workflows and requests. It provides more flexibility in managing workflow instances and aids in building workflow processes that require instantiation of a new workflow.
* Remove Elsa.Runtimes.DistributedLockingRuntime module
This commit deletes the Elsa.Runtimes.DistributedLockingRuntime module from the project. Changes include removed code files related to features, services and commands under this module. The Elsa.sln file has been updated to reflect these changes, excluding the removed module from the solution.
* Add dynamic client type to WorkflowClientFactory
The WorkflowClientFactory now accepts a client Type parameter for dynamic client creation. This enables the factory to create different subclasses of IWorkflowClient based on the provided Type. The CreateClient function is updated in the WorkflowClientFactoryExtensions and IWorkflowClientFactory interface, and applied in HttpWorkflowsMiddleware.
* Implement Proto.Actor support in Elsa
A comprehensive change that introduces support for Proto.Actor clustering to Elsa. It includes a redesign of the workflow client invocation model, transitioning the methods from synchronous to asynchronous. Also, modification to the Proto.Actor-based 'WorkflowGrain' was made to handle state recovery and execution processing. The structural enhancements improve scalability and performance capabilities.
* Refactor null-checks in SaveSnapshotAsync method
Simplified the null-checking in the method SaveSnapshotAsync within WorkflowGrain.cs. The check on _workflowHost and workflowState has been shortened using conditional access operator, improving the code readability.
* Refactor code to enhance database configuration logic
Removed the 'IModelCreatingHandler' file as it's no longer needed and instead introduced enums for 'SqlDatabaseProvider' and 'PersistenceProvider'. The enums replace previous hard-coded boolean flags for database options, making the code cleaner and more scalable. Simplified and improved the efficiency of Database Connection Handling by optimizing the timing of connection creation.
* Improve tenant ID retrieval in HttpContext
The method GetTenantId has been updated in HttpContextTenantExtensions. Instead of accessing the "TenantId" key directly in HttpContext.Items, it now uses TryGetValue. This change improves error handling for cases when the "TenantId" key is not found in the collection.
* Remove trailing comma in IdentityTokenOptions
The trailing comma at the end of the NameClaimType assignment in the IdentityTokenOptions.cs file has been removed. This change ensures proper usage of the syntax and maintains the cleanliness of the codebase.
* Remove unused imports
Several unused imports were detected and removed from the codebase. These imports were scattered across multiple files and did not contribute to the functionality of the system. By removing them, we decrease clutter and make the codebase easier to navigate and maintain.
* Refactor code and update packages
The codebase has undergone a major refactoring to improve code readability and consistency, with non-essential methods being removed and variable names being optimized for clarity. Package references for Proto.Actor and related packages have been also updated to the latest versions.
* Add Proto.Cluster.AzureContainerApps package to Directory.Packages.props
The Proto.Cluster.AzureContainerApps package with version 1.6.0 has been included in the Directory.Packages.props file. This addition extends the range of Proto.Cluster packages used in the project.
* Remove redundant Proto.Actor implementation files
This commit removes several redundant files related to the Proto.Actor implementation. These files were unnecessary and were cluttering up the codebase. With this removal, the project has become leaner and easier to maintain. It also eliminates potential confusion for future developers working on this project.
* Add WorkflowMatcher and replace BookmarkHasher with StimulusHasher
This commit introduces a new class, WorkflowMatcher, which represents a contract for finding triggers and bookmarks associated with workflow activities. It also renames and replaces all instances of BookmarkHasher with StimulusHasher to reflect a more accurate function relating to stimulus rather than bookmarks. Other necessary changes were made to ensure consistency with these updates across different classes. It's important to note that WorkflowInbox interface is now marked as obsolete.
* Incremental work on stimuli refactoring
* Refactor codebase to support new IWorkflowInvoker and invoke workflow logic
Multiple files updated to introduce a `IWorkflowInvoker` interface, implementation and supporting classes. This simplified how workflows are instantiated and invoked. Consequently, necessary adjustments made across multiple entities and endpoints to account for the updated invocation procedure. Old logic related to counting running workflows removed. Introduced stimulus concept while deprecating non-compliant classes and methods.
* bumped versions to fix dependency vulnerabilities (#5256)
* Update patch version in GitHub workflows
The version number used in the branch checking step of the GitHub workflows has been updated. Instead of scanning for the branch containing the patch version 3.1.2, it now scans for the branch that contains version 3.1.3. This change is aligned with the updated product version.
* Update git branch grep pattern in workflow file
The git grep pattern has been corrected to properly identify tagged versions in the GitHub Actions workflow. The correction ensures that the workflow script fetches the right branches as per the release tag instead of patch.
* Update grep command in packages workflow
The grep command used in the 'packages.yml' GitHub workflow was previously looking for the exact 'refs/tags/3.1.3' string. This commit simplifies the command by making it only look for '3.1.3'. This adjustment will streamline the process and potentially prevent issues with branch recognition.
* Update package versions and refactor code for Elasticsearch and JavaScript modules
Updated versions of numerous packages in the Directory.Packages.props file to their latest stable releases. This includes updates to Elasticsearch, JavaScript, and MongoDB packages among others. Additionally, refactored parts of the code in the WorkflowInstanceConfiguration and JintJavaScriptEvaluator within the Elasticsearch and JavaScript modules, respectively, to improve index management and script preparation. The WorkflowInstanceStore also saw a minor adjustment.
* Refactor workflow management with workflow definition handles
The existing workflow management has been significantly refactored, introducing the concept of "Workflow Definition Handles". These handles allow for consistent management whether we're dealing with a specific workflow definition, a version of a definition, or more flexible version constraints. This refactor also adjusts how workflow instances are created, now using a more intuitive and detailed "WorkflowInstanceOptions" approach.
* Add ResumeBookmarkResult and update related methods
Implemented a ResumeBookmarkResult class to handle bookmark resumption results. Methods related to resuming bookmarks have been refactored to return this new class, providing more information such as bookmarks' matched state. Also, some methods were optimized to break the loop early if no bookmarks were found, improving code efficiency.
* Update workflow definition, execution and correlation
This commit focuses on enhancements and adjustments to workflow definition and execution. Notable changes include the addition of ExecuteResponse model and new test workflow scenarios. Refactoring has been performed to improve readability and efficiency in various components. It also includes an important fix for the correct application of WorkflowDefinition filters, primarily using both DefinitionId and DefinitionVersionId for more accurate results.
* Refactor runtime codebase for better structure and workflow control
This commit involves changes to functionally reorganize the runtime codebase for improved structure. It also allows for better handling of workflows, particularly through the addition of original bookmarks in the workflow execution context. Removed unnecessary dependencies and ensured more efficient management of bookmarks in the workflow running process. Several method and class names were also updated to better reflect their purpose.
* Refactor WorkflowInvoker and remove 'OriginalBookmarks'
Optimized the constructor of 'WorkflowInvoker' by using 'IServiceScopeFactory' to get instances of required services. Removed the 'OriginalBookmarks' property from 'WorkflowStateExtractor' and 'WorkflowState', a subsequent change included in 'WorkflowGraphBuilder' as well. Reorganized the namespaces in 'Elsa.Workflows.ComponentTests' project. Added 'UseCache' in WorkflowServer configurations.
* Removed RunWorkflowParams class
This update deletes the RunWorkflowParams class within the Runtime Requests of the Elsa.Workflows module. The class was no longer needed, hence the elimination and cleanup in the codebase.
* Update RunWorkflowParamsMapper to handle null or empty fields
This commit modifies the RunWorkflowParamsMapper in the Elsa.ProtoActor module. It primarily treats the BookmarkId and TriggerActivityId fields to return null if they are empty, boosting the application's robustness against potential null or empty field issues.
* Refactor workflow handling and improve null checks
In this update, the handling of workflows was refactored to improve efficiency. The 'RunAsync' method now correctly uses 'WorkflowGraph' as a parameter, instead of 'Workflow'. Additionally, null checks for 'bookmarkId' and 'activityHandle.ActivityInstanceId' have been improved to avoid null and empty strings. Finally, when '_workflowInstanceId' is null in the 'WorkflowGrain' class, it is now properly initialized by parsing the cluster identity.
* Enable ProtoActor in Elsa.Server.Web
This commit turns on the use of ProtoActor within the Elsa.Server.Web bundle. This switch may affect the system's behavior and performance.
* Added new workflow scheduling and management features
Implemented new features for creating, running, and scheduling workflow instances. The implementation added new files for handling workflow runtime and scheduling features, including creating and running a workflow instance request, a mapper for the request, and handler services. Modified files include updating method calls according to the new requests, updating workflow definitions, and adjustment to method arguments in Hangfire job class.
* Handle null or empty workflow instance IDs and correlation IDs
This commit introduces null checks for workflow instance IDs and correlation IDs in the workflow infrastructure. Previously, the code assumed that the IDs were provided. It now gracefully handles cases where they might be null or empty, preventing possible null reference exceptions and ensuring more robust workflow execution.
* Update mapping details in ResumeWorkflowJob
Removed unnecessary using statement for Elsa.Workflows.Runtime.Requests in ResumeWorkflowJob.cs. Updated references from DispatchWorkflowInstanceRequest to ScheduleExistingWorkflowInstanceRequest for retrieving ActivityHandle and WorkflowInstanceId.
* Refactor AzureServiceBus module and integrate into web project
In this commit, changes were made to the AzureServiceBus module to use Topic definitions for subscriptions. The Subscriptions property in the AzureServiceBusOptions and the Topic property in the SubscriptionDefinition class are marked as obsolete and suggestions to use TopicDefinition.Subscriptions instead have been added. The AzureServiceBus module was also integrated into the web project and configured to use options from the appsettings.json.
* Refactor code to use async scopes and improve service dependencies
Refactored code to use async scopes for improved task management. Also organized service dependencies better by moving service fetching inside methods where they are needed and propagating necessary dependencies through method parameters for cleaner code.
* Add Azure Service Bus workflow component tests
This commit introduces a set of workflow component tests for Azure Service Bus integration. These tests encompass scenarios like message receiving, sending messages with correlation IDS, and sending single messages. In addition, 'SignalResetEvent' test helper was removed, a new test helper 'TriggerSignal' was added, and a Mock ServiceBusClient and ServiceBusAdministrationClient were added to the WorkflowServer fixture. Lastly, the NSubstitute package was added to the test project's dependencies.
* Add support for deferred tasks in workflow execution context
Added support for deferred tasks in the workflow execution context. This implementation allows tasks to be deferred and executed right after persistence of bookmarks in the workflow. A new middleware, ExecuteDeferredActivityTasks, is introduced to handle the execution of these deferred tasks.
* Refactor TriggerSignal and SendMessage activity execution
Refactored the execution of TriggerSignal and SendMessage activities by using context.DeferTask to ensure the activities run asynchronously. Also, made code format modifications and simplifications such as handling ApplicationProperties better in the SendMessage activity, and other minor changes.
* Update workflow ID generation method
The workflow ID generation method has been updated in the WorkflowBuilder. Previously, it was always generated by _identityGenerator. Now, it only gets generated if the definitionId or Id is null or empty, otherwise it uses the existing value. This change brings the ID generation practice in line with how we handle definitionId.
* Add support for service bus testing in workflow tests
Two new helper classes, DictionaryExtensions and MockServiceBusProcessor, have been added to support mocking Azure service bus in workflow component tests. Also, the tests have been updated to use SignalManager to ensure proper order of execution. The WorkflowServer test fixture has been extensively refactored to create mock instances of service bus senders and processors. Furthermore, some configurations have been commented out and new configurations related to MemoryTriggerStore and MemoryBookmarkStore have been added.
* Enhanced workflow correlation and caching in Elsa Workflows
This update improves Elsa Workflows by enabling caching and enhancing correlation in Correlate.cs. It expands functionality by adding new methods that accept various input types and provide more options for activities correlation. Correlation improvements also extend to AzureServiceBusTests, which were updated to test workflow instances by correlation ID. Furthermore, the test workflow received a name change and new correlation mechanics based on Azure messaging.
* Renamed method argument from 'payload' to 'stimulus'
The method argument 'payload' in various functions across 'MessageReceived.cs' and 'ActivityExecutionContext.cs' files has been renamed to 'stimulus'. This change was made to improve code readability and understanding by using a more context-specific term.
* Refactor Workflow APIs and enhance logging
Refactored Workflow APIs by removing the TriggerActivityId from StimulusMetadata and introducing Direct Triggers. Refactored Reenter method in WorkflowGrain to be more concise and straightforward. Enhanced logging by adding additional logging in ActivityExecutionPipeline and LogLevel in appsettings. Also, updated ProtoActorFeature for better log level management.
* Refactor AzureServiceBusTests and add workflow completion signal
The AzureServiceBusTests class is refactored to separate and encapsulate concerns. SignalManager and WorkflowEvents are now class-level variables. Also, a signal to indicate the completion of a workflow is added. This allows the test to wait for workflow completion in the sequence of its operations. Additionally, the workflow definition ID in MessageReceivedTriggerWorkflow is now static and fixed, rather than dynamically derived from the class name.
* Refactor methods to streamline workflow creation and execution
The changes primarily consolidate the process of creating and running a workflow instance into a single operation. Specifically, the 'CreateAndRunWorkflowInstanceRequest' class is utilized in multiple modules to simplify and streamline the workflow creation process. Also, several redundant and inefficient methods were removed in the 'WorkflowGrain' module, and the remaining methods were updated to return the required response directly, resulting in cleaner, more efficient code.
* Refactor asynchronous serialization to synchronous
Simplified serialization by converting all asynchronous tasks in the workflow state serializer to synchronous ones. This change affects Elsa's Core, Dapper, EntityFrameworkCore, Management, and ProtoActor modules, as well as the Workflow State Serializer - switching all async workflow state serialization methods to their synchronous equivalents.
* Removed Elsa.ServiceBus.IntegrationTests project
The Elsa.ServiceBus.IntegrationTests project and all related files and references were removed from the solution. This update affects the main application and several workflow files, scenarios, and helper methods.
* Refactor WorkflowGrain and update ProtoActor timeouts
Renamed the Method OnStopped to async and replaced Context.Stop with Context.Poison in the Method Stop within the WorkflowGrain.cs. Also, adjusted the ActorRequestTimeout to a shorter duration and commented out the LegacyRequestTimeoutBehavior() in ProtoActorFeature.cs. These changes aim to enhance the efficiency and performance of the system.
* Refactor Workflow execution and ProtoActor interaction
This commit refactors the execution of workflows to manage re-entrancy and improve sequential calls. It also modifies the interaction model between ProtoActor grains and clients by following the ask-pattern. The ProtoWorkflowSubStatus enumeration has been extended to include a "Pending" state. The ActorRequestTimeout has been increased for better debugging.
* Remove unused queue and receive timeout in WorkflowGrain
The _executionQueue was initialized but never used in the WorkflowGrain class. This removal leads to cleaner and less confusing code. Additionally, the Context.SetReceiveTimeout method call has been removed from OnStarted method as it's no longer needed.
* Add ProtoActor to WorkflowServer runtime
In the WorkflowServer of Elsa Workflows Component Tests, the ProtoActor has been added to the runtime settings. This enhances the overall functionality and efficiency of the server.
* Add new component tests for Elsa.AzureServiceBus and remove old unit tests
In this commit, a new set of component tests for Elsa.AzureServiceBus have been added, providing more detailed and reliable testing. Simultaneously, several old unit test files and projects have been removed as they're no longer relevant or useful. These include tests in the 'Elsa.Workflows.Runtime.UnitTests1', 'Elsa.Activities.UnitTests' and 'Elsa.JavaScript.UnitTests' namespaces among others. The decision to remove these tests is motivated by the desire to streamline the testing process and focus on the most meaningful and reliable tests.
* Rename GlobalUsings.cs to Usings.cs in integration tests
Renamed the GlobalUsings.cs file to Usings.cs in the Elsa.Alterations.IntegrationTests project to better reflect its purpose. This change is intended to improve clarity within the codebase.
* Refactor Azure service bus testing setup to separate extension
This commit abstracts the setup for Azure service bus testing into a separate extension named AzureServiceBusServiceCollectionExtensions. The code has been removed from the WorkflowServer class, contributing to a cleaner and more modular codebase. This enhancement will facilitate better unit testing and reduce redundancy in test setup.
* Uncomment 'Description' and remove 'OptionsProvider' and 'OptionsMethod'
In the 'InputAttribute.cs' file, the 'Description' property has been uncommented to allow for a brief description of properties during workflow tooling. Furthermore, the 'OptionsProvider' and 'OptionsMethod' properties have been removed, simplifying the attribute options handling.
* Enable Azure Service Bus module
The change updates the 'useAzureServiceBusModule' constant from false to true in the Elsa.Server.Web Program.cs file. This adjustment allows the application to employ the Azure Service Bus module.
* Refactor ProtoActor module for workflow instance focus
The main changes in this commit revolve around renaming and refactoring to orient the ProtoActor module toward handling workflow instances. In the process, unnecessary imports have been removed, classes have been renamed to reflect their new focus on workflow instances, and various related elements such as protobuf files and services have also been renamed and refactored to align with these changes.
* Change AnalysisModeDocumentation to 'AllDisabledByDefault'
The AnalysisModeDocumentation setting in Directory.Build.props has been updated to 'AllDisabledByDefault' from 'Default'. This change disables all analysis by default in the documentation generation process.
* Update default value for Content and modify build properties
Modified the default value for the property 'Content' in the 'Message' class. Also updated the build properties by changing the 'AnalysisModeDocumentation' to "Default", disabling 'EnableTrimAnalyzer', and adding exception warning codes 'CS0162' and 'CS1591' to 'NoWarn'.
* Disable Azure Service Bus and initialize Customer fields
With this commit, the Azure Service Bus module usage has been turned off. In addition, the initial fields of the Customer entity have been set to their default values for safer initialization and to avoid potential null reference exceptions.
* Add distributed workflow services and configurations
Implemented basic functionalities in DistributedWorkflowClient and DistributedWorkflowRuntime. Updated Web Application 'Program.cs' to support different WorkflowRuntimes as per the configuration. Renamed WorkflowRuntimeFeature.cs to DistributedRuntimeFeature.cs and refactored the code accordingly. Removed unnecessary method 'UseDefaultWorkflowRuntime' from ModuleExtensions.cs.
* Refactor ReceivedServiceBusMessageModel from record to class
Converted ReceivedServiceBusMessageModel from a record to a class and updated relevant initialization code. Change was implemented because of the polymorphic serialization incabability of dealing with $type properties with records.
* Refactor WorkflowInstanceImpl for improved workflow management
This change refactors the WorkflowInstanceImpl class to improve workflow management. It implements queuing of RunWorkflowOptions while a workflow is running and ensures state before any workflow operations. Furthermore, workflow host creation is replaced with directly creating and managing workflow instances.
* Add DefaultFormattersFeature and update dependencies
A new feature, DefaultFormattersFeature, has been added to the Elsa.Common module. The WorkflowsFeature in the Elsa.Workflows.Core module has been updated to depend on this new feature. This will ensure that default JSON formatters are available across the application.
* Refactor JsonFormatter with JsonSerializerOptions property
Improved the JsonFormatter class by introducing a private JsonSerializerOptions property. The new implementation uses this property in the FromStringAsync method instead of initializing a new JsonSerializerOptions each time, improving efficiency. The JsonStringEnumConverter has also been moved to the class constructor.
* Refactor WorkflowInstanceImpl for improved code clarity
The refactor includes replacing direct field access with properties in multiple places for WorkflowGraph and WorkflowState. It also makes _queuedRunWorkflowOptions field readonly and removes unnecessary newline characters. These changes aim to improve readability, maintainability and encapsulation.
* Add and update methods to workflow instances
This commit introduces add and update functionalities to the workflow instances across the application. Additionally, it includes enhancements to the workflow execution, such as distributed locking and expanded logging capabilities for better debugging and tracking. Lastly, it introduces new configurations in application settings to fine-tune the workflow runtime environment.
* Refactor worker management in AzureServiceBus module
The codebase has been simplified by removing the unnecessary management of worker ref counts in the AzureServiceBus module. Previously, to manage worker instances, we kept a count of references to each worker and removed it when the count dropped to zero. This complexity has been entirely removed to make the module simpler and easier to maintain. Now we just create a worker when necessary, without tracking its usage across the codebase.
* Refactor workflow runtime with distributed locking and state checking
The workflow runtime has been refactored for better concurrency control and state management. The changes primarily include the introduction of distributed locking in action methods of the DistributedWorkflowClient and the handling of workflow instance states in the LocalWorkflowClient. This entails changes to the logic in the RunInstanceAsync, CreateAndRunInstanceAsync, CancelAsync, ExportStateAsync and ImportStateAsync methods.
* Refactor DispatchWorkflowInstance in MassTransitWorkflowDispatcher
The DispatchWorkflowInstance model in the MassTransitWorkflowDispatcher has been refactored. Previous detailed activity parameters (ActivityId, ActivityNodeId, ActivityInstanceId, ActivityHash) were replaced with a single ActivityHandle property. An additional Properties field was added.
* Update test in BulkDispatchWorkflowsTests
The DispatchAndWaitWorkflow test case in the BulkDispatchWorkflowsTests has been updated to use the new workflow client creation and instance running methods. Necessary namespace imports have also been added in the process to support the changes.
* Remove snapshot and persistence functionality from WorkflowInstanceImpl
This commit eliminates snapshot creation and persistence from the WorkflowInstanceImpl class. Methods related to these processes have been removed, including SaveSnapshotAsync(), ApplySnapshot(), and GetState(). This has also impacted the constructor and OnStarted() method where certain calls were made related to persistence. The need to manage and recover state asynchronously was eliminated, simplifying the implementation.
* Refactor workflow client implementations and update WorkflowStateMapper
Workflow clients in the modules Elsa.Workflows.Runtime and Elsa.ProtoActor have been refactored for better maintainability and readability. The WorkflowStateMapper in the Elsa.Workflows.Management is updated to include an "Apply" method, splitting the mapping functionality into smaller, more manageable methods. Also, usage of the Azure Service Bus Module in Elsa.Server.Web has been turned off.
* Update BulkDispatchWorkflowsTests specification
This commit updates the test specification in BulkDispatchWorkflowsTests by removing an unnecessary import and updating the WorkflowDefinitionHandle in the DispatchAndWaitWorkflow test method. Also, superfluous comments have been removed for readability.
* Update workflow definition in BulkDispatchWorkflowsTests
Changed the referenced workflow definition in the test scenario from EmployeeGreetingWorkflow to GreetEmployeesWorkflow. This update reflects more precise naming in our component tests for the BulkDispatchWorkflows scenario.
* Refactor BulkDispatchWorkflows and simplify error handling
The BulkDispatchWorkflows class in Elsa Workflows Runtime module has been refactored to simplify it. The detailed error handling with a list of errors has been removed and it is now directly dispatching child workflows without checking for a successful dispatch. The ProcessItem method has been removed which handled the errors previously, and the DispatchChildWorkflowAsync method no longer returns a dispatch response. This substantially simplifies the code and reduces its complexity.
* Update workflow runtime and distributed locking configuration settings
In the web server settings, the workflow runtime was changed from 'Distributed' to 'ProtoActor'. Also, the distributed lock provider setting has been moved into a new 'DistributedLocking' section in the configuration settings, allowing more detailed lock options to be set, including a lock acquisition timeout.
* Replace ProtoActor with DistributedRuntime in WorkflowServer
The current commit modifies our WorkflowServer configuration under our component tests. The "UseProtoActor" method which was previously used for runtime configuration has been commented out and replaced with "UseDistributedRuntime". This change suggests a shift towards a distributed runtime environment.
* Add new services and classes for workflow messaging
This commit adds new classes and services to facilitate workflow messaging. These include 'BroadcastWorkflowInboxMessageOptions', 'IWorkflowInbox', 'NewWorkflowInboxMessage', 'SubmitWorkflowInboxMessageResult', 'WorkflowInboxMessage', 'WorkflowInboxMessageDeliveryParams', and 'WorkflowInboxMessageFilter'. Additionally, changes were made in 'HttpWorkflowsMiddleware.cs' and 'WorkflowRuntimeFeature.cs' to use 'IWorkflowRunner' for executing workflows, and deprecated 'IWorkflowHostFactory' and 'WorkflowInvoker'. The messaging-related classes provide methods and properties to manage and manipulate workflow messages, delivery options and results. 'IWorkflowInbox' provides an interface for delivering messages to workflow instances while 'IWorkflowRunner' fulfills running workflows.
* Refactor WorkflowCancellationService for cleaner syntax
Aesthetic adjustments were made to the WorkflowCancellationService code to improve readability and maintainability. This includes tidying up line breaks, reformatting lists, correcting spelling in comments, and consolidating parameters in a function call.
* Remove unused import in MassTransitWorkflowCancellationDispatcher
The 'Elsa.Workflows.Runtime.Contracts' namespace was removed from the MassTransitWorkflowCancellationDispatcher file because it was not being utilized. This ensures a clean and efficient codebase by removing unnecessary imports.
* Remove Class1 from Elsa.Testing.Shared.Component
This commit deletes Class1.cs as it was no longer serving any purpose in the Elsa.Testing.Shared.Component. This removal helps keep the codebase clean and maintainable.
* Reduce default timeout in ISignalManager interface
The default millisecond timeout for the WaitAsync functions in the ISignalManager interface has been reduced from 5000ms to 1000ms. This change will speed up signal wait times in our testing framework.
* Refactor syntax representation in SendMessage activity
Simplified the syntax representation in the SendMesssage activity in the Elsa Azure Service Bus module. The SupportedSyntaxes property now utilizes a more concise array initialization.
* Removed obsolete 'Stimulus' property and adjusted consumers
The 'Stimulus' property in DispatchResumeWorkflows and DispatchTriggerWorkflowsRequest classes has been removed as it was marked obsolete. The DispatchWorkflowRequestConsumer has been adjusted to only use the 'BookmarkPayload' property. This ensures a cleaner code base and removes potential confusion between the properties.
* Rename GetNamedWorkflowGrain to GetNamedWorkflowInstanceClient
The method name GetNamedWorkflowGrain in both ProtoActorWorkflowClient and ClusterExtensions has been renamed to GetNamedWorkflowInstanceClient to improve code clarity. This change provides better semantics of what the function is purposed for.
* Remove unused snapshot classes
The commit removes the WorkflowGrainSnapshot and WorkflowInstanceGrainSnapshot classes from the Elsa.ProtoActor module. These classes were part of an older architecture and are no longer required.
* Remove unused field from Azure ServiceBus Worker
The _refCount field in the Worker class from the Azure ServiceBus module was unused. To maintain a clean codebase and improve readability, this field has been removed.
* Remove WorkflowInboxMessageRecord from Elsa.Dapper module
The commit includes the deletion of the entire WorkflowInboxMessageRecord class from Elsa.Dapper module. This file was managing various activities related to the workflow inbox messages, such as delivering messages to a workflow instance.
* Add new V3_2 migrations for all database providers
This commit introduces new V3_2 migrations for MySQL, SQLite, PostgreSQL, and SQLServer database providers. Included are `Up` and `Down` migrations, the corresponding Designer files, and specific Alterations and Runtime changes. SqlDbType specifications were also added for each.
* Refactor code and update namespaces in multiple modules
The changes update the namespaces of various files and refactor code for efficiency and readability. In addition, some unnecessary comments and redundant namespaces were removed, and import statements were corrected. Functions were also simplified by removing unneeded parameters and streamlining logic.
* Refactor namespace from Elsa.Tenants.Contracts to Elsa.Tenants
The refactor operation includes the removal of 'Contracts' from the namespace under the Elsa.Tenants module. This modification affects several files across different modules where the namespace is being referenced. In addition, a new folder for Multitenancy scenarios was created in the Elsa.Workflows.ComponentTests project.
* Remove V3_2 database migration files
The commit includes removal of EntityFrameworkCore database migrations files across various databases such as MySql, PostgreSql, Sqlite, SqlServer etc. The V3_2 migration files were presumably outdated, unnecessary or causing issues in the project.
* Add TenantId field and index to various tables
This update adds a new 'TenantId' column to several tables in the database including 'WorkflowExecutionLogRecords', 'Triggers', 'KeyValuePairs', 'Bookmarks', and 'ActivityExecutionRecords'. It also creates indices for this new column in each corresponding table. This enhancement is added across various database types including MySQL, SQL Server, SQLite and PostgreSQL.
* Added TenantId column to multiple tables
In the database migration script, the "TenantId" column has been added to the Triggers, Bookmarks, WorkflowExecutionLogRecords, ActivityExecutionRecords, and KeyValuePairs tables. Also, the process of removal of the same column from these tables has been scripted for rollback scenarios.
* Update migration version number in V3_2.cs
The commit contains an update in the version number of the migration Elsa:Runtime:V3.2 in V3_2.cs file. The previous version was 20002; it has now been updated to 20003.
* Add tenantID support to workflow builder
The update introduces tenantID support to the workflow builder. This allows workflows to be associated with different tenants, improving the multi-tenant support. The changes include adding a `TenantId` property and a `WithTenantId` method, and adjusting the workflow identity creation to include the tenant ID.
* Add tenant functionality to WorkflowServer
The WorkflowServer now supports multi-tenancy. Added `UseTenants` extension method where new TestTenantsProvider is configured which will provide multiple tenants. A TenantResolutionStrategy is appended to tenant options to decide the tenant context in runtime. Also, `ITenantResolutionStrategy` is registered in the dependency injection container.
* Add multitenancy tests and utility classes
Added test scenarios for multitenancy in the Elsa workflow component. Utility classes for tenant resolution strategy and tenants provider are also added to help perform the tests. Different workflows for different tenants are set up for testing.
* Handle OperationCanceledException in BackgroundEventPublisherHostedService
An additional catch block has been added to handle OperationCanceledException within the BackgroundEventPublisherHostedService. This provides a more specific message when an operation is cancelled during the queue processing.
* Refactor WorkflowDefinitionFilter and update related modules
Empty lines were removed between property declarations to improve readability in WorkflowDefinitionFilter. An error where 'filter.IsReadonly' was used instead of 'IsReadonly' was also corrected to ensure proper functionality. Additionally, WorkflowDefinitionFilter was imported in the Delete and Revert endpoint modules of the Elsa.Workflow.Api class to maintain consistency across the codebase.
* Change MongoUserStore to non-abstract class
The MongoUserStore class was previously tagged as an abstract class in the Identity module of Elsa.MongoDb. This update changes the MongoUserStore class from an abstract to a non-abstract (concrete) class to enable direct instantiation.
* Add ForwardedType attribute and update bookmarks
This commit introduces a new `ForwardedType` attribute to aid in forwarding types to new types when deserializing JSON. Additionally, the existing bookmarks related to workflow runtime activities have been updated. These changes also require modifying the `PolymorphicSerializer` in the Elsa.MongoDb project to handle types using the new `TypeHelper.GetLatestType` method.
* Correct typos in code comments
Fixed typographical errors in comments of the "JobId" property in both BackgroundActivityStimulus and BackgroundActivityBookmark classes. This minor change ensures accuracy and clarity in the code documentation.
* Refactor Workflow API by altering import statements
This commit modifies the import statements in various files under the Workflow API endpoints. Most changes involve replacing Elsa.Workflows.Management.Contracts import with Elsa.Workflows.Management. This refactoring ensures the correct classes and interfaces are used from the updated module path. Few methods have additional parameters added as well, enhancing their functionality.
* Implement DefaultTenantResolver and update tenant resolution logic
This commit introduces a new DefaultTenantResolver class which always returns the default tenant. The previous TenantResolver is renamed to PipelinedTenantResolver. The ITenantResolver interface has also been moved to a more general namespace. All services using ITenantResolver are updated accordingly. Furthermore, TenantResolverFeature is now a dependency of WorkflowsFeature.
* Fix logger reference in exception handling
The logger reference used in the catch block of the DefaultTriggerScheduler.cs file was incorrect. This commit corrects it by using the appropriate logger variable for logging any potential cron expression format errors.
* Refactor ElsaDbContextBase constructor and remove unused usings
Removed unnecessary using directives and modified the `ElsaDbContextBase` constructor. Introduced `IServiceProvider` dependency to the constructor and removed `SaveChangesAsync` method. Also, a set of `ModifiedEntityStates` was added.
* Add async SaveChangesAsync method in ElsaDbContextBase
An override for the SaveChangesAsync method has been added to the ElsaDbContextBase class. This method ensures OnBeforeSavingAsync is called prior to the base.SaveChangesAsync method, allowing for pre-save operations to be queued and executed asynchronously.
* Add Identity module to Workflow Server configurations
The Identity module from Elsa.EntityFrameworkCore is now added to the Workflow Server configurations in both Elsa.Workflows.ComponentTests and Elsa.AzureServiceBus.ComponentTests projects. This module is configured to use Entity Framework Core with PostgreSQL as a data provider.
* Replace key with ID in key-value pair handling
The key identifier from various key-value pair references has been replaced with ID in several modules, as reflected in the recent code changes. The 'Key' field was removed in the SerializedKeyValuePair class, related entity configurations, and multiple store methods. It's expected to improve the consistency of data identification across different components in the application.
* Remove unnecessary code and refactor namespace usage
Deleted the obsolete DictionaryExtensions.cs file, and did extensive refactoring of namespace usage. Some classes have been moved to new namespaces while others have been removed. Also removed methods that were not used or duplicated elsewhere in the codebase.
* Update import in AzureServiceBusServiceCollectionExtensions
The import in AzureServiceBusServiceCollectionExtensions test file was changed. Elsa.Extensions was used instead of Elsa.Workflows.ComponentTests, adjusting the dependencies for the test configuration.
* Remove outdated migrations for Elsa.EntityFrameworkCore
This commit removes old migration files pertaining to different databases in the Elsa.EntityFrameworkCore module. These outdated migrations versioned as 'V3_2' are no longer necessary in the current context of the application. The removal helps to keep the codebase cleaner and easier to manage.
* Update migration scripts and include in Elsa solution
Deleted previous versions of migration scripts and created new versions for EFCore 3.0, 3.1, and 3.3. These scripts have been included in the Elsa.sln, to facilitate regular and consistent updates of database schemas across various provider types (MySQL, SqlServer, Sqlite, PostgreSQL).
* Add TenantId to multiple tables and remove WorkflowInboxMessages table
The commit introduces a new TenantId column to several tables including WorkflowExecutionLogRecords, Triggers, KeyValuePairs, Bookmarks, and ActivityExecutionRecords in different database providers (MySql, PostgreSql, SqlServer, Sqlite). The changes will allow isolating data based on tenant ids. This commit also removes the WorkflowInboxMessages table which is not needed anymore.
* Add PostgreSQL support to workflow servers
The code includes additional extensions to Elsa workflow server configurations. The changes involve the alteration modules, enabling them to use EntityFrameworkCore with PostgreSQL. This was applied in two workflow servers for component testing, i.e., Elsa.Workflows.ComponentTests and Elsa.AzureServiceBus.ComponentTests.
---------
Co-authored-by: jeanbaptistedalle <jean-baptiste.dalle@laposte.net>
Co-authored-by: Jean-Baptiste Dalle <jean-baptiste.dalle@stereograph.fr>
Co-authored-by: Steve Taylor <stevetayloruk@users.noreply.github.com>
* Add caching to workflow runtime and workflow management stores
The update introduces caching to workflow runtime and workflow management stores to enhance performance. This is achieved by adding decorators for several stores, which cache records to reduce database fetches. Additionally, a signaler for change tokens allows for cache invalidation when changes occur. The MemoryCache feature has also been updated to include Scrutor for decoration and the caching duration can be configured through the new CachingOptions class.
* Refactor WorkflowsMiddleware for HTTP Endpoint bookmarks and triggers
The WorkflowsMiddleware has been extensively refactored to handle HTTP Endpoint bookmarks and triggers. This involves breaking down the InvokeAsync method by extracting parts of its functionality into separate helper methods such as FindTriggersAsync and FindBookmarksAsync. Moreover, Assist with authorization checks, workflow execution within request timeout, and handling of workflow faults has been improved to be more efficient and clearly segmented.
* Update HTTP endpoint authorization to use Workflow context
The authorization process in the AuthenticationBasedHttpEndpointAuthorizationHandler class has been updated to use the Workflow context instead of the WorkflowInstanceId string. The AuthorizeHttpEndpointContext model has been correspondingly changed to include a Workflow property, thereby strengthening the link between authorization and specific workflows.
* Add FindAsync methods to trigger and bookmark stores
The code adjustments add new FindAsync methods to the trigger and bookmark store contracts as well as all their concrete implementations (MongoDb, Memory and EFCore). These methods support fetching the first record matching a given filter. The adjustments also include minor syntax improvements and the addition of [UsedImplicitly] attributes where needed.
* Refactor WorkflowsMiddleware for improved workflow handling
The code was refactored to simplify the flow of handling workflows in the WorkflowsMiddleware class. Specifically, the methods to start and resume a workflow have been extracted to improve code readability. Further, handleErrorMiddlewares was also updated to better manage instances where no valid workflows or base paths are found.
* Add caching functionality to WorkflowsMiddleware
Added IMemoryCache usage in the WorkflowsMiddleware to cache lookup results for workflows and their associated triggers. This will reduce the number of database operations required when searching for workflows, thus improving performance. The cache is maintained for one minute before it is refreshed.
* Implement dynamic cache duration for workflows
The code has been updated to have a dynamic cache duration for the workflows instead of a hardcoded one minute. By using the CachingOptions service, the cache duration can now be set in the configuration making it more flexible and adaptable to different performance needs.
* Add HttpWorkflowsCacheManager for caching HTTP workflows
This commit includes the implementation of IHttpWorkflowsCacheManager for caching of HTTP workflows. New handlers have been added to invalidate cache on workflow updates. Additionally, WorkflowsMiddleware has been renamed to HttpWorkflowsMiddleware.
* Refactor workflow trigger handling and caching
The refactoring includes deletion of `IndexWorkflowTriggersHandler.cs` and creation of `IndexTriggers.cs` thus revising the workflow trigger indexing approach. Also, revamped the `ITriggerIndexer` interface which now handles deletion of triggers with specific workflow and filter. Furthermore, the caching mechanism in `HttpWorkflowsCacheManager.cs` is modified to handle eviction of workflow definitions and triggers separately boosting its efficiency.
* Add summary to IndexedWorkflowTriggers
A summary has been added to the 'IndexedWorkflowTriggers' class, providing a brief description. This description outlines that it represents a collection of indexed workflow triggers, promoting clearer understanding for future reference.
* Refactor memory caching feature into separate module
This commit separates the memory caching feature from the Elsa.Common module into a distinct Elsa.Caching module. This includes moving and renaming related files, such as the MemoryCacheFeature class and associated dependencies. The references in other modules and in the main solution file have been updated accordingly to include the new Elsa.Caching module.
* Add distributed caching and update async methods
Introduced a distributed caching feature with extensible change token signal publishing. Updated various cache-related methods to be asynchronous for improved performance and responsiveness. Also updated some workflow identity references for clarity.
* Add distributed caching with MassTransit support
This addition includes the implementation of a distributed caching system with MassTransit transport. The changes introduce necessary interfaces and services, new distributed caching feature along with the support for MassTransit as a transport option. Moreover, the instance management feature has been renamed to clustering feature for better clarity.
* Refactor queue naming and scope of MassTransitChangeTokenSignalPublisher
Queue name construction is adjusted in the RabbitMqServiceBusFeature and AzureServiceBusFeature modules for better organization and readability. MassTransitChangeTokenSignalPublisher is now a singleton service, ensuring the signal publisher can be shared across the application, increasing efficiency and performance. Also, introduced use of DistributedCacheFeature in MassTransitDistributedCacheFeature module for better modularization.
* Add caching capabilities to workflow definition service
This commit introduces caching to the workflow definition service, improving the performance for retrieving workflow definitions. 4 new classes have been created (`CachingWorkflowDefinitionService`, `EvictWorkflowDefinitionServiceCache`, `WorkflowDefinitionCacheManager`, and `IWorkflowDefinitionCacheManager`), and several existing classes have been updated to support caching. The caching also includes invalidation mechanisms, ensuring data consistency.
* Refactor caching mechanism in workflow definition
In the workflow definition module, the explicit caching functionality related to workflow definition versioning has been removed in favor of a more streamlined approach. Additionally, the manner in which services are registered has been altered. As a result, the caching now directly involves the overall workflow definition rather than individual versions, simplifying the caching logic and potentially improving the performance.
* Update MassTransitBroker and enable RealTimeWorkflows and SignalRHubs
The MassTransitBroker has been updated to Memory from RabbitMq. In addition, the RealTimeWorkflows and UseWorkflowsSignalRHubs features are now enabled in the code. This change will impact how the service communicates and processes real-time requests for workflow operations.
* Reformat variable types in HttpFeature
The reformatting involves a list of variable types in the HttpFeature module. Each type now appears on a new line for improved readability, making the code easier to maintain and review.
* Update HTTP workflows cache invalidation handler XML comment
* Remove unnecessary using directives
Unnecessary using directives were deleted across several files in the Elsa.Http module. This simplifies the code and will possibly improve execution speed. Specific deletions include those for Encoding, Unicode, Extensions, Collections.Generic, Linq, Text, and Tasks namespaces.
* Refactor HttpWorkflowsMiddleware constructor
This commit simplifies the HttpWorkflowsMiddleware class constructor. It removes the intermediary variables `_next` and `_options` and directly uses the passed arguments in the constructor. Now, the `next` and `options` parameters are used directly throughout the middleware.
* Simplify workflow retrieval in HttpWorkflowsMiddleware
This refactoring replaces the use of FindWorkflowDefinitionAsync and MaterializeWorkflowAsync with a single method, FindWorkflowAsync. This simplifies the middleware code and likely improves performance by reducing the number of database queries or service calls required to retrieve a workflow.
* Refactor workflow retrieval in HttpBookmarkProcessor
Simplified the workflow retrieval process in HttpBookmarkProcessor.cs. Replaced FindWorkflowDefinitionAsync and MaterializeWorkflowAsync methods with a single FindWorkflowAsync call. This reduces the complexity and improves efficiency in retrieving workflow.
* Optimize FindWorkflowAsync method in HttpWorkflowsCacheManager
Removed redundant lines of code to simplify workflow search functionality. This change simplified the FindWorkflowAsync method by directly calling the FindWorkflowAsync function in the workflowDefinitionService, thus increasing code readability and efficiency.
* Refactor Endpoint.cs for workflow retrieval
The method for obtaining a workflow in the Endpoint.cs script has been refactored and streamlined. The 'GetWorkflowDefinition' method is replaced by the 'GetWorkflowAsync' method which directly retrieves the workflow, without the intermediate step of materializing the workflow definition. This shortens the code and simplifies the process.
* Refactor InputFunctionsDefinitionProvider constructor
The constructor for InputFunctionsDefinitionProvider has been simplified by removing unnecessary private fields. Services are now directly used in the method instead of being stored in fields. This improves readability and reduces complexity in the class structure.
* Refactor WorkflowInstance with improved state handling
Simplified the methods for handling workflow and workflow state in the WorkflowInstance class. The refactoring also included some code clean-ups and variable renaming. The new implementation provides better readability and maintainability of the code by reducing unnecessary lines and improving structuring of objects and responses.
* Remove unused IBookmarkManager and update workflow functions
IBookmarkManager from ProtoActorWorkflowRuntime.cs file is removed due to its redundant status. Additionally, the "FindAsync" method has been updated to use a cancellation token. Also, annotations were added to the "ExportWorkflowStateAsync" and "ImportWorkflowStateAsync" methods to flag calls to functions that require unreferenced code.
* Remove unused ReSharper directive
Unused ReSharper directive in the file IndexTriggers.cs was identified and therefore removed. This change makes the code cleaner and easier to read.
* Update activity invocation in workflow runtime
Updated the DefaultBackgroundActivityInvoker service in the Elsa.Workflows.Runtime module to annotate the ExecuteAsync method with "RequiresUnreferencedCode" attribute. This change is made considering the potential code trimming issue. Additionally, simplified the process of fetching workflow by directly using FindWorkflowAsync method instead of FindWorkflowDefinitionAsync and MaterializeWorkflowAsync methods.
* Refactor code to simplify workflow definition loading
The code for finding and materializing workflow definitions has been simplified. Instead of loading the definition and materializing it into a workflow in separate steps, a new method called FindWorkflowAsync has been introduced to perform both actions at once. This reduces redundancy and makes the code more readable.
* Refactor WorkflowHostFactory to streamline workflow creation
This commit simplifies the workflow creation process in WorkflowHostFactory. It removes redundant code and extraneous methods, specifically the overloaded CreateAsync method which used WorkflowDefinition. Now, it directly finds and uses the Workflow instance, thereby simplifying the code base and improving maintainability.
* Refactor workflow retrieval in WorkflowInstance.cs
Changed the way workflow instances are retrieved from the WorkflowDefinitionService. Instead of obtaining the workflow definition and then materializing the workflow from it, the workflow is directly retrieved using the FindWorkflowAsync function. This simplifies the code and avoids unnecessary null-checks.
* Remove unnecessary whitespace in WorkflowInstance.cs
An extraneous whitespace character was identified and removed in the WorkflowInstance.cs file. This change contributes towards maintaining clean and readable code in the Elsa.ProtoActor module.
* Remove unnecessary comment in ProtoActorWorkflowRuntime
The unnecessary comment ("Load the workflow definition.") in the method TryStartWorkflowAsync of the ProtoActorWorkflowRuntime.cs file was removed. This is part of an ongoing effort to keep the codebase clean and readable.
* Update workflow management features and handlers
Added explicit notification handlers for DeleteWorkflowInstances and RefreshActivityRegistry in WorkflowManagementFeature.cs. Also, renamed RefreshActivityRegistryHandler.cs to RefreshActivityRegistry.cs for better clarity.
* Add multiple log record support to workflow execution log stores
The major change of this commit is the addition of methods to add multiple log records in the WorkflowExecutionLogStore, across different storage modules such as EntityFramework, MongoDB, Dapper, Elasticsearch and Memory. This ensures consistency and uniform behavior across different storage types. Furthermore, some reformatting and tidying up of the code were undertaken to maintain readability and clarity.
* Remove redundant workflow definition check
The workflow definition existence check and related service retrieval were removed from HttpWorkflowsMiddleware.cs. It was determined that this check was unnecessary as the workflow definition's existence is guaranteed at this point in the process, reducing redundancy in the code.
* Improve cancellation token usage in workflow execution
This commit refines the usage of cancellation tokens during the execution of workflows in Elsa.Server and HttpWorkflowsMiddleware. Previously, a cancellation token pair was created before ExecuteWithinTimeoutAsync was called, which limited duration control solely to that method. Now, cancellation tokens are included within ExecuteWithinTimeoutAsync method. This allows the method to observe any cancellation initiated by outer scopes, enhancing control over the timeout of operations.
* Add PersistStateAsync method to WorkflowHost
A new PersistStateAsync method has been added to the WorkflowHost, which enables the host to directly persist its own state. The method has been integrated into the DefaultWorkflowRuntime and HttpWorkflowsMiddleware. This update eliminates the need to continuously get instances of IWorkflowInstanceManager to save state, which improves efficiency and code readability.
* Refactor DefaultAlterationRunner service
This update simplifies the DefaultAlterationRunner service, reducing the number of code lines and removing unnecessary references. The workflow materialization step has been merged with the find workflow step, and unused namespaces have been dropped.
* Refine wording in IWorkflowHost interface documentation
The documentation for the 'CanStartWorkflowAsync' method in the IWorkflowHost interface has been cleaned up. The superfluous "or not" verbiage has been removed, making it easier to understand the method's function.
* Remove CancellationTokens struct and simplify cancellation handling
Removed the CancellationTokens struct and all its references across the code base. Simplified cancellation handling by using standard CancellationToken only. Also cleaned up redundant usages and unnecessary namespaces across various modules. This simplification better aligns with standard .NET conventions and reduces the code complexity.
* Implement ActivityHandle for better activity identification
The ActivityHandle class has been introduced to consolidate various activity identification parameters such as ActivityId, ActivityNodeId, ActivityInstanceId, and ActivityHash. This makes it easier to track and manage activities by reducing the number of parameters needed for identification. Adoption of ActivityHandle has been implemented across the codebase.
* Remove AzureContainerApps related code
This commit includes the removal of all the AzureContainerApps associated code from the ProtoActor Cluster. The deletion includes multiple files which had housed the AzureContainerApps cluster provider and all its supporting services, util functions, options, contracts, and models. This move might be towards refactoring the structure or removal of unwanted dependencies.
* Add distributed execution runtime and client
Removed some unused classes and created a distributed execution runtime using distributed locking and persistence. Introduced an interface for workflow clients and implemented two versions, a local one and one using `Proto.Actor`. Made some changes in other modules to add the necessary interfaces and methods. Also, added `DistributedLockingRuntime` module to implement distributed execution.
* Remove WorkflowClient.cs from Elsa.Workflows.Runtime
The WorkflowClient.cs file was removed from the Elsa.Workflows.Runtime project. It held placeholder methods that had not yet been implemented, making it unnecessary in the current codebase.
* Add ProtoActor implementation for workflow execution
Added ProtoActor implementation for executing workflow instances. This includes ProtoBuf message definitions, grain interfaces and implementations, and various ProtoActor services. Extended WorkflowHost and related components to provide more execution details in order to better support distributed processing via ProtoActor.
* Refactor workflow parameters to workflow requests
The refactor includes renaming old 'WorkflowParams' classes to 'WorkflowRequest' to better represent their usage. The changes have been made across all the involved modules ensuring that the project maintains consistency. New properties, methods, and class names were updated accordingly.
* Add ProtoActor implementation for data mappers
This update adds the ProtoActor implementation for data mappers and updates the DI configuration accordingly. It also updates the client interfaces for a more streamlined usage, and refactors the WorkflowHost to adapt to these changes. All changes were implemented in accordance with the new bookmark information model.
* Add functionality to create a new workflow instance
This commit introduces the capability to create a new workflow instance in the Elsa Workflow Runtime by enhancing existing workflow classes and creating the WorkflowClientFactoryExtensions class, in addition to adding the "IsNewInstance" parameter to multiple workflows and requests. It provides more flexibility in managing workflow instances and aids in building workflow processes that require instantiation of a new workflow.
* Remove Elsa.Runtimes.DistributedLockingRuntime module
This commit deletes the Elsa.Runtimes.DistributedLockingRuntime module from the project. Changes include removed code files related to features, services and commands under this module. The Elsa.sln file has been updated to reflect these changes, excluding the removed module from the solution.
* Add dynamic client type to WorkflowClientFactory
The WorkflowClientFactory now accepts a client Type parameter for dynamic client creation. This enables the factory to create different subclasses of IWorkflowClient based on the provided Type. The CreateClient function is updated in the WorkflowClientFactoryExtensions and IWorkflowClientFactory interface, and applied in HttpWorkflowsMiddleware.
* Implement Proto.Actor support in Elsa
A comprehensive change that introduces support for Proto.Actor clustering to Elsa. It includes a redesign of the workflow client invocation model, transitioning the methods from synchronous to asynchronous. Also, modification to the Proto.Actor-based 'WorkflowGrain' was made to handle state recovery and execution processing. The structural enhancements improve scalability and performance capabilities.
* Refactor null-checks in SaveSnapshotAsync method
Simplified the null-checking in the method SaveSnapshotAsync within WorkflowGrain.cs. The check on _workflowHost and workflowState has been shortened using conditional access operator, improving the code readability.
* Refactor code and update packages
The codebase has undergone a major refactoring to improve code readability and consistency, with non-essential methods being removed and variable names being optimized for clarity. Package references for Proto.Actor and related packages have been also updated to the latest versions.
* Add Proto.Cluster.AzureContainerApps package to Directory.Packages.props
The Proto.Cluster.AzureContainerApps package with version 1.6.0 has been included in the Directory.Packages.props file. This addition extends the range of Proto.Cluster packages used in the project.
* Remove redundant Proto.Actor implementation files
This commit removes several redundant files related to the Proto.Actor implementation. These files were unnecessary and were cluttering up the codebase. With this removal, the project has become leaner and easier to maintain. It also eliminates potential confusion for future developers working on this project.
* Add WorkflowMatcher and replace BookmarkHasher with StimulusHasher
This commit introduces a new class, WorkflowMatcher, which represents a contract for finding triggers and bookmarks associated with workflow activities. It also renames and replaces all instances of BookmarkHasher with StimulusHasher to reflect a more accurate function relating to stimulus rather than bookmarks. Other necessary changes were made to ensure consistency with these updates across different classes. It's important to note that WorkflowInbox interface is now marked as obsolete.
* Incremental work on stimuli refactoring
* Refactor codebase to support new IWorkflowInvoker and invoke workflow logic
Multiple files updated to introduce a `IWorkflowInvoker` interface, implementation and supporting classes. This simplified how workflows are instantiated and invoked. Consequently, necessary adjustments made across multiple entities and endpoints to account for the updated invocation procedure. Old logic related to counting running workflows removed. Introduced stimulus concept while deprecating non-compliant classes and methods.
* bumped versions to fix dependency vulnerabilities (#5256)
* Update patch version in GitHub workflows
The version number used in the branch checking step of the GitHub workflows has been updated. Instead of scanning for the branch containing the patch version 3.1.2, it now scans for the branch that contains version 3.1.3. This change is aligned with the updated product version.
* Update git branch grep pattern in workflow file
The git grep pattern has been corrected to properly identify tagged versions in the GitHub Actions workflow. The correction ensures that the workflow script fetches the right branches as per the release tag instead of patch.
* Update grep command in packages workflow
The grep command used in the 'packages.yml' GitHub workflow was previously looking for the exact 'refs/tags/3.1.3' string. This commit simplifies the command by making it only look for '3.1.3'. This adjustment will streamline the process and potentially prevent issues with branch recognition.
* Update package versions and refactor code for Elasticsearch and JavaScript modules
Updated versions of numerous packages in the Directory.Packages.props file to their latest stable releases. This includes updates to Elasticsearch, JavaScript, and MongoDB packages among others. Additionally, refactored parts of the code in the WorkflowInstanceConfiguration and JintJavaScriptEvaluator within the Elasticsearch and JavaScript modules, respectively, to improve index management and script preparation. The WorkflowInstanceStore also saw a minor adjustment.
* Refactor workflow management with workflow definition handles
The existing workflow management has been significantly refactored, introducing the concept of "Workflow Definition Handles". These handles allow for consistent management whether we're dealing with a specific workflow definition, a version of a definition, or more flexible version constraints. This refactor also adjusts how workflow instances are created, now using a more intuitive and detailed "WorkflowInstanceOptions" approach.
* Add ResumeBookmarkResult and update related methods
Implemented a ResumeBookmarkResult class to handle bookmark resumption results. Methods related to resuming bookmarks have been refactored to return this new class, providing more information such as bookmarks' matched state. Also, some methods were optimized to break the loop early if no bookmarks were found, improving code efficiency.
* Update workflow definition, execution and correlation
This commit focuses on enhancements and adjustments to workflow definition and execution. Notable changes include the addition of ExecuteResponse model and new test workflow scenarios. Refactoring has been performed to improve readability and efficiency in various components. It also includes an important fix for the correct application of WorkflowDefinition filters, primarily using both DefinitionId and DefinitionVersionId for more accurate results.
* Refactor runtime codebase for better structure and workflow control
This commit involves changes to functionally reorganize the runtime codebase for improved structure. It also allows for better handling of workflows, particularly through the addition of original bookmarks in the workflow execution context. Removed unnecessary dependencies and ensured more efficient management of bookmarks in the workflow running process. Several method and class names were also updated to better reflect their purpose.
* Refactor WorkflowInvoker and remove 'OriginalBookmarks'
Optimized the constructor of 'WorkflowInvoker' by using 'IServiceScopeFactory' to get instances of required services. Removed the 'OriginalBookmarks' property from 'WorkflowStateExtractor' and 'WorkflowState', a subsequent change included in 'WorkflowGraphBuilder' as well. Reorganized the namespaces in 'Elsa.Workflows.ComponentTests' project. Added 'UseCache' in WorkflowServer configurations.
* Removed RunWorkflowParams class
This update deletes the RunWorkflowParams class within the Runtime Requests of the Elsa.Workflows module. The class was no longer needed, hence the elimination and cleanup in the codebase.
* Update RunWorkflowParamsMapper to handle null or empty fields
This commit modifies the RunWorkflowParamsMapper in the Elsa.ProtoActor module. It primarily treats the BookmarkId and TriggerActivityId fields to return null if they are empty, boosting the application's robustness against potential null or empty field issues.
* Refactor workflow handling and improve null checks
In this update, the handling of workflows was refactored to improve efficiency. The 'RunAsync' method now correctly uses 'WorkflowGraph' as a parameter, instead of 'Workflow'. Additionally, null checks for 'bookmarkId' and 'activityHandle.ActivityInstanceId' have been improved to avoid null and empty strings. Finally, when '_workflowInstanceId' is null in the 'WorkflowGrain' class, it is now properly initialized by parsing the cluster identity.
* Enable ProtoActor in Elsa.Server.Web
This commit turns on the use of ProtoActor within the Elsa.Server.Web bundle. This switch may affect the system's behavior and performance.
* Added new workflow scheduling and management features
Implemented new features for creating, running, and scheduling workflow instances. The implementation added new files for handling workflow runtime and scheduling features, including creating and running a workflow instance request, a mapper for the request, and handler services. Modified files include updating method calls according to the new requests, updating workflow definitions, and adjustment to method arguments in Hangfire job class.
* Handle null or empty workflow instance IDs and correlation IDs
This commit introduces null checks for workflow instance IDs and correlation IDs in the workflow infrastructure. Previously, the code assumed that the IDs were provided. It now gracefully handles cases where they might be null or empty, preventing possible null reference exceptions and ensuring more robust workflow execution.
* Update mapping details in ResumeWorkflowJob
Removed unnecessary using statement for Elsa.Workflows.Runtime.Requests in ResumeWorkflowJob.cs. Updated references from DispatchWorkflowInstanceRequest to ScheduleExistingWorkflowInstanceRequest for retrieving ActivityHandle and WorkflowInstanceId.
* Refactor AzureServiceBus module and integrate into web project
In this commit, changes were made to the AzureServiceBus module to use Topic definitions for subscriptions. The Subscriptions property in the AzureServiceBusOptions and the Topic property in the SubscriptionDefinition class are marked as obsolete and suggestions to use TopicDefinition.Subscriptions instead have been added. The AzureServiceBus module was also integrated into the web project and configured to use options from the appsettings.json.
* Refactor code to use async scopes and improve service dependencies
Refactored code to use async scopes for improved task management. Also organized service dependencies better by moving service fetching inside methods where they are needed and propagating necessary dependencies through method parameters for cleaner code.
* Add Azure Service Bus workflow component tests
This commit introduces a set of workflow component tests for Azure Service Bus integration. These tests encompass scenarios like message receiving, sending messages with correlation IDS, and sending single messages. In addition, 'SignalResetEvent' test helper was removed, a new test helper 'TriggerSignal' was added, and a Mock ServiceBusClient and ServiceBusAdministrationClient were added to the WorkflowServer fixture. Lastly, the NSubstitute package was added to the test project's dependencies.
* Add support for deferred tasks in workflow execution context
Added support for deferred tasks in the workflow execution context. This implementation allows tasks to be deferred and executed right after persistence of bookmarks in the workflow. A new middleware, ExecuteDeferredActivityTasks, is introduced to handle the execution of these deferred tasks.
* Refactor TriggerSignal and SendMessage activity execution
Refactored the execution of TriggerSignal and SendMessage activities by using context.DeferTask to ensure the activities run asynchronously. Also, made code format modifications and simplifications such as handling ApplicationProperties better in the SendMessage activity, and other minor changes.
* Update workflow ID generation method
The workflow ID generation method has been updated in the WorkflowBuilder. Previously, it was always generated by _identityGenerator. Now, it only gets generated if the definitionId or Id is null or empty, otherwise it uses the existing value. This change brings the ID generation practice in line with how we handle definitionId.
* Add support for service bus testing in workflow tests
Two new helper classes, DictionaryExtensions and MockServiceBusProcessor, have been added to support mocking Azure service bus in workflow component tests. Also, the tests have been updated to use SignalManager to ensure proper order of execution. The WorkflowServer test fixture has been extensively refactored to create mock instances of service bus senders and processors. Furthermore, some configurations have been commented out and new configurations related to MemoryTriggerStore and MemoryBookmarkStore have been added.
* Enhanced workflow correlation and caching in Elsa Workflows
This update improves Elsa Workflows by enabling caching and enhancing correlation in Correlate.cs. It expands functionality by adding new methods that accept various input types and provide more options for activities correlation. Correlation improvements also extend to AzureServiceBusTests, which were updated to test workflow instances by correlation ID. Furthermore, the test workflow received a name change and new correlation mechanics based on Azure messaging.
* Renamed method argument from 'payload' to 'stimulus'
The method argument 'payload' in various functions across 'MessageReceived.cs' and 'ActivityExecutionContext.cs' files has been renamed to 'stimulus'. This change was made to improve code readability and understanding by using a more context-specific term.
* Refactor Workflow APIs and enhance logging
Refactored Workflow APIs by removing the TriggerActivityId from StimulusMetadata and introducing Direct Triggers. Refactored Reenter method in WorkflowGrain to be more concise and straightforward. Enhanced logging by adding additional logging in ActivityExecutionPipeline and LogLevel in appsettings. Also, updated ProtoActorFeature for better log level management.
* Refactor AzureServiceBusTests and add workflow completion signal
The AzureServiceBusTests class is refactored to separate and encapsulate concerns. SignalManager and WorkflowEvents are now class-level variables. Also, a signal to indicate the completion of a workflow is added. This allows the test to wait for workflow completion in the sequence of its operations. Additionally, the workflow definition ID in MessageReceivedTriggerWorkflow is now static and fixed, rather than dynamically derived from the class name.
* Refactor methods to streamline workflow creation and execution
The changes primarily consolidate the process of creating and running a workflow instance into a single operation. Specifically, the 'CreateAndRunWorkflowInstanceRequest' class is utilized in multiple modules to simplify and streamline the workflow creation process. Also, several redundant and inefficient methods were removed in the 'WorkflowGrain' module, and the remaining methods were updated to return the required response directly, resulting in cleaner, more efficient code.
* Refactor asynchronous serialization to synchronous
Simplified serialization by converting all asynchronous tasks in the workflow state serializer to synchronous ones. This change affects Elsa's Core, Dapper, EntityFrameworkCore, Management, and ProtoActor modules, as well as the Workflow State Serializer - switching all async workflow state serialization methods to their synchronous equivalents.
* Removed Elsa.ServiceBus.IntegrationTests project
The Elsa.ServiceBus.IntegrationTests project and all related files and references were removed from the solution. This update affects the main application and several workflow files, scenarios, and helper methods.
* Refactor WorkflowGrain and update ProtoActor timeouts
Renamed the Method OnStopped to async and replaced Context.Stop with Context.Poison in the Method Stop within the WorkflowGrain.cs. Also, adjusted the ActorRequestTimeout to a shorter duration and commented out the LegacyRequestTimeoutBehavior() in ProtoActorFeature.cs. These changes aim to enhance the efficiency and performance of the system.
* Refactor Workflow execution and ProtoActor interaction
This commit refactors the execution of workflows to manage re-entrancy and improve sequential calls. It also modifies the interaction model between ProtoActor grains and clients by following the ask-pattern. The ProtoWorkflowSubStatus enumeration has been extended to include a "Pending" state. The ActorRequestTimeout has been increased for better debugging.
* Remove unused queue and receive timeout in WorkflowGrain
The _executionQueue was initialized but never used in the WorkflowGrain class. This removal leads to cleaner and less confusing code. Additionally, the Context.SetReceiveTimeout method call has been removed from OnStarted method as it's no longer needed.
* Add ProtoActor to WorkflowServer runtime
In the WorkflowServer of Elsa Workflows Component Tests, the ProtoActor has been added to the runtime settings. This enhances the overall functionality and efficiency of the server.
* Add new component tests for Elsa.AzureServiceBus and remove old unit tests
In this commit, a new set of component tests for Elsa.AzureServiceBus have been added, providing more detailed and reliable testing. Simultaneously, several old unit test files and projects have been removed as they're no longer relevant or useful. These include tests in the 'Elsa.Workflows.Runtime.UnitTests1', 'Elsa.Activities.UnitTests' and 'Elsa.JavaScript.UnitTests' namespaces among others. The decision to remove these tests is motivated by the desire to streamline the testing process and focus on the most meaningful and reliable tests.
* Rename GlobalUsings.cs to Usings.cs in integration tests
Renamed the GlobalUsings.cs file to Usings.cs in the Elsa.Alterations.IntegrationTests project to better reflect its purpose. This change is intended to improve clarity within the codebase.
* Refactor Azure service bus testing setup to separate extension
This commit abstracts the setup for Azure service bus testing into a separate extension named AzureServiceBusServiceCollectionExtensions. The code has been removed from the WorkflowServer class, contributing to a cleaner and more modular codebase. This enhancement will facilitate better unit testing and reduce redundancy in test setup.
* Uncomment 'Description' and remove 'OptionsProvider' and 'OptionsMethod'
In the 'InputAttribute.cs' file, the 'Description' property has been uncommented to allow for a brief description of properties during workflow tooling. Furthermore, the 'OptionsProvider' and 'OptionsMethod' properties have been removed, simplifying the attribute options handling.
* Enable Azure Service Bus module
The change updates the 'useAzureServiceBusModule' constant from false to true in the Elsa.Server.Web Program.cs file. This adjustment allows the application to employ the Azure Service Bus module.
* Refactor ProtoActor module for workflow instance focus
The main changes in this commit revolve around renaming and refactoring to orient the ProtoActor module toward handling workflow instances. In the process, unnecessary imports have been removed, classes have been renamed to reflect their new focus on workflow instances, and various related elements such as protobuf files and services have also been renamed and refactored to align with these changes.
* Change AnalysisModeDocumentation to 'AllDisabledByDefault'
The AnalysisModeDocumentation setting in Directory.Build.props has been updated to 'AllDisabledByDefault' from 'Default'. This change disables all analysis by default in the documentation generation process.
* Update default value for Content and modify build properties
Modified the default value for the property 'Content' in the 'Message' class. Also updated the build properties by changing the 'AnalysisModeDocumentation' to "Default", disabling 'EnableTrimAnalyzer', and adding exception warning codes 'CS0162' and 'CS1591' to 'NoWarn'.
* Disable Azure Service Bus and initialize Customer fields
With this commit, the Azure Service Bus module usage has been turned off. In addition, the initial fields of the Customer entity have been set to their default values for safer initialization and to avoid potential null reference exceptions.
* Add distributed workflow services and configurations
Implemented basic functionalities in DistributedWorkflowClient and DistributedWorkflowRuntime. Updated Web Application 'Program.cs' to support different WorkflowRuntimes as per the configuration. Renamed WorkflowRuntimeFeature.cs to DistributedRuntimeFeature.cs and refactored the code accordingly. Removed unnecessary method 'UseDefaultWorkflowRuntime' from ModuleExtensions.cs.
* Refactor ReceivedServiceBusMessageModel from record to class
Converted ReceivedServiceBusMessageModel from a record to a class and updated relevant initialization code. Change was implemented because of the polymorphic serialization incabability of dealing with $type properties with records.
* Refactor WorkflowInstanceImpl for improved workflow management
This change refactors the WorkflowInstanceImpl class to improve workflow management. It implements queuing of RunWorkflowOptions while a workflow is running and ensures state before any workflow operations. Furthermore, workflow host creation is replaced with directly creating and managing workflow instances.
* Add DefaultFormattersFeature and update dependencies
A new feature, DefaultFormattersFeature, has been added to the Elsa.Common module. The WorkflowsFeature in the Elsa.Workflows.Core module has been updated to depend on this new feature. This will ensure that default JSON formatters are available across the application.
* Refactor JsonFormatter with JsonSerializerOptions property
Improved the JsonFormatter class by introducing a private JsonSerializerOptions property. The new implementation uses this property in the FromStringAsync method instead of initializing a new JsonSerializerOptions each time, improving efficiency. The JsonStringEnumConverter has also been moved to the class constructor.
* Refactor WorkflowInstanceImpl for improved code clarity
The refactor includes replacing direct field access with properties in multiple places for WorkflowGraph and WorkflowState. It also makes _queuedRunWorkflowOptions field readonly and removes unnecessary newline characters. These changes aim to improve readability, maintainability and encapsulation.
* Add and update methods to workflow instances
This commit introduces add and update functionalities to the workflow instances across the application. Additionally, it includes enhancements to the workflow execution, such as distributed locking and expanded logging capabilities for better debugging and tracking. Lastly, it introduces new configurations in application settings to fine-tune the workflow runtime environment.
* Refactor worker management in AzureServiceBus module
The codebase has been simplified by removing the unnecessary management of worker ref counts in the AzureServiceBus module. Previously, to manage worker instances, we kept a count of references to each worker and removed it when the count dropped to zero. This complexity has been entirely removed to make the module simpler and easier to maintain. Now we just create a worker when necessary, without tracking its usage across the codebase.
* Refactor workflow runtime with distributed locking and state checking
The workflow runtime has been refactored for better concurrency control and state management. The changes primarily include the introduction of distributed locking in action methods of the DistributedWorkflowClient and the handling of workflow instance states in the LocalWorkflowClient. This entails changes to the logic in the RunInstanceAsync, CreateAndRunInstanceAsync, CancelAsync, ExportStateAsync and ImportStateAsync methods.
* Refactor DispatchWorkflowInstance in MassTransitWorkflowDispatcher
The DispatchWorkflowInstance model in the MassTransitWorkflowDispatcher has been refactored. Previous detailed activity parameters (ActivityId, ActivityNodeId, ActivityInstanceId, ActivityHash) were replaced with a single ActivityHandle property. An additional Properties field was added.
* Update test in BulkDispatchWorkflowsTests
The DispatchAndWaitWorkflow test case in the BulkDispatchWorkflowsTests has been updated to use the new workflow client creation and instance running methods. Necessary namespace imports have also been added in the process to support the changes.
* Remove snapshot and persistence functionality from WorkflowInstanceImpl
This commit eliminates snapshot creation and persistence from the WorkflowInstanceImpl class. Methods related to these processes have been removed, including SaveSnapshotAsync(), ApplySnapshot(), and GetState(). This has also impacted the constructor and OnStarted() method where certain calls were made related to persistence. The need to manage and recover state asynchronously was eliminated, simplifying the implementation.
* Refactor workflow client implementations and update WorkflowStateMapper
Workflow clients in the modules Elsa.Workflows.Runtime and Elsa.ProtoActor have been refactored for better maintainability and readability. The WorkflowStateMapper in the Elsa.Workflows.Management is updated to include an "Apply" method, splitting the mapping functionality into smaller, more manageable methods. Also, usage of the Azure Service Bus Module in Elsa.Server.Web has been turned off.
* Update BulkDispatchWorkflowsTests specification
This commit updates the test specification in BulkDispatchWorkflowsTests by removing an unnecessary import and updating the WorkflowDefinitionHandle in the DispatchAndWaitWorkflow test method. Also, superfluous comments have been removed for readability.
* Update workflow definition in BulkDispatchWorkflowsTests
Changed the referenced workflow definition in the test scenario from EmployeeGreetingWorkflow to GreetEmployeesWorkflow. This update reflects more precise naming in our component tests for the BulkDispatchWorkflows scenario.
* Refactor BulkDispatchWorkflows and simplify error handling
The BulkDispatchWorkflows class in Elsa Workflows Runtime module has been refactored to simplify it. The detailed error handling with a list of errors has been removed and it is now directly dispatching child workflows without checking for a successful dispatch. The ProcessItem method has been removed which handled the errors previously, and the DispatchChildWorkflowAsync method no longer returns a dispatch response. This substantially simplifies the code and reduces its complexity.
* Update workflow runtime and distributed locking configuration settings
In the web server settings, the workflow runtime was changed from 'Distributed' to 'ProtoActor'. Also, the distributed lock provider setting has been moved into a new 'DistributedLocking' section in the configuration settings, allowing more detailed lock options to be set, including a lock acquisition timeout.
* Replace ProtoActor with DistributedRuntime in WorkflowServer
The current commit modifies our WorkflowServer configuration under our component tests. The "UseProtoActor" method which was previously used for runtime configuration has been commented out and replaced with "UseDistributedRuntime". This change suggests a shift towards a distributed runtime environment.
* Add new services and classes for workflow messaging
This commit adds new classes and services to facilitate workflow messaging. These include 'BroadcastWorkflowInboxMessageOptions', 'IWorkflowInbox', 'NewWorkflowInboxMessage', 'SubmitWorkflowInboxMessageResult', 'WorkflowInboxMessage', 'WorkflowInboxMessageDeliveryParams', and 'WorkflowInboxMessageFilter'. Additionally, changes were made in 'HttpWorkflowsMiddleware.cs' and 'WorkflowRuntimeFeature.cs' to use 'IWorkflowRunner' for executing workflows, and deprecated 'IWorkflowHostFactory' and 'WorkflowInvoker'. The messaging-related classes provide methods and properties to manage and manipulate workflow messages, delivery options and results. 'IWorkflowInbox' provides an interface for delivering messages to workflow instances while 'IWorkflowRunner' fulfills running workflows.
* Refactor WorkflowCancellationService for cleaner syntax
Aesthetic adjustments were made to the WorkflowCancellationService code to improve readability and maintainability. This includes tidying up line breaks, reformatting lists, correcting spelling in comments, and consolidating parameters in a function call.
* Remove unused import in MassTransitWorkflowCancellationDispatcher
The 'Elsa.Workflows.Runtime.Contracts' namespace was removed from the MassTransitWorkflowCancellationDispatcher file because it was not being utilized. This ensures a clean and efficient codebase by removing unnecessary imports.
* Remove Class1 from Elsa.Testing.Shared.Component
This commit deletes Class1.cs as it was no longer serving any purpose in the Elsa.Testing.Shared.Component. This removal helps keep the codebase clean and maintainable.
* Reduce default timeout in ISignalManager interface
The default millisecond timeout for the WaitAsync functions in the ISignalManager interface has been reduced from 5000ms to 1000ms. This change will speed up signal wait times in our testing framework.
* Refactor syntax representation in SendMessage activity
Simplified the syntax representation in the SendMesssage activity in the Elsa Azure Service Bus module. The SupportedSyntaxes property now utilizes a more concise array initialization.
* Removed obsolete 'Stimulus' property and adjusted consumers
The 'Stimulus' property in DispatchResumeWorkflows and DispatchTriggerWorkflowsRequest classes has been removed as it was marked obsolete. The DispatchWorkflowRequestConsumer has been adjusted to only use the 'BookmarkPayload' property. This ensures a cleaner code base and removes potential confusion between the properties.
* Rename GetNamedWorkflowGrain to GetNamedWorkflowInstanceClient
The method name GetNamedWorkflowGrain in both ProtoActorWorkflowClient and ClusterExtensions has been renamed to GetNamedWorkflowInstanceClient to improve code clarity. This change provides better semantics of what the function is purposed for.
* Remove unused snapshot classes
The commit removes the WorkflowGrainSnapshot and WorkflowInstanceGrainSnapshot classes from the Elsa.ProtoActor module. These classes were part of an older architecture and are no longer required.
* Remove unused field from Azure ServiceBus Worker
The _refCount field in the Worker class from the Azure ServiceBus module was unused. To maintain a clean codebase and improve readability, this field has been removed.
* Remove WorkflowInboxMessageRecord from Elsa.Dapper module
The commit includes the deletion of the entire WorkflowInboxMessageRecord class from Elsa.Dapper module. This file was managing various activities related to the workflow inbox messages, such as delivering messages to a workflow instance.
* Add new V3_2 migrations for all database providers
This commit introduces new V3_2 migrations for MySQL, SQLite, PostgreSQL, and SQLServer database providers. Included are `Up` and `Down` migrations, the corresponding Designer files, and specific Alterations and Runtime changes. SqlDbType specifications were also added for each.
* Refactor WorkflowDefinitionFilter and update related modules
Empty lines were removed between property declarations to improve readability in WorkflowDefinitionFilter. An error where 'filter.IsReadonly' was used instead of 'IsReadonly' was also corrected to ensure proper functionality. Additionally, WorkflowDefinitionFilter was imported in the Delete and Revert endpoint modules of the Elsa.Workflow.Api class to maintain consistency across the codebase.
* Change MongoUserStore to non-abstract class
The MongoUserStore class was previously tagged as an abstract class in the Identity module of Elsa.MongoDb. This update changes the MongoUserStore class from an abstract to a non-abstract (concrete) class to enable direct instantiation.
* Add ForwardedType attribute and update bookmarks
This commit introduces a new `ForwardedType` attribute to aid in forwarding types to new types when deserializing JSON. Additionally, the existing bookmarks related to workflow runtime activities have been updated. These changes also require modifying the `PolymorphicSerializer` in the Elsa.MongoDb project to handle types using the new `TypeHelper.GetLatestType` method.
* Fix logger reference in exception handling
The logger reference used in the catch block of the DefaultTriggerScheduler.cs file was incorrect. This commit corrects it by using the appropriate logger variable for logging any potential cron expression format errors.
* Refactor component tests and improve code cleanliness
This commit refactor the component tests, introduced new interfaces and events related to workflow definition and trigger change token signals. Removed an unused file, DictionaryExtensions.cs and refactored the GetOrAdd method to better handle null values. Some minor changes and improvements were also made in existing files to enhance overall code cleanliness.
---------
Co-authored-by: Steve Taylor <stevetayloruk@users.noreply.github.com>