[codex] Add codebase wiki (#7453)
* Add codebase wiki * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Document resilient restore workflow --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
6dee7094f0
commit
b9664a954d
72
doc/wiki/README.md
Normal file
72
doc/wiki/README.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Elsa Core Wiki
|
||||
|
||||
This wiki is a repo-local, code-grounded map of Elsa Core. It is intended for contributors who need the same kind of fast orientation that a DeepWiki-style generated wiki gives: what the system is, where the important code lives, how the pieces connect, and how to safely extend or test them.
|
||||
|
||||
The source of truth is still the code, specs, ADRs, and tests. Each page links back to the relevant files so you can jump from explanation to implementation.
|
||||
|
||||
## Start Here
|
||||
|
||||
Elsa Core is a modular .NET workflow engine. The main solution is [Elsa.sln](../../Elsa.sln). Production code lives under [src](../../src), tests under [test](../../test), specifications under [specs](../../specs), and architecture decisions under [doc/adr](../adr).
|
||||
|
||||
The shortest mental model:
|
||||
|
||||
1. An application calls `services.AddElsa(...)`.
|
||||
2. Elsa builds an `IModule` and configures feature objects.
|
||||
3. Features register services, activities, API endpoints, middleware, hosted services, and persistence stores.
|
||||
4. Workflow definitions are created by code, JSON, imported files, or providers.
|
||||
5. The runtime starts, resumes, dispatches, and persists workflow instances.
|
||||
6. APIs, SignalR hubs, HTTP endpoint activities, diagnostics, and persistence packages layer around that core.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
App["Host app"] --> Module["Elsa module system"]
|
||||
Module --> Core["Workflow core"]
|
||||
Module --> Management["Workflow management"]
|
||||
Module --> Runtime["Workflow runtime"]
|
||||
Module --> Api["Workflow API"]
|
||||
Module --> Extensions["HTTP, Scheduling, Expressions, Identity, Tenants"]
|
||||
Management --> Persistence["Stores / EF Core providers"]
|
||||
Runtime --> Persistence
|
||||
Runtime --> Logs["Execution logs and diagnostics"]
|
||||
Api --> Studio["Elsa Studio / API clients"]
|
||||
```
|
||||
|
||||
## Page Map
|
||||
|
||||
| Page | Use it for |
|
||||
| --- | --- |
|
||||
| [Repository Map](repository-map.md) | Top-level folders, projects, and where to look first. |
|
||||
| [Architecture](architecture.md) | The main system layers and request/execution flow. |
|
||||
| [Module System](module-system.md) | How `IModule`, `FeatureBase`, feature dependencies, and shell features work. |
|
||||
| [Workflow Core](workflow-core.md) | Activities, execution contexts, pipelines, variables, bookmarks, graphs, and flowchart execution. |
|
||||
| [Workflow Management](workflow-management.md) | Workflow definitions, instances, import/export, materializers, validation, and activity descriptors. |
|
||||
| [Workflow Runtime](workflow-runtime.md) | Dispatch, triggers, bookmarks, queues, background activity scheduling, graceful shutdown, and recovery. |
|
||||
| [Workflow API](workflow-api.md) | FastEndpoints, route prefixing, API categories, SignalR, and client-facing contracts. |
|
||||
| [Activities And Authoring](activities-and-authoring.md) | How workflows are authored in C#, JSON, ElsaScript, and host methods. |
|
||||
| [Expressions And Scripting](expressions-and-scripting.md) | Expression evaluators and language feature packages. |
|
||||
| [HTTP, Scheduling, And Resilience](http-scheduling-resilience.md) | Inbound HTTP workflows, outbound HTTP, scheduled triggers, and resilience strategies. |
|
||||
| [Persistence](persistence.md) | In-memory stores, EF Core stores, provider packages, migrations, and multi-provider rules. |
|
||||
| [Diagnostics Structured Logs](diagnostics-structured-logs.md) | `ILogger` capture, live feed, REST/SignalR surface, redaction, and SQLite persistence. |
|
||||
| [Identity, Tenancy, And Security](identity-tenancy-security.md) | Users, applications, roles, API keys, tenant resolution, and authorization touch points. |
|
||||
| [Testing Guide](testing-guide.md) | Test project layout, fixture choices, and targeted commands. |
|
||||
| [Extension Guide](extension-guide.md) | How to add features, activities, expression providers, stores, endpoints, and ingress sources. |
|
||||
| [Specs And ADRs](specs-and-adrs.md) | How current specs and ADRs explain design intent. |
|
||||
| [Build, Run, And Operate](build-run-operate.md) | Build commands, sample hosts, runtime knobs, Docker notes, and operational endpoints. |
|
||||
|
||||
## Source Landmarks
|
||||
|
||||
- Main public entry: [src/modules/Elsa/Extensions/DependencyInjectionExtensions.cs](../../src/modules/Elsa/Extensions/DependencyInjectionExtensions.cs)
|
||||
- Default umbrella feature: [src/modules/Elsa/Features/ElsaFeature.cs](../../src/modules/Elsa/Features/ElsaFeature.cs)
|
||||
- Module implementation: [src/common/Elsa.Features/Implementations/Module.cs](../../src/common/Elsa.Features/Implementations/Module.cs)
|
||||
- Core workflow feature: [src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs](../../src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs)
|
||||
- Management feature: [src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs](../../src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs)
|
||||
- Runtime feature: [src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs](../../src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs)
|
||||
- API feature: [src/modules/Elsa.Workflows.Api/Features/WorkflowsApiFeature.cs](../../src/modules/Elsa.Workflows.Api/Features/WorkflowsApiFeature.cs)
|
||||
- Reference server: [src/apps/Elsa.Server.Web/Program.cs](../../src/apps/Elsa.Server.Web/Program.cs)
|
||||
- Active structured-log persistence plan: [specs/005-structured-log-persistence/plan.md](../../specs/005-structured-log-persistence/plan.md)
|
||||
|
||||
## Contributor Workflow
|
||||
|
||||
Use targeted reads first, then targeted tests. For most changes, start with the relevant module page, inspect the linked feature class and contracts, add or update tests in the matching `test/unit`, `test/integration`, or `test/component` project, and run the narrowest `dotnet test` command that proves the behavior.
|
||||
|
||||
When changing public behavior, update the related README, spec quickstart, or wiki page in the same PR. This repository is strongly modular, so the best changes keep ownership boundaries clear.
|
||||
131
doc/wiki/activities-and-authoring.md
Normal file
131
doc/wiki/activities-and-authoring.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# Activities And Authoring
|
||||
|
||||
Elsa supports several workflow authoring paths: C# workflow classes, JSON definitions, visual designer definitions, host method activities, workflow-definition activities, and the experimental ElsaScript DSL.
|
||||
|
||||
## C# Workflows
|
||||
|
||||
C# workflows usually derive from [WorkflowBase](../../src/modules/Elsa.Workflows.Core/Abstractions/WorkflowBase.cs) and implement `Build(IWorkflowBuilder builder)`.
|
||||
|
||||
The root activity can be a `Sequence`, `Flowchart`, or another composite activity. The README has a minimal example that starts with `HttpEndpoint` and then sends email.
|
||||
|
||||
Source landmarks:
|
||||
|
||||
- [WorkflowBase](../../src/modules/Elsa.Workflows.Core/Abstractions/WorkflowBase.cs)
|
||||
- [WorkflowBuilder](../../src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs)
|
||||
- [IWorkflowBuilder](../../src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs)
|
||||
- [Workflow runtime feature AddWorkflow/AddWorkflowsFrom](../../src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs)
|
||||
|
||||
The reference server registers workflows from its assembly with `AddWorkflowsFrom<Program>()` in [Program.cs](../../src/apps/Elsa.Server.Web/Program.cs).
|
||||
|
||||
## JSON Workflows
|
||||
|
||||
JSON definitions are materialized by [JsonWorkflowMaterializer](../../src/modules/Elsa.Workflows.Management/Materializers/JsonWorkflowMaterializer.cs). Sample JSON workflows appear in:
|
||||
|
||||
- [src/apps/Elsa.Server.Web/Workflows](../../src/apps/Elsa.Server.Web/Workflows)
|
||||
- [test/component/Elsa.Workflows.ComponentTests/Scenarios](../../test/component/Elsa.Workflows.ComponentTests/Scenarios)
|
||||
- [test/integration/Elsa.Workflows.IntegrationTests/Scenarios](../../test/integration/Elsa.Workflows.IntegrationTests/Scenarios)
|
||||
|
||||
JSON workflows are important for designer compatibility and import/export tests.
|
||||
|
||||
## Designer Authored Workflows
|
||||
|
||||
The designer consumes metadata from workflow API descriptor endpoints and persists definitions through workflow definition endpoints. The server-side responsibilities are:
|
||||
|
||||
- expose activity descriptors
|
||||
- expose expression descriptors
|
||||
- expose variable descriptors
|
||||
- save drafts and publish versions
|
||||
- return workflow graphs and reference data
|
||||
|
||||
Relevant code:
|
||||
|
||||
- [ActivityDescriptors endpoints](../../src/modules/Elsa.Workflows.Api/Endpoints/ActivityDescriptors)
|
||||
- [WorkflowDefinitions endpoints](../../src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions)
|
||||
- [WorkflowDefinitionManager](../../src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionManager.cs)
|
||||
- [ActivityRegistryPopulator](../../src/modules/Elsa.Workflows.Management/Services/ActivityRegistryPopulator.cs)
|
||||
|
||||
## ElsaScript DSL
|
||||
|
||||
[Elsa.Dsl.ElsaScript](../../src/modules/Elsa.Dsl.ElsaScript) is an experimental JavaScript-inspired textual DSL for authoring workflows.
|
||||
|
||||
The module README is the best current guide: [ElsaScript README](../../src/modules/Elsa.Dsl.ElsaScript/README.md).
|
||||
|
||||
Current shape:
|
||||
|
||||
- parser creates AST nodes from ElsaScript source
|
||||
- compiler maps AST nodes to Elsa activities
|
||||
- expression prefixes map into Elsa expression providers
|
||||
- integration tests cover parser and compiler basics
|
||||
|
||||
Known limitations are documented in the README; do not assume full language coverage yet.
|
||||
|
||||
## Host Method Activities
|
||||
|
||||
Host method activities expose methods on registered host types as activities. Register host types with workflow management:
|
||||
|
||||
```csharp
|
||||
services.AddElsa(elsa =>
|
||||
{
|
||||
elsa.AddActivityHost<MyHost>();
|
||||
});
|
||||
```
|
||||
|
||||
Key files:
|
||||
|
||||
- [HostMethodActivity](../../src/modules/Elsa.Workflows.Management/Activities/HostMethod/HostMethodActivity.cs)
|
||||
- [HostMethodActivityProvider](../../src/modules/Elsa.Workflows.Management/Activities/HostMethod/HostMethodActivityProvider.cs)
|
||||
- [HostMethodActivitiesOptions](../../src/modules/Elsa.Workflows.Management/Options/HostMethodActivitiesOptions.cs)
|
||||
- sample host type [Penguin](../../src/apps/Elsa.Server.Web/ActivityHosts/Penguin.cs)
|
||||
|
||||
Use host method activities when host application methods need to appear as designer activities without creating a full activity package.
|
||||
|
||||
## Workflow Definition Activities
|
||||
|
||||
Workflow definition activities let a workflow call another workflow definition. This is useful for composition and reuse.
|
||||
|
||||
Key files:
|
||||
|
||||
- [WorkflowDefinitionActivity](../../src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivity.cs)
|
||||
- [WorkflowDefinitionActivityDescriptorFactory](../../src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivityDescriptorFactory.cs)
|
||||
- [WorkflowDefinitionActivityProvider](../../src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivityProvider.cs)
|
||||
- [WorkflowReferenceGraphBuilder](../../src/modules/Elsa.Workflows.Management/Services/WorkflowReferenceGraphBuilder.cs)
|
||||
|
||||
Tests:
|
||||
|
||||
- [CachingAndWorkflowDefinitionActivity](../../test/component/Elsa.Workflows.ComponentTests/Scenarios/CachingAndWorkflowDefinitionActivity)
|
||||
- [WorkflowReferenceGraph](../../test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowReferenceGraph)
|
||||
|
||||
## Adding A New Activity
|
||||
|
||||
Typical steps:
|
||||
|
||||
1. Add an activity class in the owning module's `Activities` folder.
|
||||
2. Derive from the appropriate base class, usually `Activity` or `CodeActivity`.
|
||||
3. Define inputs and outputs with Elsa input/output models.
|
||||
4. Register it with management, often via `Module.AddActivitiesFrom<TMarker>()` or `management.AddActivity<T>()`.
|
||||
5. Add a unit test with `ActivityTestFixture` for activity-only behavior.
|
||||
6. Add integration or component tests if it creates bookmarks, uses persistence, or participates in runtime dispatch.
|
||||
|
||||
Good examples:
|
||||
|
||||
- [WriteLine](../../src/modules/Elsa.Workflows.Core/Activities/WriteLine.cs)
|
||||
- [HttpEndpoint](../../src/modules/Elsa.Http/Activities/HttpEndpoint.cs)
|
||||
- [SendHttpRequest](../../src/modules/Elsa.Http/Activities/SendHttpRequest.cs)
|
||||
- [RunJavaScript](../../src/modules/Elsa.Expressions.JavaScript/Activities/RunJavaScript/RunJavaScript.cs)
|
||||
|
||||
## Activity Metadata And UI Hints
|
||||
|
||||
Designer-facing metadata is produced by descriptors and UI hint handlers. Core UI hints live under [Elsa.Workflows.Core/UIHints](../../src/modules/Elsa.Workflows.Core/UIHints). Module-specific handlers live with their module, such as HTTP content type options in [Elsa.Http/UIHints](../../src/modules/Elsa.Http/UIHints).
|
||||
|
||||
If an activity property needs dynamic options, add an `IPropertyUIHandler` and expose it through the descriptor option endpoint.
|
||||
|
||||
## Authoring Choice Guide
|
||||
|
||||
| Need | Use |
|
||||
| --- | --- |
|
||||
| Compile-time workflow with strong typing | C# workflow class |
|
||||
| Designer-created or imported workflow | JSON workflow definition |
|
||||
| Host app method as activity | Host method activity |
|
||||
| Reusable workflow composition | Workflow definition activity |
|
||||
| Text DSL experiment or code-centric workflow file | ElsaScript |
|
||||
| Module-specific trigger or IO | Custom activity in the owning module |
|
||||
123
doc/wiki/architecture.md
Normal file
123
doc/wiki/architecture.md
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
# Architecture
|
||||
|
||||
Elsa Core is a modular workflow platform. The core engine is intentionally small compared with the full host surface: features add management stores, runtime dispatch, APIs, HTTP activities, expression languages, persistence, identity, tenants, diagnostics, and shell integration.
|
||||
|
||||
## Layered View
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
Host["Host app / sample server"] --> Entry["AddElsa / ConfigureElsa"]
|
||||
Entry --> FeatureGraph["Feature graph"]
|
||||
FeatureGraph --> Core["Workflow Core"]
|
||||
FeatureGraph --> Mgmt["Workflow Management"]
|
||||
FeatureGraph --> Runtime["Workflow Runtime"]
|
||||
FeatureGraph --> Api["Workflow API"]
|
||||
FeatureGraph --> Ext["Extension modules"]
|
||||
Mgmt --> DefStores["Definition and instance stores"]
|
||||
Runtime --> RuntimeStores["Bookmark, trigger, queue, execution log stores"]
|
||||
Api --> FastEndpoints["FastEndpoints"]
|
||||
Ext --> Http["HTTP"]
|
||||
Ext --> Scheduling["Scheduling"]
|
||||
Ext --> Expressions["Expressions"]
|
||||
Ext --> Identity["Identity and tenants"]
|
||||
DefStores --> Persistence["In-memory or EF Core providers"]
|
||||
RuntimeStores --> Persistence
|
||||
```
|
||||
|
||||
The important boundary is that workflow execution concepts live in core, while persisted definitions and runtime orchestration live in management and runtime. API and transport packages are layered on top.
|
||||
|
||||
## Default Feature Composition
|
||||
|
||||
The default umbrella feature is [ElsaFeature](../../src/modules/Elsa/Features/ElsaFeature.cs). It depends on:
|
||||
|
||||
- `MediatorFeature`
|
||||
- `WorkflowsFeature`
|
||||
- `FlowchartFeature`
|
||||
- `DefaultWorkflowRuntimeFeature`
|
||||
- `WorkflowManagementFeature`
|
||||
|
||||
When installed, it configures default workflow and activity execution pipelines and registers built-in core activities through workflow management. The public entry point is [AddElsa](../../src/modules/Elsa/Extensions/DependencyInjectionExtensions.cs).
|
||||
|
||||
## Main Runtime Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Trigger as External stimulus
|
||||
participant Runtime as Workflow runtime
|
||||
participant Stores as Runtime stores
|
||||
participant Mgmt as Management services
|
||||
participant Core as Workflow runner
|
||||
participant Logs as Execution logs
|
||||
|
||||
Trigger->>Runtime: dispatch trigger/bookmark/workflow
|
||||
Runtime->>Stores: find triggers or bookmarks
|
||||
Runtime->>Mgmt: load workflow definition/instance
|
||||
Runtime->>Core: run workflow execution pipeline
|
||||
Core->>Core: schedule and invoke activities
|
||||
Core->>Runtime: produce bookmarks, logs, state changes
|
||||
Runtime->>Stores: commit triggers/bookmarks/logs/state
|
||||
Runtime->>Logs: publish runtime notifications
|
||||
```
|
||||
|
||||
## Definitions Versus Instances
|
||||
|
||||
- A workflow definition describes what can run. It may originate from C# workflow types, JSON files, imported payloads, blob storage providers, or DSL compilation.
|
||||
- A workflow instance is a running or historical execution, including workflow state, variables, activity execution state, incidents, status, and logs.
|
||||
- Management owns definition and instance stores. Runtime owns trigger/bookmark queues and execution.
|
||||
|
||||
## Activities And Control Flow
|
||||
|
||||
Activities are the unit of work. Core activity types live under [Elsa.Workflows.Core/Activities](../../src/modules/Elsa.Workflows.Core/Activities). Control flow includes `Sequence`, `If`, `Switch`, `Fork`, `For`, `ForEach`, `While`, `Parallel`, `Flowchart`, and flowchart node activities.
|
||||
|
||||
Flowchart execution has a token-centric model documented in [ADR 0005](../adr/0005-token-centric-flowchart-execution-model.md), with explicit join behavior documented in [ADR 0007](../adr/0007-adoption-of-explicit-merge-modes-for-flowchart-joins.md).
|
||||
|
||||
## Management Layer
|
||||
|
||||
[WorkflowManagementFeature](../../src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs) wires:
|
||||
|
||||
- workflow definition and instance stores
|
||||
- workflow serializers and materializers
|
||||
- workflow definition manager, publisher, importer, exporter, validator
|
||||
- activity and expression descriptor providers
|
||||
- host method activities and workflow definition activities
|
||||
- workflow reference graph services
|
||||
- default variable type descriptors
|
||||
|
||||
The management layer is what Studio and API endpoints use to list, save, publish, import, export, and validate workflows.
|
||||
|
||||
## Runtime Layer
|
||||
|
||||
[WorkflowRuntimeFeature](../../src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs) wires:
|
||||
|
||||
- local runtime and dispatchers
|
||||
- trigger and bookmark stores
|
||||
- bookmark queue worker and queue store
|
||||
- workflow and activity execution log stores
|
||||
- workflow matcher, starter, invoker, resumer, canceler
|
||||
- background dispatch and task dispatch services
|
||||
- graceful shutdown services such as quiescence signal, ingress source registry, and drain orchestrator
|
||||
- recurring startup and maintenance tasks
|
||||
|
||||
The runtime can use in-memory stores by default or EF Core stores when persistence features are installed.
|
||||
|
||||
## API Layer
|
||||
|
||||
[WorkflowsApiFeature](../../src/modules/Elsa.Workflows.Api/Features/WorkflowsApiFeature.cs) registers FastEndpoints from the module and depends on workflow management, workflow instances, workflow runtime, and SAS tokens. The default route prefix is `elsa/api`, defined in [ApiEndpointOptions](../../src/modules/Elsa.Workflows.Api/Options/ApiEndpointOptions.cs) and applied by [UseWorkflowsApi](../../src/common/Elsa.Api.Common/Extensions/WebApplicationExtensions.cs).
|
||||
|
||||
Real-time workflow updates are in [RealTimeWorkflowUpdatesFeature](../../src/modules/Elsa.Workflows.Api/Features/RealTimeWorkflowUpdatesFeature.cs) and [WorkflowInstanceHub](../../src/modules/Elsa.Workflows.Api/RealTime/Hubs/WorkflowInstanceHub.cs).
|
||||
|
||||
## Persistence Layer
|
||||
|
||||
In-memory stores are the default for many features. EF Core provider packages replace store delegates in feature configuration:
|
||||
|
||||
- management stores through `WorkflowManagementFeature`
|
||||
- runtime stores through `WorkflowRuntimeFeature`
|
||||
- identity, tenants, labels, alterations, and key values through their own feature hooks
|
||||
|
||||
Provider-specific packages such as SQLite, SQL Server, PostgreSQL, MySQL, and Oracle depend on the shared EF Core module and provide database-specific setup.
|
||||
|
||||
## Diagnostics Layer
|
||||
|
||||
[Elsa.Diagnostics.StructuredLogs](../../src/modules/Elsa.Diagnostics.StructuredLogs) captures semantic `ILogger` events, redacts them, keeps recent events, exposes REST endpoints, and streams live events through SignalR. The default store is in-memory; the active `005-structured-log-persistence` work adds SQLite persistence through a shared relational package.
|
||||
|
||||
See [Diagnostics Structured Logs](diagnostics-structured-logs.md).
|
||||
157
doc/wiki/build-run-operate.md
Normal file
157
doc/wiki/build-run-operate.md
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# Build, Run, And Operate
|
||||
|
||||
This page collects day-to-day build, run, and operational notes for Elsa Core contributors.
|
||||
|
||||
## Build Commands
|
||||
|
||||
Restore first when working from a clean checkout or after dependency changes. The `--ignore-failed-sources` option keeps external feed hiccups from blocking packages that are available from other configured sources:
|
||||
|
||||
```bash
|
||||
./build.sh Restore --ignore-failed-sources
|
||||
```
|
||||
|
||||
Default NUKE build target after restore:
|
||||
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
NUKE test target after restore:
|
||||
|
||||
```bash
|
||||
./build.sh Test
|
||||
```
|
||||
|
||||
Direct solution build with the same restore/no-restore pattern:
|
||||
|
||||
```bash
|
||||
dotnet restore Elsa.sln --ignore-failed-sources
|
||||
dotnet build Elsa.sln --no-restore
|
||||
```
|
||||
|
||||
Direct solution tests:
|
||||
|
||||
```bash
|
||||
dotnet restore Elsa.sln --ignore-failed-sources
|
||||
dotnet test Elsa.sln --no-restore
|
||||
```
|
||||
|
||||
Targeted test project:
|
||||
|
||||
```bash
|
||||
dotnet restore test/unit/Elsa.Workflows.Core.UnitTests/Elsa.Workflows.Core.UnitTests.csproj --ignore-failed-sources
|
||||
dotnet test test/unit/Elsa.Workflows.Core.UnitTests/Elsa.Workflows.Core.UnitTests.csproj --no-restore
|
||||
```
|
||||
|
||||
ElsaScript DSL tests:
|
||||
|
||||
```bash
|
||||
./run-dsl-tests.sh
|
||||
```
|
||||
|
||||
## Build System
|
||||
|
||||
The NUKE build lives in [build/Build.cs](../../build/Build.cs). It defines clean, restore, compile, test, and package behavior through NUKE components. Test projects are discovered as solution projects whose names end with `Tests`.
|
||||
|
||||
Source projects multi-target `net8.0`, `net9.0`, and `net10.0` through [src/Directory.Build.props](../../src/Directory.Build.props). Central package versions are in [Directory.Packages.props](../../Directory.Packages.props), including conditional version blocks for .NET 8/9 and .NET 10.
|
||||
|
||||
## Run The Reference Server
|
||||
|
||||
The main sample host is [src/apps/Elsa.Server.Web](../../src/apps/Elsa.Server.Web). It wires most major modules in [Program.cs](../../src/apps/Elsa.Server.Web/Program.cs).
|
||||
|
||||
Restore the project and run it with:
|
||||
|
||||
```bash
|
||||
dotnet restore src/apps/Elsa.Server.Web/Elsa.Server.Web.csproj --ignore-failed-sources
|
||||
dotnet run --project src/apps/Elsa.Server.Web/Elsa.Server.Web.csproj --no-restore
|
||||
```
|
||||
|
||||
Notable toggles in `Program.cs`:
|
||||
|
||||
- `useReadOnlyMode`
|
||||
- `useSignalR`
|
||||
- `useStructuredLogs`
|
||||
- `useMultitenancy`
|
||||
- `disableVariableWrappers`
|
||||
|
||||
The sample configures identity, default authentication, workflow management/runtime with SQLite, workflow API, fluent storage, ElsaScript blob storage, scheduling, C#, JavaScript, Python, Liquid, HTTP, and optional tenants/structured logs.
|
||||
|
||||
## Docker Quick Try
|
||||
|
||||
The root [README](../../README.md) documents the public Docker quick start:
|
||||
|
||||
```bash
|
||||
docker pull elsaworkflows/elsa-server-and-studio-v3:latest
|
||||
docker run -t -i -e ASPNETCORE_ENVIRONMENT='Development' -e HTTP_PORTS=8080 -e HTTP__BASEURL=http://localhost:13000 -p 13000:8080 elsaworkflows/elsa-server-and-studio-v3:latest
|
||||
```
|
||||
|
||||
Default development login:
|
||||
|
||||
```text
|
||||
Username: admin
|
||||
Password: password
|
||||
```
|
||||
|
||||
Do not use default credentials in production.
|
||||
|
||||
## ASP.NET Middleware Order
|
||||
|
||||
The reference server pipeline is a useful ordering guide:
|
||||
|
||||
1. developer exception page in development
|
||||
2. CORS
|
||||
3. health checks
|
||||
4. routing
|
||||
5. authentication
|
||||
6. authorization
|
||||
7. tenants
|
||||
8. workflow API
|
||||
9. JSON serialization error handler
|
||||
10. workflow HTTP endpoint middleware
|
||||
11. controllers
|
||||
12. Swagger UI in development
|
||||
13. SignalR workflow hubs if enabled
|
||||
14. structured logs hub if enabled
|
||||
|
||||
See [Program.cs](../../src/apps/Elsa.Server.Web/Program.cs).
|
||||
|
||||
## Operational Endpoints
|
||||
|
||||
With default route prefix `elsa/api`, runtime admin endpoints include:
|
||||
|
||||
- `GET /elsa/api/admin/workflow-runtime/status`
|
||||
- `POST /elsa/api/admin/workflow-runtime/pause`
|
||||
- `POST /elsa/api/admin/workflow-runtime/resume`
|
||||
- `POST /elsa/api/admin/workflow-runtime/force-drain`
|
||||
|
||||
Structured log diagnostics endpoints include:
|
||||
|
||||
- `GET|POST /elsa/api/diagnostics/structured-logs/recent`
|
||||
- `GET /elsa/api/diagnostics/structured-logs/sources`
|
||||
- `GET /elsa/api/diagnostics/structured-logs/storage`
|
||||
|
||||
Health checks are mapped to `/` in the reference server.
|
||||
|
||||
## Runtime Knobs
|
||||
|
||||
Common runtime-related options in the reference host:
|
||||
|
||||
- `RuntimeOptions.InactivityThreshold`
|
||||
- `BookmarkQueuePurgeOptions.Ttl`
|
||||
- `CachingOptions.CacheDuration`
|
||||
- `IncidentOptions.DefaultIncidentStrategy`
|
||||
- recurring task schedules for trigger queue, bookmark queue purge, and interrupted workflow restart
|
||||
|
||||
Structured logs options include recent log capacity, query size, source heartbeat timeout, redaction settings, and storage provider options.
|
||||
|
||||
## Local Development Notes
|
||||
|
||||
- Prefer targeted builds/tests while iterating.
|
||||
- Use `rg` to find feature registration and endpoint routes.
|
||||
- Keep package version changes centralized in [Directory.Packages.props](../../Directory.Packages.props).
|
||||
- Avoid provider-specific assumptions in core modules.
|
||||
- When changing middleware, verify both code-first host setup and shell-feature setup if applicable.
|
||||
|
||||
## Release And Package Notes
|
||||
|
||||
Package behavior is controlled by the NUKE build and project metadata. Because source projects multi-target three frameworks, package upgrades should be checked against all target frameworks and provider packages. Persistence changes usually need extra scrutiny because each provider package may need migrations or compatibility updates.
|
||||
163
doc/wiki/diagnostics-structured-logs.md
Normal file
163
doc/wiki/diagnostics-structured-logs.md
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
# Diagnostics Structured Logs
|
||||
|
||||
`Elsa.Diagnostics.StructuredLogs` captures semantic `ILogger` events from an Elsa host, redacts sensitive data, keeps a recent queryable buffer, exposes REST endpoints, and streams live events to Studio over SignalR.
|
||||
|
||||
Start in [src/modules/Elsa.Diagnostics.StructuredLogs](../../src/modules/Elsa.Diagnostics.StructuredLogs).
|
||||
|
||||
## Scope
|
||||
|
||||
This module captures structured `ILogger` records only. It does not capture raw stdout/stderr console streams, traces, metrics, or OpenTelemetry spans. Those are intentionally separate future diagnostics concerns.
|
||||
|
||||
## Feature Wiring
|
||||
|
||||
[StructuredLogsFeature](../../src/modules/Elsa.Diagnostics.StructuredLogs/Features/StructuredLogsFeature.cs):
|
||||
|
||||
- registers FastEndpoints assembly
|
||||
- calls `AddStructuredLogsServices`
|
||||
- adds FastEndpoints from the module
|
||||
|
||||
[AddStructuredLogsServices](../../src/modules/Elsa.Diagnostics.StructuredLogs/Extensions/ServiceCollectionExtensions.cs) registers:
|
||||
|
||||
- SignalR
|
||||
- `StructuredLogsOptions`
|
||||
- source registry
|
||||
- redactor
|
||||
- in-memory store
|
||||
- in-memory live feed
|
||||
- default provider facade
|
||||
- subscription manager
|
||||
- `StructuredLogLoggerProvider` as an `ILoggerProvider`
|
||||
|
||||
## Core Contracts
|
||||
|
||||
| Contract | Purpose |
|
||||
| --- | --- |
|
||||
| [IStructuredLogProvider](../../src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogProvider.cs) | REST/SignalR facade used by endpoints and clients. |
|
||||
| [IStructuredLogStore](../../src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogStore.cs) | Queryable storage abstraction. |
|
||||
| [IStructuredLogLiveFeed](../../src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogLiveFeed.cs) | Live event publication/subscription abstraction. |
|
||||
| [IStructuredLogSink](../../src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogSink.cs) | Event ingestion boundary. |
|
||||
| [IStructuredLogRedactor](../../src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogRedactor.cs) | Redacts properties and text before storage/live delivery. |
|
||||
| [IStructuredLogSourceRegistry](../../src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogSourceRegistry.cs) | Tracks source metadata and health. |
|
||||
| [IStructuredLogStorageDiagnostics](../../src/modules/Elsa.Diagnostics.StructuredLogs/Contracts/IStructuredLogStorageDiagnostics.cs) | Provider-neutral diagnostics such as dropped durable writes. |
|
||||
|
||||
## Event Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as App ILogger
|
||||
participant Provider as StructuredLogLoggerProvider
|
||||
participant Redactor as IStructuredLogRedactor
|
||||
participant Store as IStructuredLogStore
|
||||
participant Feed as IStructuredLogLiveFeed
|
||||
participant Hub as StructuredLogsHub
|
||||
participant Studio as Studio
|
||||
|
||||
App->>Provider: Log event + scopes
|
||||
Provider->>Redactor: redact event
|
||||
Redactor->>Store: append event
|
||||
Redactor->>Feed: publish event
|
||||
Feed->>Hub: live event
|
||||
Hub->>Studio: SignalR stream
|
||||
Studio->>Store: recent query through REST
|
||||
```
|
||||
|
||||
## In-Memory Provider
|
||||
|
||||
The default provider keeps recent logs in process:
|
||||
|
||||
- [InMemoryStructuredLogStore](../../src/modules/Elsa.Diagnostics.StructuredLogs/Providers/InMemory/InMemoryStructuredLogStore.cs)
|
||||
- [InMemoryStructuredLogLiveFeed](../../src/modules/Elsa.Diagnostics.StructuredLogs/Providers/InMemory/InMemoryStructuredLogLiveFeed.cs)
|
||||
- [RingBuffer](../../src/modules/Elsa.Diagnostics.StructuredLogs/Providers/InMemory/RingBuffer.cs)
|
||||
|
||||
This is bounded and process-local. In clustered deployments, each node has its own source identity and in-memory history unless durable/shared persistence is configured.
|
||||
|
||||
## REST And SignalR Surface
|
||||
|
||||
REST endpoints:
|
||||
|
||||
- `GET|POST /elsa/api/diagnostics/structured-logs/recent`
|
||||
- `GET /elsa/api/diagnostics/structured-logs/sources`
|
||||
- `GET /elsa/api/diagnostics/structured-logs/storage`
|
||||
|
||||
Endpoint code is under [Endpoints/StructuredLogs](../../src/modules/Elsa.Diagnostics.StructuredLogs/Endpoints/StructuredLogs).
|
||||
|
||||
SignalR:
|
||||
|
||||
- Hub: [StructuredLogsHub](../../src/modules/Elsa.Diagnostics.StructuredLogs/RealTime/StructuredLogsHub.cs)
|
||||
- Client contract: [IStructuredLogsClient](../../src/modules/Elsa.Diagnostics.StructuredLogs/RealTime/IStructuredLogsClient.cs)
|
||||
- Mapping: [MapStructuredLogsHub](../../src/modules/Elsa.Diagnostics.StructuredLogs/Extensions/EndpointRouteBuilderExtensions.cs)
|
||||
- App extension: [UseStructuredLogs](../../src/modules/Elsa.Diagnostics.StructuredLogs/Extensions/ApplicationBuilderExtensions.cs)
|
||||
|
||||
The README states the hub is mapped at `/elsa/hubs/diagnostics/structured-logs`.
|
||||
|
||||
## Authorization
|
||||
|
||||
The endpoints require `read:diagnostics:structured-logs`, defined in [StructuredLogsPermissions](../../src/modules/Elsa.Diagnostics.StructuredLogs/Permissions/StructuredLogsPermissions.cs). The SignalR hub requires an authenticated user.
|
||||
|
||||
## Redaction
|
||||
|
||||
Events pass through `IStructuredLogRedactor` before buffering or streaming. Configuration lives in [StructuredLogsOptions](../../src/modules/Elsa.Diagnostics.StructuredLogs/Options/StructuredLogsOptions.cs). Extend sensitive property names and text patterns there.
|
||||
|
||||
## SQLite Persistence
|
||||
|
||||
The active structured-log persistence work adds durable SQLite storage:
|
||||
|
||||
- design plan: [specs/005-structured-log-persistence/plan.md](../../specs/005-structured-log-persistence/plan.md)
|
||||
- quickstart: [specs/005-structured-log-persistence/quickstart.md](../../specs/005-structured-log-persistence/quickstart.md)
|
||||
- relational package: [Elsa.Diagnostics.StructuredLogs.Persistence.Relational](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Relational)
|
||||
- SQLite package: [Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite)
|
||||
|
||||
Configuration example from the SQLite README:
|
||||
|
||||
```csharp
|
||||
services.AddElsa(elsa =>
|
||||
{
|
||||
elsa.UseStructuredLogs(structuredLogs =>
|
||||
{
|
||||
structuredLogs.UseSqliteStorage("Data Source=elsa-structured-logs.db", sqlite =>
|
||||
{
|
||||
sqlite.RunMigrationsOnStartup = true;
|
||||
sqlite.Relational.WriteQueue.Capacity = 10_000;
|
||||
sqlite.Relational.WriteQueue.BatchSize = 100;
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Relational Persistence Design
|
||||
|
||||
[AddRelationalStructuredLogPersistence](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Relational/Extensions/RelationalStructuredLogsServiceCollectionExtensions.cs) registers:
|
||||
|
||||
- `RelationalStructuredLogMapper`
|
||||
- `RelationalStructuredLogSqlBuilder`
|
||||
- `RelationalStructuredLogStore`
|
||||
- `StructuredLogWriteBuffer`
|
||||
- `StructuredLogRetentionService`
|
||||
- `IStructuredLogStore` as the write buffer
|
||||
- `IStructuredLogWriteBuffer`
|
||||
- `IStructuredLogStorageDiagnostics`
|
||||
- hosted service for the write buffer
|
||||
|
||||
The write buffer uses a bounded queue. If the queue is full, newest events are dropped and the dropped-write count is reported through storage diagnostics.
|
||||
|
||||
## SQLite Provider Boundary
|
||||
|
||||
[AddSqliteStructuredLogPersistence](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite/Extensions/SqliteStructuredLogsModuleExtensions.cs) supplies provider-specific services:
|
||||
|
||||
- `IRelationalStructuredLogConnectionFactory`
|
||||
- `IRelationalStructuredLogDialect`
|
||||
- `IStructuredLogSchemaMigrator`
|
||||
- startup migration/cleanup hosted service
|
||||
|
||||
The core structured logs package must remain unaware of SQLite. Future relational providers should copy this boundary: provider package supplies connection factory, dialect, migrator, and option binding; relational package supplies shared store behavior.
|
||||
|
||||
## Tests
|
||||
|
||||
Relevant tests:
|
||||
|
||||
- [test/unit/Elsa.Diagnostics.StructuredLogs.UnitTests](../../test/unit/Elsa.Diagnostics.StructuredLogs.UnitTests)
|
||||
- [test/integration/Elsa.Diagnostics.StructuredLogs.IntegrationTests](../../test/integration/Elsa.Diagnostics.StructuredLogs.IntegrationTests)
|
||||
- [test/unit/Elsa.Diagnostics.StructuredLogs.Persistence.Relational.UnitTests](../../test/unit/Elsa.Diagnostics.StructuredLogs.Persistence.Relational.UnitTests)
|
||||
- [test/integration/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests](../../test/integration/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests)
|
||||
|
||||
Run targeted structured-log tests before broader builds when touching this area.
|
||||
110
doc/wiki/expressions-and-scripting.md
Normal file
110
doc/wiki/expressions-and-scripting.md
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# Expressions And Scripting
|
||||
|
||||
Expressions let workflow inputs be dynamic. The base expression feature provides evaluator infrastructure; language modules add concrete evaluators, descriptors, activities, and type/function definitions.
|
||||
|
||||
## Base Expressions
|
||||
|
||||
[ExpressionsFeature](../../src/modules/Elsa.Expressions/Features/ExpressionsFeature.cs) registers:
|
||||
|
||||
- `IExpressionEvaluator`
|
||||
- `IWellKnownTypeRegistry`
|
||||
|
||||
The base project is [Elsa.Expressions](../../src/modules/Elsa.Expressions). It is intentionally small and does not own language-specific runtime behavior.
|
||||
|
||||
## Language Modules
|
||||
|
||||
| Module | Feature | Evaluator | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| [Elsa.Expressions.JavaScript](../../src/modules/Elsa.Expressions.JavaScript) | [JavaScriptFeature](../../src/modules/Elsa.Expressions.JavaScript/Features/JavaScriptFeature.cs) | Jint-backed `IJavaScriptEvaluator` | Adds type definitions, function definitions, `RunJavaScript`, and FastEndpoints assembly. |
|
||||
| [Elsa.Expressions.CSharp](../../src/modules/Elsa.Expressions.CSharp) | [CSharpFeature](../../src/modules/Elsa.Expressions.CSharp/Features/CSharpFeature.cs) | Roslyn scripting-backed `ICSharpEvaluator` | Adds `RunCSharp`, descriptors, and C# options. |
|
||||
| [Elsa.Expressions.Python](../../src/modules/Elsa.Expressions.Python) | [PythonFeature](../../src/modules/Elsa.Expressions.Python/Features/PythonFeature.cs) | pythonnet-backed `IPythonEvaluator` | Registers `PythonGlobalInterpreterManager` as a hosted service. |
|
||||
| [Elsa.Expressions.Liquid](../../src/modules/Elsa.Expressions.Liquid) | [LiquidFeature](../../src/modules/Elsa.Expressions.Liquid/Features/LiquidFeature.cs) | Fluid-backed Liquid manager | Adds Liquid filters and parser services. |
|
||||
|
||||
## JavaScript
|
||||
|
||||
JavaScript is the richest expression module. It registers:
|
||||
|
||||
- `IJavaScriptEvaluator`
|
||||
- `ITypeDefinitionService`
|
||||
- type describers and type definition renderers
|
||||
- function definition providers
|
||||
- variable definition providers
|
||||
- `RunJavaScript` activity
|
||||
- TypeScript definition support
|
||||
- expression descriptors for Studio
|
||||
|
||||
Configuration example from [Elsa.Server.Web/Program.cs](../../src/apps/Elsa.Server.Web/Program.cs):
|
||||
|
||||
```csharp
|
||||
elsa.UseJavaScript(options =>
|
||||
{
|
||||
options.AllowClrAccess = true;
|
||||
options.ConfigureEngine(engine =>
|
||||
{
|
||||
engine.Execute("function greet(name) { return `Hello ${name}!`; }");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
Additional JavaScript libraries are in [Elsa.Expressions.JavaScript.Libraries](../../src/modules/Elsa.Expressions.JavaScript.Libraries), including Lodash, Lodash FP, and Moment feature packages.
|
||||
|
||||
## CSharp
|
||||
|
||||
[CSharpFeature](../../src/modules/Elsa.Expressions.CSharp/Features/CSharpFeature.cs) registers C# descriptors and `ICSharpEvaluator`, then adds activities from its assembly. The reference server demonstrates configuring wrappers and appending helper scripts:
|
||||
|
||||
```csharp
|
||||
elsa.UseCSharp(options =>
|
||||
{
|
||||
options.DisableWrappers = disableVariableWrappers;
|
||||
options.AppendScript("string Greet(string name) => $\"Hello {name}!\";");
|
||||
});
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
[PythonFeature](../../src/modules/Elsa.Expressions.Python/Features/PythonFeature.cs) registers pythonnet-based evaluation and configures `PythonGlobalInterpreterManager` as a hosted service. Hosts must configure the Python DLL path or set `PYTHONNET_PYDLL`.
|
||||
|
||||
The reference server binds `Scripting:Python` configuration in [Program.cs](../../src/apps/Elsa.Server.Web/Program.cs).
|
||||
|
||||
## Liquid
|
||||
|
||||
[LiquidFeature](../../src/modules/Elsa.Expressions.Liquid/Features/LiquidFeature.cs) registers Fluid options, parser services, expression descriptors, and built-in filters:
|
||||
|
||||
- array filters
|
||||
- string filters
|
||||
- number filters
|
||||
- miscellaneous filters
|
||||
- `base64`
|
||||
- `keys`
|
||||
|
||||
The reference server configures the Fluid encoder to `HtmlEncoder.Default`.
|
||||
|
||||
## Expression Descriptors
|
||||
|
||||
Expression descriptors let Studio know which expression languages are available and how to present them. Providers are registered by language features, for example:
|
||||
|
||||
- `JavaScriptExpressionDescriptorProvider`
|
||||
- `CSharpExpressionDescriptorProvider`
|
||||
- `PythonExpressionDescriptorProvider`
|
||||
- `LiquidExpressionDescriptorProvider`
|
||||
|
||||
The API exposes descriptors under `/elsa/api/descriptors/expression-descriptors`.
|
||||
|
||||
## Type Aliases
|
||||
|
||||
Expression modules and activity modules register type aliases through `ExpressionOptions`. HTTP, for example, adds aliases such as `HttpRequest`, `HttpResponse`, `RouteData`, `FormFile`, and `Downloadable` in [HttpFeature](../../src/modules/Elsa.Http/Features/HttpFeature.cs).
|
||||
|
||||
## ElsaScript Relationship
|
||||
|
||||
ElsaScript does not replace expression languages. It uses Elsa's expression providers through language prefixes such as `js =>`, `cs =>`, `py =>`, and `liquid =>`. See [ElsaScript README](../../src/modules/Elsa.Dsl.ElsaScript/README.md).
|
||||
|
||||
## Testing
|
||||
|
||||
Expression tests are split by concern:
|
||||
|
||||
- [test/unit/Elsa.Expressions.UnitTests](../../test/unit/Elsa.Expressions.UnitTests)
|
||||
- [test/integration/Elsa.JavaScript.IntegrationTests](../../test/integration/Elsa.JavaScript.IntegrationTests)
|
||||
- [test/integration/Elsa.Dsl.ElsaScript.IntegrationTests](../../test/integration/Elsa.Dsl.ElsaScript.IntegrationTests)
|
||||
- workflow integration tests under [test/integration/Elsa.Workflows.IntegrationTests/Evaluation](../../test/integration/Elsa.Workflows.IntegrationTests/Evaluation)
|
||||
|
||||
Prefer unit tests for parser/evaluator behavior and integration tests when expression evaluation interacts with workflow variables, activity outputs, or designer descriptors.
|
||||
145
doc/wiki/extension-guide.md
Normal file
145
doc/wiki/extension-guide.md
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# Extension Guide
|
||||
|
||||
Elsa is designed to be extended by adding modules, features, activities, stores, expression providers, API endpoints, and runtime integration points. This page collects the common patterns.
|
||||
|
||||
## Add A Code-First Feature
|
||||
|
||||
1. Create `Features/MyFeature.cs`.
|
||||
2. Derive from `FeatureBase`.
|
||||
3. Add `[DependsOn]` attributes for required features.
|
||||
4. Use `Configure()` for feature graph changes and activity scanning.
|
||||
5. Use `ConfigureHostedServices()` for hosted services.
|
||||
6. Use `Apply()` for service registration.
|
||||
7. Add `Extensions/ModuleExtensions.cs` with `UseMyFeature`.
|
||||
8. Add unit tests that prove core services register.
|
||||
|
||||
Use [HttpFeature](../../src/modules/Elsa.Http/Features/HttpFeature.cs), [SchedulingFeature](../../src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs), and [StructuredLogsFeature](../../src/modules/Elsa.Diagnostics.StructuredLogs/Features/StructuredLogsFeature.cs) as examples.
|
||||
|
||||
## Add A Shell Feature
|
||||
|
||||
Shell features live in `ShellFeatures` and implement CShells interfaces such as `IShellFeature`, `IFastEndpointsShellFeature`, or `IMiddlewareShellFeature`.
|
||||
|
||||
Use shell features when modular server/package configuration needs to activate the feature without code-first `AddElsa` calls.
|
||||
|
||||
Examples:
|
||||
|
||||
- [Elsa.Shells.Api/ShellFeatures/ShellsApiFeature.cs](../../src/modules/Elsa.Shells.Api/ShellFeatures/ShellsApiFeature.cs)
|
||||
- [Elsa.Diagnostics.StructuredLogs/ShellFeatures/StructuredLogsFeature.cs](../../src/modules/Elsa.Diagnostics.StructuredLogs/ShellFeatures/StructuredLogsFeature.cs)
|
||||
- [EF Core provider shell features](../../src/modules/Elsa.Persistence.EFCore.Sqlite/ShellFeatures)
|
||||
|
||||
## Add An Activity
|
||||
|
||||
1. Put the activity in the owning module's `Activities` folder.
|
||||
2. Derive from `Activity`, `Activity<T>`, `CodeActivity`, or a module-specific base.
|
||||
3. Use `Input<T>` and `Output<T>` for designer/runtime compatibility.
|
||||
4. Register the activity with workflow management.
|
||||
5. Add descriptor/UI hint handlers if the designer needs dynamic options.
|
||||
6. Test activity-only behavior with `ActivityTestFixture`.
|
||||
7. Add integration/component tests for bookmarks, triggers, persistence, or transport behavior.
|
||||
|
||||
Good examples:
|
||||
|
||||
- [SetVariable](../../src/modules/Elsa.Workflows.Core/Activities/SetVariable.cs)
|
||||
- [HttpEndpoint](../../src/modules/Elsa.Http/Activities/HttpEndpoint.cs)
|
||||
- [RunCSharp](../../src/modules/Elsa.Expressions.CSharp/Activities/RunCSharp/RunCSharp.cs)
|
||||
|
||||
## Add An Expression Provider
|
||||
|
||||
Expression providers need:
|
||||
|
||||
- evaluator contract and implementation
|
||||
- expression descriptor provider
|
||||
- optional activity for running scripts
|
||||
- optional UI hint handler
|
||||
- option type
|
||||
- feature registration
|
||||
- tests for evaluator behavior and workflow integration
|
||||
|
||||
Compare existing language modules:
|
||||
|
||||
- [JavaScriptFeature](../../src/modules/Elsa.Expressions.JavaScript/Features/JavaScriptFeature.cs)
|
||||
- [CSharpFeature](../../src/modules/Elsa.Expressions.CSharp/Features/CSharpFeature.cs)
|
||||
- [PythonFeature](../../src/modules/Elsa.Expressions.Python/Features/PythonFeature.cs)
|
||||
- [LiquidFeature](../../src/modules/Elsa.Expressions.Liquid/Features/LiquidFeature.cs)
|
||||
|
||||
## Add An API Endpoint
|
||||
|
||||
1. Create a folder under the relevant `Endpoints` category.
|
||||
2. Add `Endpoint.cs` and local `Models.cs` when needed.
|
||||
3. Derive from the Elsa endpoint base used by nearby endpoints.
|
||||
4. Configure verb, route, permissions, and summary.
|
||||
5. Inject service contracts, not concrete internals when possible.
|
||||
6. Add endpoint tests or component coverage if behavior is important.
|
||||
7. Update client models if the endpoint is part of the public client surface.
|
||||
|
||||
Use route prefixing from `UseWorkflowsApi`; endpoint routes should usually be written without `/elsa/api`.
|
||||
|
||||
## Add A Store Or Persistence Provider
|
||||
|
||||
For an EF Core-backed store:
|
||||
|
||||
1. Add the entity/configuration/store to the shared EF Core module slice if it is a common Elsa domain.
|
||||
2. Add provider-specific migrations if persisted shape changes.
|
||||
3. Replace the owning feature's store factory in the persistence feature.
|
||||
4. Add tests for query/filter/order behavior.
|
||||
5. Add provider integration tests for migrations or SQL differences.
|
||||
|
||||
For diagnostics structured log relational providers:
|
||||
|
||||
1. Reference the relational structured-log package.
|
||||
2. Implement `IRelationalStructuredLogConnectionFactory`.
|
||||
3. Implement `IRelationalStructuredLogDialect`.
|
||||
4. Implement `IStructuredLogSchemaMigrator`.
|
||||
5. Register those services and call `AddRelationalStructuredLogPersistence`.
|
||||
|
||||
See [SqliteStructuredLogsModuleExtensions](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite/Extensions/SqliteStructuredLogsModuleExtensions.cs).
|
||||
|
||||
## Add A Runtime Ingress Source
|
||||
|
||||
External event sources should participate in graceful shutdown. Add an ingress source when a module feeds work into the runtime from outside the engine.
|
||||
|
||||
Steps:
|
||||
|
||||
1. Implement the runtime `IIngressSource` contract in the owning module.
|
||||
2. Register it as a singleton service.
|
||||
3. Make dispatch loops or middleware honor paused state.
|
||||
4. Add tests for pause/resume/drain behavior.
|
||||
|
||||
Existing first-party examples are HTTP and Scheduling ingress source registrations.
|
||||
|
||||
## Add A Workflow Provider
|
||||
|
||||
Workflow providers bring definitions from external storage. Existing examples:
|
||||
|
||||
- [Elsa.WorkflowProviders.BlobStorage](../../src/modules/Elsa.WorkflowProviders.BlobStorage)
|
||||
- [Elsa.WorkflowProviders.BlobStorage.ElsaScript](../../src/modules/Elsa.WorkflowProviders.BlobStorage.ElsaScript)
|
||||
|
||||
Keep provider modules focused on discovery/materialization and leave execution to runtime.
|
||||
|
||||
## Add Documentation
|
||||
|
||||
Update docs when changing:
|
||||
|
||||
- public APIs
|
||||
- options/configuration
|
||||
- endpoint routes
|
||||
- persistence schema or provider setup
|
||||
- runtime behavior
|
||||
- security/authorization behavior
|
||||
- developer workflows
|
||||
|
||||
Good locations:
|
||||
|
||||
- module README
|
||||
- relevant spec quickstart
|
||||
- this wiki
|
||||
- ADR for architectural decisions
|
||||
|
||||
## Design Rules Of Thumb
|
||||
|
||||
- Keep core provider-neutral.
|
||||
- Use feature configuration instead of direct cross-module service replacement.
|
||||
- Add dependencies explicitly with `[DependsOn]`.
|
||||
- Prefer contracts at module boundaries.
|
||||
- Put tests near the module whose behavior changed.
|
||||
- Avoid adding shared abstractions until at least two real modules need them.
|
||||
144
doc/wiki/http-scheduling-resilience.md
Normal file
144
doc/wiki/http-scheduling-resilience.md
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
# HTTP, Scheduling, And Resilience
|
||||
|
||||
HTTP, scheduling, and resilience are extension modules layered on top of workflow core, management, runtime, and expressions.
|
||||
|
||||
## HTTP Module
|
||||
|
||||
Start in [src/modules/Elsa.Http](../../src/modules/Elsa.Http).
|
||||
|
||||
[HttpFeature](../../src/modules/Elsa.Http/Features/HttpFeature.cs) owns:
|
||||
|
||||
- inbound HTTP endpoint workflows
|
||||
- outbound HTTP request activities
|
||||
- route matching and route table updates
|
||||
- HTTP bookmark payloads
|
||||
- HTTP request/response content parsing and writing
|
||||
- downloadable content handling
|
||||
- file cache and zip management
|
||||
- correlation and workflow instance ID selectors
|
||||
- HTTP activity descriptors and UI hints
|
||||
- HTTP resilience strategy registration
|
||||
- HTTP ingress source registration for graceful shutdown
|
||||
|
||||
The public module extension is [UseHttp](../../src/modules/Elsa.Http/Extensions/ModuleExtensions.cs).
|
||||
|
||||
## Inbound HTTP Workflows
|
||||
|
||||
The inbound path is:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Request["ASP.NET request"] --> Middleware["HttpWorkflowsMiddleware"]
|
||||
Middleware --> RouteTable["IRouteTable / IRouteMatcher"]
|
||||
RouteTable --> Lookup["IHttpWorkflowLookupService"]
|
||||
Lookup --> Runtime["Workflow runtime"]
|
||||
Runtime --> Activity["HttpEndpoint activity"]
|
||||
Activity --> Response["HTTP response activity"]
|
||||
```
|
||||
|
||||
Important files:
|
||||
|
||||
- [HttpWorkflowsMiddleware](../../src/modules/Elsa.Http/Middleware/HttpWorkflowsMiddleware.cs)
|
||||
- [HttpEndpoint](../../src/modules/Elsa.Http/Activities/HttpEndpoint.cs)
|
||||
- [HttpEndpointBase](../../src/modules/Elsa.Http/Activities/HttpEndpointBase.cs)
|
||||
- [RouteMatcher](../../src/modules/Elsa.Http/Services/RouteMatcher.cs)
|
||||
- [RouteTable](../../src/modules/Elsa.Http/Services/RouteTable.cs)
|
||||
- [DefaultRouteTableUpdater](../../src/modules/Elsa.Http/Services/DefaultRouteTableUpdater.cs)
|
||||
- [HttpWorkflowLookupService](../../src/modules/Elsa.Http/Services/HttpWorkflowLookupService.cs)
|
||||
|
||||
Hosts enable middleware with [UseWorkflows](../../src/modules/Elsa.Http/Extensions/ApplicationBuilderExtensions.cs).
|
||||
|
||||
## Outbound HTTP
|
||||
|
||||
Outbound HTTP activities:
|
||||
|
||||
- [SendHttpRequest](../../src/modules/Elsa.Http/Activities/SendHttpRequest.cs)
|
||||
- [FlowSendHttpRequest](../../src/modules/Elsa.Http/Activities/FlowSendHttpRequest.cs)
|
||||
- [DownloadHttpFile](../../src/modules/Elsa.Http/Activities/DownloadHttpFile.cs)
|
||||
|
||||
Supporting services include `HttpClientFileDownloader`, content factories, content parsers, and downloadable content handlers.
|
||||
|
||||
## HTTP Security And Faults
|
||||
|
||||
HTTP endpoint authorization and faults are configurable through `HttpFeature`:
|
||||
|
||||
- [AuthenticationBasedHttpEndpointAuthorizationHandler](../../src/modules/Elsa.Http/Handlers/AuthenticationBasedHttpEndpointAuthorizationHandler.cs)
|
||||
- [AllowAnonymousHttpEndpointAuthorizationHandler](../../src/modules/Elsa.Http/Handlers/AllowAnonymousHttpEndpointAuthorizationHandler.cs)
|
||||
- [DefaultHttpEndpointFaultHandler](../../src/modules/Elsa.Http/Handlers/DefaultHttpEndpointFaultHandler.cs)
|
||||
- [DetailedHttpEndpointFaultHandler](../../src/modules/Elsa.Http/Handlers/DetailedHttpEndpointFaultHandler.cs)
|
||||
|
||||
The module registers authorization services because the authentication-based handler requires them.
|
||||
|
||||
## HTTP Tests
|
||||
|
||||
Good test entry points:
|
||||
|
||||
- [test/unit/Elsa.Http.UnitTests](../../test/unit/Elsa.Http.UnitTests)
|
||||
- [test/integration/Elsa.Http.IntegrationTests](../../test/integration/Elsa.Http.IntegrationTests)
|
||||
- [test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/Http](../../test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/Http)
|
||||
- [test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows](../../test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows)
|
||||
|
||||
## Scheduling Module
|
||||
|
||||
Start in [src/modules/Elsa.Scheduling](../../src/modules/Elsa.Scheduling).
|
||||
|
||||
[SchedulingFeature](../../src/modules/Elsa.Scheduling/Features/SchedulingFeature.cs) registers:
|
||||
|
||||
- local scheduler
|
||||
- cron parser
|
||||
- trigger scheduler
|
||||
- bookmark scheduler
|
||||
- workflow scheduler
|
||||
- tenant schedule updater
|
||||
- create-schedules background task
|
||||
- `ScheduleWorkflows` handlers
|
||||
- Cron trigger payload validator
|
||||
- scheduled-trigger ingress source for graceful shutdown
|
||||
- scheduling activities through workflow management
|
||||
|
||||
The public extension is [UseScheduling](../../src/modules/Elsa.Scheduling/Extensions/ModuleExtensions.cs).
|
||||
|
||||
## Scheduling Concepts
|
||||
|
||||
Scheduled workflows typically create trigger or bookmark payloads that the scheduler can wake later. Important files:
|
||||
|
||||
- [Bookmarks](../../src/modules/Elsa.Scheduling/Bookmarks)
|
||||
- [Services](../../src/modules/Elsa.Scheduling/Services)
|
||||
- [Handlers](../../src/modules/Elsa.Scheduling/Handlers)
|
||||
- [HostedServices](../../src/modules/Elsa.Scheduling/HostedServices)
|
||||
- [TriggerPayloadValidators](../../src/modules/Elsa.Scheduling/TriggerPayloadValidators)
|
||||
|
||||
The scheduler integrates with tenancy by reacting to tenant activation/deletion events.
|
||||
|
||||
## Resilience Module
|
||||
|
||||
Start in [src/modules/Elsa.Resilience](../../src/modules/Elsa.Resilience) and [Elsa.Resilience.Core](../../src/modules/Elsa.Resilience.Core).
|
||||
|
||||
[ResilienceFeature](../../src/modules/Elsa.Resilience/Features/ResilienceFeature.cs) registers:
|
||||
|
||||
- activity descriptor modifier for resilient activities
|
||||
- resilience strategy catalog
|
||||
- strategy config evaluator
|
||||
- resilient activity invoker
|
||||
- configuration strategy source
|
||||
- retry attempt recorders/readers
|
||||
- transient exception detector and strategy
|
||||
- FastEndpoints assembly for resilience descriptors/testing endpoints
|
||||
|
||||
HTTP registers [HttpResilienceStrategy](../../src/modules/Elsa.Http/Resilience/HttpResilienceStrategy.cs) with resilience in `HttpFeature.Configure()`.
|
||||
|
||||
## Resilience Concepts
|
||||
|
||||
Core contracts:
|
||||
|
||||
- [IResilienceStrategy](../../src/modules/Elsa.Resilience.Core/Contracts/IResilienceStrategy.cs)
|
||||
- [IResilientActivity](../../src/modules/Elsa.Resilience.Core/Contracts/IResilientActivity.cs)
|
||||
- [IResilientActivityInvoker](../../src/modules/Elsa.Resilience.Core/Contracts/IResilientActivityInvoker.cs)
|
||||
- [IRetryAttemptRecorder](../../src/modules/Elsa.Resilience.Core/Contracts/IRetryAttemptRecorder.cs)
|
||||
- [ITransientExceptionDetector](../../src/modules/Elsa.Resilience.Core/Contracts/ITransientExceptionDetector.cs)
|
||||
|
||||
Use resilience when an activity performs IO that can fail transiently. Keep strategy types registered by the owning module.
|
||||
|
||||
## Cross-Cutting Graceful Shutdown
|
||||
|
||||
HTTP and Scheduling both register runtime ingress sources so graceful shutdown can pause new external work. When adding a new external event source, implement and register an `IIngressSource` in the owning module, then add runtime tests that prove pause/resume/drain behavior.
|
||||
113
doc/wiki/identity-tenancy-security.md
Normal file
113
doc/wiki/identity-tenancy-security.md
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# Identity, Tenancy, And Security
|
||||
|
||||
Elsa security and tenancy are split across identity, SAS token, tenant, tenant HTTP routing, API authorization, and persistence packages.
|
||||
|
||||
## Identity
|
||||
|
||||
Start in [src/modules/Elsa.Identity](../../src/modules/Elsa.Identity).
|
||||
|
||||
[IdentityFeature](../../src/modules/Elsa.Identity/Features/IdentityFeature.cs) registers:
|
||||
|
||||
- identity token options
|
||||
- API key options
|
||||
- users, applications, and roles options
|
||||
- memory stores for users, applications, and roles
|
||||
- user, application, and role providers
|
||||
- user and role managers
|
||||
- secret hashing
|
||||
- access token issuing
|
||||
- API key generation/parsing
|
||||
- tenant resolvers based on claims and current user
|
||||
- FastEndpoints assembly
|
||||
|
||||
Identity supports store-based providers, configuration-based providers, and admin bootstrap providers.
|
||||
|
||||
## Authentication
|
||||
|
||||
[DefaultAuthenticationFeature](../../src/modules/Elsa.Identity/Features/DefaultAuthenticationFeature.cs) wires default authentication. The reference server calls:
|
||||
|
||||
```csharp
|
||||
elsa
|
||||
.UseIdentity(...)
|
||||
.UseDefaultAuthentication();
|
||||
```
|
||||
|
||||
See [src/apps/Elsa.Server.Web/Program.cs](../../src/apps/Elsa.Server.Web/Program.cs).
|
||||
|
||||
## Default Admin Bootstrap
|
||||
|
||||
The default admin bootstrap is documented in [src/modules/Elsa.Identity/README.md](../../src/modules/Elsa.Identity/README.md) and [ADR 0010](../adr/0010-default-admin-user-bootstrap-for-initial-identity-access.md).
|
||||
|
||||
Key points:
|
||||
|
||||
- It creates initial admin role/user idempotently.
|
||||
- It is recommended for initial identity access.
|
||||
- Do not keep development defaults in production.
|
||||
- Shell-based configuration uses `DefaultAdminUser` shell feature.
|
||||
- Code-first configuration uses `identity.UseDefaultAdmin(...)`.
|
||||
|
||||
## SAS Tokens
|
||||
|
||||
[SasTokensFeature](../../src/modules/Elsa.SasTokens/Features/SasTokensFeature.cs) registers data protection and `ITokenService`. Workflow API depends on SAS tokens. The default data protection application name is `Elsa Workflows`.
|
||||
|
||||
Use SAS tokens for protected links or temporary access flows where the API expects signed token semantics.
|
||||
|
||||
## Tenancy
|
||||
|
||||
Start in [src/modules/Elsa.Tenants](../../src/modules/Elsa.Tenants).
|
||||
|
||||
Key features:
|
||||
|
||||
- [TenantsFeature](../../src/modules/Elsa.Tenants/Features/TenantsFeature.cs): enables tenant resolution pipeline, tenant options, and tenant resolver services.
|
||||
- [TenantManagementFeature](../../src/modules/Elsa.Tenants/Features/TenantManagementFeature.cs): registers tenant store, defaulting to memory.
|
||||
- [TenantManagementEndpointsFeature](../../src/modules/Elsa.Tenants/Features/TenantManagementEndpointsFeature.cs): exposes tenant management endpoints.
|
||||
|
||||
Tenant providers:
|
||||
|
||||
- configuration-based tenants provider
|
||||
- store-based tenants provider
|
||||
|
||||
The reference server enables configuration-based tenants and a custom tenant resolver pipeline using `CurrentUserTenantResolver`.
|
||||
|
||||
## ASP.NET Core Tenant Routing
|
||||
|
||||
[Elsa.Tenants.AspNetCore](../../src/modules/Elsa.Tenants.AspNetCore) integrates tenants with HTTP routing.
|
||||
|
||||
[MultitenantHttpRoutingFeature](../../src/modules/Elsa.Tenants.AspNetCore/Features/MultitenantHttpRoutingFeature.cs):
|
||||
|
||||
- is a dependency of `HttpFeature` and `TenantsFeature`
|
||||
- configures HTTP endpoint routes and base path providers to use tenant prefixes
|
||||
- registers route-prefix, header, and host tenant resolvers
|
||||
- lets hosts configure tenant header and HTTP tenancy options
|
||||
|
||||
This feature is important when HTTP workflow routes must be tenant-aware.
|
||||
|
||||
## Tenant Persistence Conventions
|
||||
|
||||
Persistence is tenant-aware through EF Core model/saving handlers and tenant-aware DbContext factory decoration. ADRs explain conventions:
|
||||
|
||||
- [ADR 0008: Empty String As Default Tenant ID](../adr/0008-empty-string-as-default-tenant-id.md)
|
||||
- [ADR 0009: Asterisk Sentinel Value For Tenant-Agnostic Entities](../adr/0009-asterisk-sentinel-value-for-tenant-agnostic-entities.md)
|
||||
|
||||
When changing persisted entities, verify tenant ID behavior and default tenant semantics.
|
||||
|
||||
## API Authorization
|
||||
|
||||
Workflow API defines read-only-mode authorization in:
|
||||
|
||||
- [AuthorizationPolicies](../../src/modules/Elsa.Workflows.Api/Constants/AuthorizationPolicies.cs)
|
||||
- [NotReadOnlyRequirement](../../src/modules/Elsa.Workflows.Api/Requirements/NotReadOnlyRequirement.cs)
|
||||
|
||||
Structured logs define diagnostics permissions in [StructuredLogsPermissions](../../src/modules/Elsa.Diagnostics.StructuredLogs/Permissions/StructuredLogsPermissions.cs).
|
||||
|
||||
Identity endpoints and user-management endpoints are permission-based; see [ADR 0010](../adr/0010-default-admin-user-bootstrap-for-initial-identity-access.md).
|
||||
|
||||
## Security Review Checklist
|
||||
|
||||
- Does the endpoint require authentication or a permission?
|
||||
- Does mutable API behavior honor read-only mode?
|
||||
- Does the operation need tenant scoping?
|
||||
- Does persistence apply tenant ID filters and saving handlers?
|
||||
- Are bootstrap credentials only for development or secret-managed environments?
|
||||
- Does any diagnostic/logging feature expose sensitive data without redaction?
|
||||
- Do token settings use production-grade signing keys and data protection configuration?
|
||||
96
doc/wiki/module-system.md
Normal file
96
doc/wiki/module-system.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Module System
|
||||
|
||||
The module system is the backbone of Elsa. It is a thin abstraction over `IServiceCollection` that lets packages register cohesive feature sets with dependency ordering.
|
||||
|
||||
## Core Types
|
||||
|
||||
| Type | File | Role |
|
||||
| --- | --- | --- |
|
||||
| `IModule` | [src/common/Elsa.Features/Services/IModule.cs](../../src/common/Elsa.Features/Services/IModule.cs) | Holds `IServiceCollection`, module properties, configured features, hosted service descriptors, and `Apply()`. |
|
||||
| `Module` | [src/common/Elsa.Features/Implementations/Module.cs](../../src/common/Elsa.Features/Implementations/Module.cs) | Concrete feature graph builder and applier. |
|
||||
| `IFeature` | [src/common/Elsa.Features/Services/IFeature.cs](../../src/common/Elsa.Features/Services/IFeature.cs) | Feature lifecycle contract. |
|
||||
| `FeatureBase` | [src/common/Elsa.Features/Abstractions/FeatureBase.cs](../../src/common/Elsa.Features/Abstractions/FeatureBase.cs) | Base class for most code-first features. |
|
||||
| `DependsOnAttribute` | [src/common/Elsa.Features/Attributes/DependsOn.cs](../../src/common/Elsa.Features/Attributes/DependsOn.cs) | Declares feature dependencies. |
|
||||
| `DependencyOfAttribute` | [src/common/Elsa.Features/Attributes/DependencyOf.cs](../../src/common/Elsa.Features/Attributes/DependencyOf.cs) | Declares optional dependency relationships. |
|
||||
|
||||
## Lifecycle
|
||||
|
||||
Feature classes usually use three lifecycle methods:
|
||||
|
||||
1. `Configure()`: declare additional feature configuration, scan activities, or add endpoint assemblies.
|
||||
2. `ConfigureHostedServices()`: register hosted services with optional priority.
|
||||
3. `Apply()`: add concrete services, options, stores, handlers, endpoints, and providers to DI.
|
||||
|
||||
`Module.Apply()` topologically sorts configured features and dependencies, configures them once, filters features with missing optional dependencies, registers hosted services, applies services, and finally registers installed-feature metadata.
|
||||
|
||||
## Entry Points
|
||||
|
||||
The common public path is:
|
||||
|
||||
```csharp
|
||||
services.AddElsa(elsa =>
|
||||
{
|
||||
elsa
|
||||
.UseWorkflowManagement()
|
||||
.UseWorkflowRuntime()
|
||||
.UseWorkflowsApi();
|
||||
});
|
||||
```
|
||||
|
||||
Implementation links:
|
||||
|
||||
- [AddElsa and ConfigureElsa](../../src/modules/Elsa/Extensions/DependencyInjectionExtensions.cs)
|
||||
- [CreateModule and Use<T>](../../src/common/Elsa.Features/Extensions/DependencyInjectionExtensions.cs)
|
||||
- [ElsaFeature](../../src/modules/Elsa/Features/ElsaFeature.cs)
|
||||
- [AppFeature](../../src/modules/Elsa/Features/AppFeature.cs)
|
||||
|
||||
`AppFeature` is a small wrapper that lets application-specific configuration run after the default `ElsaFeature` dependencies.
|
||||
|
||||
## Feature Dependencies
|
||||
|
||||
Feature dependencies are explicit attributes. Examples:
|
||||
|
||||
- [WorkflowsFeature](../../src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs) depends on system clock, expressions, mediator, default formatters, multitenancy, and commit strategies.
|
||||
- [WorkflowManagementFeature](../../src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs) depends on string compression, mediator, memory cache, system clock, workflows, workflow definitions, and workflow instances.
|
||||
- [WorkflowsApiFeature](../../src/modules/Elsa.Workflows.Api/Features/WorkflowsApiFeature.cs) depends on workflow instances, management, runtime, and SAS tokens.
|
||||
|
||||
This is why feature classes are the best way to learn a module. They encode its runtime assumptions.
|
||||
|
||||
## Module Properties
|
||||
|
||||
`IModule.Properties` is used as a shared bag during feature configuration. A concrete example is FastEndpoints assembly collection in [Elsa.Api.Common/Extensions/ModuleExtensions.cs](../../src/common/Elsa.Api.Common/Extensions/ModuleExtensions.cs). Features call `AddFastEndpointsAssembly`, and later `AddFastEndpointsFromModule` registers all collected assemblies with FastEndpoints.
|
||||
|
||||
## Shell Features
|
||||
|
||||
Many modules also have `ShellFeatures/*Feature.cs`. These implement CShells interfaces and allow modular server hosts to activate feature sets from configuration or packages. Shell features are parallel to code-first features:
|
||||
|
||||
- Code-first feature: [Elsa.Diagnostics.StructuredLogs/Features/StructuredLogsFeature.cs](../../src/modules/Elsa.Diagnostics.StructuredLogs/Features/StructuredLogsFeature.cs)
|
||||
- Shell feature: [Elsa.Diagnostics.StructuredLogs/ShellFeatures/StructuredLogsFeature.cs](../../src/modules/Elsa.Diagnostics.StructuredLogs/ShellFeatures/StructuredLogsFeature.cs)
|
||||
|
||||
Use shell features when working on modular hosting, package discovery, or `Elsa.ModularServer.Web`. Use code-first features for normal host configuration and tests.
|
||||
|
||||
## Extension Method Pattern
|
||||
|
||||
Modules expose fluent extension methods in `Extensions/ModuleExtensions.cs` or related files. The method usually calls `module.Configure<TFeature>()` and returns `IModule`:
|
||||
|
||||
```csharp
|
||||
public static IModule UseWorkflowsApi(this IModule module, Action<WorkflowsApiFeature>? configure = default)
|
||||
{
|
||||
module.Configure(configure);
|
||||
return module;
|
||||
}
|
||||
```
|
||||
|
||||
When adding a new module, follow this shape:
|
||||
|
||||
- one `Features/*Feature.cs`
|
||||
- one `ShellFeatures/*Feature.cs` if the module must work with CShells
|
||||
- one `Extensions/ModuleExtensions.cs`
|
||||
- tests that prove the feature registers its core contracts
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- Do not register services in extension methods when the module already has a feature class. Put service registration in `Apply()`.
|
||||
- Do not bypass dependencies with direct service provider access in unrelated modules. Add a contract and dependency if the relationship is real.
|
||||
- Use `TryAdd*` for overridable defaults and normal `Add*` for deliberate multiple registrations such as handlers, validators, and descriptors.
|
||||
- If a feature uses `Module.Configure<OtherFeature>()`, verify that the other feature is already a dependency or that optional behavior is intentional.
|
||||
131
doc/wiki/persistence.md
Normal file
131
doc/wiki/persistence.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# Persistence
|
||||
|
||||
Elsa uses replaceable stores. Most features default to memory stores, then provider packages replace those stores with EF Core or other persistence implementations. Diagnostics structured logs also have a separate relational/SQLite persistence path that deliberately does not use EF Core.
|
||||
|
||||
## Store Replacement Pattern
|
||||
|
||||
Feature classes expose store factories. Persistence features replace those factories during `Configure()`.
|
||||
|
||||
Example from [EFCoreWorkflowRuntimePersistenceFeature](../../src/modules/Elsa.Persistence.EFCore/Modules/Runtime/WorkflowRuntimePersistenceFeature.cs):
|
||||
|
||||
- replace `WorkflowRuntimeFeature.TriggerStore`
|
||||
- replace `BookmarkStore`
|
||||
- replace `BookmarkQueueStore`
|
||||
- replace `WorkflowExecutionLogStore`
|
||||
- replace `ActivityExecutionLogStore`
|
||||
- replace key-value store
|
||||
|
||||
Management persistence follows the same idea for definition and instance stores.
|
||||
|
||||
## EF Core Shared Infrastructure
|
||||
|
||||
Shared EF Core infrastructure lives in [Elsa.Persistence.EFCore.Common](../../src/modules/Elsa.Persistence.EFCore.Common) and [Elsa.Persistence.EFCore](../../src/modules/Elsa.Persistence.EFCore).
|
||||
|
||||
Important base types:
|
||||
|
||||
- [PersistenceFeatureBase](../../src/modules/Elsa.Persistence.EFCore.Common/PersistenceFeatureBase.cs)
|
||||
- [PersistenceShellFeatureBase](../../src/modules/Elsa.Persistence.EFCore.Common/PersistenceShellFeatureBase.cs)
|
||||
- [CombinedPersistenceShellFeatureBase](../../src/modules/Elsa.Persistence.EFCore.Common/CombinedPersistenceShellFeatureBase.cs)
|
||||
- [ElsaDbContextBase](../../src/modules/Elsa.Persistence.EFCore.Common/ElsaDbContextBase.cs)
|
||||
|
||||
`PersistenceFeatureBase` registers `IDbContextFactory<TDbContext>`, migration options, tenant-aware context factory decoration, and tenant model handlers.
|
||||
|
||||
## EF Core Module Slices
|
||||
|
||||
The shared EF Core module contains slices for:
|
||||
|
||||
- [Management](../../src/modules/Elsa.Persistence.EFCore/Modules/Management)
|
||||
- [Runtime](../../src/modules/Elsa.Persistence.EFCore/Modules/Runtime)
|
||||
- [Identity](../../src/modules/Elsa.Persistence.EFCore/Modules/Identity)
|
||||
- [Tenants](../../src/modules/Elsa.Persistence.EFCore/Modules/Tenants)
|
||||
- [Labels](../../src/modules/Elsa.Persistence.EFCore/Modules/Labels)
|
||||
- [Alterations](../../src/modules/Elsa.Persistence.EFCore/Modules/Alterations)
|
||||
|
||||
Each slice has a DbContext, configurations, store implementations, feature classes, and shell feature classes.
|
||||
|
||||
## Provider Packages
|
||||
|
||||
Provider packages configure database-specific EF Core options and migrations:
|
||||
|
||||
- [Elsa.Persistence.EFCore.Sqlite](../../src/modules/Elsa.Persistence.EFCore.Sqlite)
|
||||
- [Elsa.Persistence.EFCore.SqlServer](../../src/modules/Elsa.Persistence.EFCore.SqlServer)
|
||||
- [Elsa.Persistence.EFCore.PostgreSql](../../src/modules/Elsa.Persistence.EFCore.PostgreSql)
|
||||
- [Elsa.Persistence.EFCore.MySql](../../src/modules/Elsa.Persistence.EFCore.MySql)
|
||||
- [Elsa.Persistence.EFCore.Oracle](../../src/modules/Elsa.Persistence.EFCore.Oracle)
|
||||
|
||||
Combined provider shell features such as `SqliteWorkflowPersistenceShellFeature` let modular hosts configure workflow persistence once and share settings with dependent definition, instance, and runtime persistence features.
|
||||
|
||||
## Typical Host Configuration
|
||||
|
||||
The reference server configures SQLite persistence for management and runtime separately:
|
||||
|
||||
```csharp
|
||||
elsa.UseWorkflowManagement(management =>
|
||||
{
|
||||
management.UseEntityFrameworkCore(ef => ef.UseSqlite());
|
||||
});
|
||||
|
||||
elsa.UseWorkflowRuntime(runtime =>
|
||||
{
|
||||
runtime.UseEntityFrameworkCore(ef => ef.UseSqlite());
|
||||
});
|
||||
```
|
||||
|
||||
See [src/apps/Elsa.Server.Web/Program.cs](../../src/apps/Elsa.Server.Web/Program.cs).
|
||||
|
||||
## Migrations
|
||||
|
||||
EF Core migrations are controlled by feature options such as `RunMigrations`. The base persistence feature registers startup tasks that run migrations when enabled.
|
||||
|
||||
Migration-related files:
|
||||
|
||||
- [MigrationOptions](../../src/modules/Elsa.Persistence.EFCore.Common/MigrationOptions.cs)
|
||||
- [RunMigrationsStartupTask](../../src/modules/Elsa.Persistence.EFCore.Common/RunMigrationsStartupTask.cs)
|
||||
- [scripts/migrations/README.md](../../scripts/migrations/README.md)
|
||||
|
||||
When adding an entity or changing persisted shape, check every provider package and test provider-specific migration behavior where practical.
|
||||
|
||||
## Tenant Awareness
|
||||
|
||||
EF Core persistence decorates `IDbContextFactory<TDbContext>` with `TenantAwareDbContextFactory<TDbContext>` and registers model/saving handlers:
|
||||
|
||||
- `ApplyTenantId`
|
||||
- `SetTenantIdFilter`
|
||||
|
||||
Tenant conventions are documented in ADRs:
|
||||
|
||||
- [ADR 0008: Empty String As Default Tenant ID](../adr/0008-empty-string-as-default-tenant-id.md)
|
||||
- [ADR 0009: Asterisk Sentinel Value For Tenant-Agnostic Entities](../adr/0009-asterisk-sentinel-value-for-tenant-agnostic-entities.md)
|
||||
|
||||
## Structured Log Persistence
|
||||
|
||||
Structured log persistence is intentionally separate from EF Core. The active feature plan is [005 structured log persistence](../../specs/005-structured-log-persistence/plan.md).
|
||||
|
||||
Packages:
|
||||
|
||||
- [Elsa.Diagnostics.StructuredLogs](../../src/modules/Elsa.Diagnostics.StructuredLogs): core capture, API, hub, provider/store contracts, default in-memory store.
|
||||
- [Elsa.Diagnostics.StructuredLogs.Persistence.Relational](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Relational): provider-neutral relational store, SQL builder, mapper, retention service, write buffer.
|
||||
- [Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite): SQLite connection factory, dialect, FluentMigrator runner, startup migration/cleanup service.
|
||||
|
||||
This path uses explicit SQL and FluentMigrator. It stores timestamps as UTC ISO-8601 text and JSON payloads as text in SQLite.
|
||||
|
||||
## Adding A Store
|
||||
|
||||
When adding a new store implementation:
|
||||
|
||||
1. Identify the feature contract that owns the store.
|
||||
2. Keep the core module provider-neutral.
|
||||
3. Add the concrete store in the persistence/provider module.
|
||||
4. Replace the feature's store factory in the persistence feature.
|
||||
5. Add unit tests for store-specific query behavior if logic is nontrivial.
|
||||
6. Add integration tests for provider behavior, migrations, and multi-target concerns where practical.
|
||||
|
||||
## Persistence Risk Checklist
|
||||
|
||||
- Does the change affect multiple target frameworks?
|
||||
- Does it need provider-specific migrations?
|
||||
- Does it preserve tenant filtering?
|
||||
- Does it update both definition and instance stores if both shapes changed?
|
||||
- Does it require API/client DTO updates?
|
||||
- Does it alter runtime recovery, bookmark, or trigger semantics?
|
||||
- Does it need retention, cleanup, or migration documentation?
|
||||
64
doc/wiki/repository-map.md
Normal file
64
doc/wiki/repository-map.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Repository Map
|
||||
|
||||
Elsa Core is organized as a large multi-project .NET solution. The repo favors small, independently packaged modules over one monolith.
|
||||
|
||||
## Top-Level Layout
|
||||
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| [src/apps](../../src/apps) | Runnable reference hosts, load-balancer host, modular server host, and sample package. |
|
||||
| [src/modules](../../src/modules) | Elsa product modules: workflow engine, runtime, management, APIs, HTTP, identity, persistence, diagnostics, scripting, scheduling, tenants, labels, resilience, and more. |
|
||||
| [src/common](../../src/common) | Shared infrastructure such as feature/module plumbing, mediator, API helpers, and test helpers. |
|
||||
| [src/clients](../../src/clients) | Client packages, currently including the Elsa API client. |
|
||||
| [src/extensions](../../src/extensions) | Extension packages that are not core modules. |
|
||||
| [test/unit](../../test/unit) | Fast unit tests scoped to individual modules or services. |
|
||||
| [test/integration](../../test/integration) | In-process tests that compose multiple Elsa services. |
|
||||
| [test/component](../../test/component) | Larger host-level and persistence-oriented scenarios. |
|
||||
| [test/performance](../../test/performance) | Benchmark and throughput-oriented tests. |
|
||||
| [build](../../build) | NUKE build project and CI build wiring. |
|
||||
| [doc](../../doc) | ADRs, QA notes, agent logs, bounty docs, and this wiki. |
|
||||
| [specs](../../specs) | Spec Kit feature specs, plans, tasks, contracts, and quickstarts. |
|
||||
| [design](../../design) | Logos, screenshots, and visual assets used by public docs and README files. |
|
||||
|
||||
## Major Module Families
|
||||
|
||||
| Family | Projects | What they own |
|
||||
| --- | --- | --- |
|
||||
| Base host package | [Elsa](../../src/modules/Elsa) | `AddElsa`, `ElsaFeature`, default workflow feature wiring. |
|
||||
| Workflow engine | [Elsa.Workflows.Core](../../src/modules/Elsa.Workflows.Core) | Activities, execution contexts, pipelines, serialization, variables, bookmarks, graphs, flowchart primitives. |
|
||||
| Workflow management | [Elsa.Workflows.Management](../../src/modules/Elsa.Workflows.Management) | Definitions, instances, stores, import/export, materializers, validation, descriptors. |
|
||||
| Workflow runtime | [Elsa.Workflows.Runtime](../../src/modules/Elsa.Workflows.Runtime) and [Elsa.Workflows.Runtime.Distributed](../../src/modules/Elsa.Workflows.Runtime.Distributed) | Dispatch, triggers, bookmark queues, runtime logs, background activity scheduling, recovery, distributed runtime support. |
|
||||
| Workflow API | [Elsa.Workflows.Api](../../src/modules/Elsa.Workflows.Api) and [Elsa.Api.Common](../../src/common/Elsa.Api.Common) | FastEndpoints registration, workflow endpoints, real-time workflow updates, API serialization. |
|
||||
| Expression languages | [Elsa.Expressions](../../src/modules/Elsa.Expressions), [CSharp](../../src/modules/Elsa.Expressions.CSharp), [JavaScript](../../src/modules/Elsa.Expressions.JavaScript), [Python](../../src/modules/Elsa.Expressions.Python), [Liquid](../../src/modules/Elsa.Expressions.Liquid) | Expression evaluation and language-specific activities/descriptors. |
|
||||
| Transport/activity packages | [Elsa.Http](../../src/modules/Elsa.Http), [Elsa.Scheduling](../../src/modules/Elsa.Scheduling), [Elsa.Resilience](../../src/modules/Elsa.Resilience) | HTTP triggers and calls, scheduled triggers, resilience strategies. |
|
||||
| Persistence | [Elsa.Persistence.EFCore](../../src/modules/Elsa.Persistence.EFCore), provider packages under `Elsa.Persistence.EFCore.*`, and structured-log persistence packages | EF Core stores and provider-specific configuration/migrations. |
|
||||
| Security and tenancy | [Elsa.Identity](../../src/modules/Elsa.Identity), [Elsa.Tenants](../../src/modules/Elsa.Tenants), [Elsa.Tenants.AspNetCore](../../src/modules/Elsa.Tenants.AspNetCore), [Elsa.SasTokens](../../src/modules/Elsa.SasTokens) | Users, applications, roles, API keys, tenants, tenant-aware routing, SAS tokens. |
|
||||
| Diagnostics | [Elsa.Diagnostics.StructuredLogs](../../src/modules/Elsa.Diagnostics.StructuredLogs), [Relational](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Relational), [Sqlite](../../src/modules/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite) | Structured `ILogger` capture, live feed, REST/SignalR endpoints, in-memory and SQLite storage. |
|
||||
| Shells and modular hosting | [Elsa.Shells.Api](../../src/modules/Elsa.Shells.Api), CShells-facing shell feature classes throughout modules | Runtime-configurable feature loading for modular hosts. |
|
||||
|
||||
## Reference Hosts
|
||||
|
||||
- [Elsa.Server.Web](../../src/apps/Elsa.Server.Web) is the most useful all-up ASP.NET Core sample. Its [Program.cs](../../src/apps/Elsa.Server.Web/Program.cs) shows typical module composition with identity, EF Core SQLite, runtime, management, HTTP, scheduling, scripting, multitenancy, and optional structured logs.
|
||||
- [Elsa.ModularServer.Web](../../src/apps/Elsa.ModularServer.Web) demonstrates modular package loading through Nuplane and shell features.
|
||||
- [Elsa.Server.LoadBalancer](../../src/apps/Elsa.Server.LoadBalancer) is a load-balancer host.
|
||||
- [Elsa.SamplePackage](../../src/apps/Elsa.SamplePackage) is a minimal package-style feature sample.
|
||||
|
||||
## Build And Package Files
|
||||
|
||||
- [Directory.Build.props](../../Directory.Build.props) contains shared MSBuild settings.
|
||||
- [src/Directory.Build.props](../../src/Directory.Build.props) multi-targets source packages for `net8.0`, `net9.0`, and `net10.0`.
|
||||
- [Directory.Packages.props](../../Directory.Packages.props) centrally manages package versions, including conditional versions for .NET 8/9 versus .NET 10.
|
||||
- [build/Build.cs](../../build/Build.cs) defines the NUKE build, test, and package targets.
|
||||
|
||||
## How To Find Code Fast
|
||||
|
||||
Use the feature class first. Most modules have a `Features/*Feature.cs` and often a parallel `ShellFeatures/*Feature.cs`. The feature class tells you what the module registers and what other features it depends on. After that, follow contracts and service registrations into implementation files.
|
||||
|
||||
Good first searches:
|
||||
|
||||
```bash
|
||||
rg "class .*Feature" src/modules src/common
|
||||
rg "interface I.*Store" src/modules
|
||||
rg "AddScoped|AddSingleton|TryAdd" src/modules/Elsa.Workflows.Runtime/Features
|
||||
rg "Get\\(|Post\\(|Delete\\(" src/modules/Elsa.Workflows.Api/Endpoints
|
||||
```
|
||||
96
doc/wiki/specs-and-adrs.md
Normal file
96
doc/wiki/specs-and-adrs.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Specs And ADRs
|
||||
|
||||
The repository carries two useful design-history systems:
|
||||
|
||||
- ADRs in [doc/adr](../adr), which document durable architecture decisions.
|
||||
- Spec Kit feature specs in [specs](../../specs), which document planned and recently implemented feature work.
|
||||
|
||||
Use both before making architectural changes. Specs often explain the "why now"; ADRs explain decisions intended to outlive a single feature.
|
||||
|
||||
## ADR Index
|
||||
|
||||
The table of contents is [doc/adr/toc.md](../adr/toc.md).
|
||||
|
||||
Current ADRs:
|
||||
|
||||
| ADR | Topic |
|
||||
| --- | --- |
|
||||
| [0001](../adr/0001-record-architecture-decisions.md) | Record architecture decisions. |
|
||||
| [0002](../adr/0002-fault-propagation-from-child-to-parent-activities.md) | Fault propagation from child to parent activities. |
|
||||
| [0003](../adr/0003-direct-bookmark-management-in-workflowexecutioncontext.md) | Direct bookmark management in `WorkflowExecutionContext`. |
|
||||
| [0004](../adr/0004-activity-execution-snapshots.md) | Activity execution snapshots. |
|
||||
| [0005](../adr/0005-token-centric-flowchart-execution-model.md) | Token-centric flowchart execution. |
|
||||
| [0006](../adr/0006-tenant-deleted-event.md) | Tenant deleted event. |
|
||||
| [0007](../adr/0007-adoption-of-explicit-merge-modes-for-flowchart-joins.md) | Explicit merge modes for flowchart joins. |
|
||||
| [0008](../adr/0008-empty-string-as-default-tenant-id.md) | Empty string as default tenant ID. |
|
||||
| [0009](../adr/0009-asterisk-sentinel-value-for-tenant-agnostic-entities.md) | Asterisk sentinel value for tenant-agnostic entities. |
|
||||
| [0010](../adr/0010-default-admin-user-bootstrap-for-initial-identity-access.md) | Default admin user bootstrap for initial identity access. |
|
||||
|
||||
## Active And Recent Specs
|
||||
|
||||
| Spec | Area | Why it matters |
|
||||
| --- | --- | --- |
|
||||
| [001 shell reload API](../../specs/001-shell-reload-api/spec.md) | Shell management | Explains reload behavior for modular/shell hosts. |
|
||||
| [002 graceful shutdown](../../specs/002-graceful-shutdown/spec.md) | Runtime | Defines quiescence, ingress sources, drain orchestration, interrupted recovery, and runtime admin endpoints. |
|
||||
| [003 live server logs](../../specs/003-live-server-logs/spec.md) | Diagnostics precursor | Earlier live server logs work that led to structured diagnostics. |
|
||||
| [004 diagnostics structured logs](../../specs/004-diagnostics-structured-logs/spec.md) | Diagnostics | Refactors server logs into structured log diagnostics with semantic `ILogger` capture. |
|
||||
| [005 structured log persistence](../../specs/005-structured-log-persistence/spec.md) | Diagnostics persistence | Adds storage abstraction, relational persistence, SQLite durability, migrations, write queue, and retention. |
|
||||
|
||||
Each spec folder usually contains:
|
||||
|
||||
- `spec.md`: product/user-facing requirements
|
||||
- `plan.md`: architecture and implementation plan
|
||||
- `research.md`: decisions and tradeoffs
|
||||
- `data-model.md`: domain model
|
||||
- `contracts`: API/provider contracts
|
||||
- `quickstart.md`: usage validation
|
||||
- `tasks.md`: implementation backlog
|
||||
- `checklists/requirements.md`: requirement quality checks
|
||||
|
||||
## Reading Order For Runtime Work
|
||||
|
||||
For runtime behavior, read in this order:
|
||||
|
||||
1. [Workflow Runtime wiki page](workflow-runtime.md)
|
||||
2. [specs/002-graceful-shutdown/plan.md](../../specs/002-graceful-shutdown/plan.md)
|
||||
3. [ADR 0003](../adr/0003-direct-bookmark-management-in-workflowexecutioncontext.md)
|
||||
4. [ADR 0004](../adr/0004-activity-execution-snapshots.md)
|
||||
5. affected runtime service and tests
|
||||
|
||||
## Reading Order For Flowchart Work
|
||||
|
||||
1. [Workflow Core wiki page](workflow-core.md)
|
||||
2. [ADR 0005](../adr/0005-token-centric-flowchart-execution-model.md)
|
||||
3. [ADR 0007](../adr/0007-adoption-of-explicit-merge-modes-for-flowchart-joins.md)
|
||||
4. [Flowchart activities](../../src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities)
|
||||
5. flowchart unit/integration tests
|
||||
|
||||
## Reading Order For Tenancy Work
|
||||
|
||||
1. [Identity, Tenancy, And Security](identity-tenancy-security.md)
|
||||
2. [ADR 0008](../adr/0008-empty-string-as-default-tenant-id.md)
|
||||
3. [ADR 0009](../adr/0009-asterisk-sentinel-value-for-tenant-agnostic-entities.md)
|
||||
4. tenant feature and persistence code
|
||||
5. tenant unit tests
|
||||
|
||||
## Reading Order For Diagnostics Work
|
||||
|
||||
1. [Diagnostics Structured Logs](diagnostics-structured-logs.md)
|
||||
2. [specs/004-diagnostics-structured-logs/plan.md](../../specs/004-diagnostics-structured-logs/plan.md)
|
||||
3. [specs/005-structured-log-persistence/plan.md](../../specs/005-structured-log-persistence/plan.md)
|
||||
4. structured logs core package
|
||||
5. relational and SQLite persistence packages
|
||||
6. structured logs unit/integration tests
|
||||
|
||||
## When To Write An ADR
|
||||
|
||||
Write or update an ADR when a decision:
|
||||
|
||||
- changes workflow execution semantics
|
||||
- changes persisted data conventions
|
||||
- changes tenant/security behavior
|
||||
- introduces a durable architectural boundary
|
||||
- rejects an obvious alternative that future contributors may ask about
|
||||
- affects multiple modules or provider packages
|
||||
|
||||
Feature-specific decisions can stay in `specs/*/research.md` unless they are expected to outlive the feature or guide unrelated future work.
|
||||
136
doc/wiki/testing-guide.md
Normal file
136
doc/wiki/testing-guide.md
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
# Testing Guide
|
||||
|
||||
Elsa uses unit, integration, component, and performance tests. The best test choice depends on what boundary you are changing.
|
||||
|
||||
The detailed internal testing strategy is [doc/qa/test-guidelines.md](../qa/test-guidelines.md). This page is a wiki-sized map.
|
||||
|
||||
## Test Folders
|
||||
|
||||
| Folder | Purpose |
|
||||
| --- | --- |
|
||||
| [test/unit](../../test/unit) | Isolated services, activities, converters, stores, validators, descriptors, and small logic. |
|
||||
| [test/integration](../../test/integration) | In-process composition of workflow engine services, expressions, activities, runtime behavior, and module integration. |
|
||||
| [test/component](../../test/component) | Host-level workflows, persistence-backed scenarios, HTTP workflows, clustered behavior, and lifecycle behavior. |
|
||||
| [test/performance](../../test/performance) | Benchmark and throughput scenarios. |
|
||||
|
||||
Shared helpers:
|
||||
|
||||
- [Elsa.Testing.Shared](../../src/common/Elsa.Testing.Shared)
|
||||
- [Elsa.Testing.Shared.Integration](../../src/common/Elsa.Testing.Shared.Integration)
|
||||
- [Elsa.Testing.Shared.Component](../../src/common/Elsa.Testing.Shared.Component)
|
||||
|
||||
## Choosing A Test Type
|
||||
|
||||
| Change | Preferred test |
|
||||
| --- | --- |
|
||||
| Activity logic without persistence or scheduler | Unit test with `ActivityTestFixture`. |
|
||||
| Expression evaluator/parser behavior | Unit test or language-specific integration test. |
|
||||
| Workflow execution semantics | Integration test with workflow runner/test fixture. |
|
||||
| Bookmarks, triggers, runtime dispatch, recovery | Integration test; component test if host lifecycle or persistence matters. |
|
||||
| API endpoint shape or authorization | Unit/integration endpoint test if existing pattern exists; component test for host-level behavior. |
|
||||
| EF Core store or migration | Provider-specific integration/component test. |
|
||||
| HTTP workflows | Component test under HTTP workflow scenarios. |
|
||||
| Structured log SQLite persistence | SQLite integration test project. |
|
||||
|
||||
## Useful Commands
|
||||
|
||||
Restore first when starting from a clean checkout or after dependency changes:
|
||||
|
||||
```bash
|
||||
./build.sh Restore --ignore-failed-sources
|
||||
```
|
||||
|
||||
Build the solution with direct `dotnet` commands:
|
||||
|
||||
```bash
|
||||
dotnet restore Elsa.sln --ignore-failed-sources
|
||||
dotnet build Elsa.sln --no-restore
|
||||
```
|
||||
|
||||
Run all tests with direct `dotnet` commands:
|
||||
|
||||
```bash
|
||||
dotnet restore Elsa.sln --ignore-failed-sources
|
||||
dotnet test Elsa.sln --no-restore
|
||||
```
|
||||
|
||||
Run the NUKE test target after the resilient restore:
|
||||
|
||||
```bash
|
||||
./build.sh Test
|
||||
```
|
||||
|
||||
Run targeted projects:
|
||||
|
||||
```bash
|
||||
dotnet restore test/unit/Elsa.Workflows.Core.UnitTests/Elsa.Workflows.Core.UnitTests.csproj --ignore-failed-sources
|
||||
dotnet test test/unit/Elsa.Workflows.Core.UnitTests/Elsa.Workflows.Core.UnitTests.csproj --no-restore
|
||||
|
||||
dotnet restore test/integration/Elsa.Workflows.IntegrationTests/Elsa.Workflows.IntegrationTests.csproj --ignore-failed-sources
|
||||
dotnet test test/integration/Elsa.Workflows.IntegrationTests/Elsa.Workflows.IntegrationTests.csproj --no-restore
|
||||
|
||||
dotnet restore test/component/Elsa.Workflows.ComponentTests/Elsa.Workflows.ComponentTests.csproj --ignore-failed-sources
|
||||
dotnet test test/component/Elsa.Workflows.ComponentTests/Elsa.Workflows.ComponentTests.csproj --no-restore
|
||||
|
||||
dotnet restore test/integration/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests.csproj --ignore-failed-sources
|
||||
dotnet test test/integration/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests/Elsa.Diagnostics.StructuredLogs.Persistence.Sqlite.IntegrationTests.csproj --no-restore
|
||||
```
|
||||
|
||||
Run ElsaScript DSL tests:
|
||||
|
||||
```bash
|
||||
./run-dsl-tests.sh
|
||||
```
|
||||
|
||||
## Activity Tests
|
||||
|
||||
Use `ActivityTestFixture` from [Elsa.Testing.Shared](../../src/common/Elsa.Testing.Shared). Activity tests should assert activity outputs, variables, scheduled child activities, outcomes, and fault behavior without needing a host.
|
||||
|
||||
Examples live in:
|
||||
|
||||
- [test/unit/Elsa.Activities.UnitTests](../../test/unit/Elsa.Activities.UnitTests)
|
||||
- [test/unit/Elsa.Workflows.Core.UnitTests](../../test/unit/Elsa.Workflows.Core.UnitTests)
|
||||
|
||||
## Workflow Integration Tests
|
||||
|
||||
Use integration helpers when activity behavior depends on workflow runner behavior, variables, activity outputs, expressions, or bookmarks.
|
||||
|
||||
Examples:
|
||||
|
||||
- [test/integration/Elsa.Workflows.IntegrationTests](../../test/integration/Elsa.Workflows.IntegrationTests)
|
||||
- [test/integration/Elsa.Activities.IntegrationTests](../../test/integration/Elsa.Activities.IntegrationTests)
|
||||
- [test/integration/Elsa.JavaScript.IntegrationTests](../../test/integration/Elsa.JavaScript.IntegrationTests)
|
||||
|
||||
## Component Tests
|
||||
|
||||
Component tests use host fixtures. The base class is [AppComponentTest](../../test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs). It creates a scope, pushes the default tenant context, tracks in-flight workflows, and waits for them to idle on dispose.
|
||||
|
||||
Fixture landmarks:
|
||||
|
||||
- [App](../../test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs)
|
||||
- [Cluster](../../test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Cluster.cs)
|
||||
- [WorkflowServer](../../test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs)
|
||||
- [Infrastructure](../../test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Infrastructure.cs)
|
||||
|
||||
Use component tests when host lifecycle, HTTP server behavior, actual persistence, distributed runtime behavior, or multiple services working together are essential to the assertion.
|
||||
|
||||
## Structured Log Tests
|
||||
|
||||
Structured log tests are split by layer:
|
||||
|
||||
- core module unit tests
|
||||
- core module integration tests
|
||||
- relational unit tests
|
||||
- SQLite integration tests
|
||||
|
||||
This mirrors the architecture: core capture and API behavior should not require SQLite; SQLite tests should prove durability, migrations, retention, timestamp storage, queue overflow, and filtering.
|
||||
|
||||
## Good Test Hygiene
|
||||
|
||||
- Prefer targeted project tests while iterating.
|
||||
- Add a regression test for a bug before or alongside the fix.
|
||||
- Keep arrange/setup in constructors or small helpers when it repeats.
|
||||
- Use `IAsyncDisposable` or xUnit async lifetime patterns for async teardown.
|
||||
- Avoid sleeps when a deterministic signal or store assertion is available.
|
||||
- For multi-targeting issues, consider whether all target frameworks need coverage.
|
||||
- When changing shared runtime or persistence behavior, finish with a broader build/test run if feasible.
|
||||
97
doc/wiki/workflow-api.md
Normal file
97
doc/wiki/workflow-api.md
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
# Workflow API
|
||||
|
||||
The workflow API exposes management, runtime, descriptors, execution logs, tasks, installed features, runtime admin, and real-time workflow updates. It uses FastEndpoints with Elsa-specific serializer configuration.
|
||||
|
||||
Start in [src/modules/Elsa.Workflows.Api](../../src/modules/Elsa.Workflows.Api) and shared API infrastructure in [src/common/Elsa.Api.Common](../../src/common/Elsa.Api.Common).
|
||||
|
||||
## Feature Wiring
|
||||
|
||||
[WorkflowsApiFeature](../../src/modules/Elsa.Workflows.Api/Features/WorkflowsApiFeature.cs):
|
||||
|
||||
- depends on workflow instances, workflow management, workflow runtime, and SAS tokens
|
||||
- registers its endpoint assembly with the module
|
||||
- calls `AddFastEndpointsFromModule()`
|
||||
- configures API serialization
|
||||
- registers `IWorkflowDefinitionLinker`
|
||||
- registers read-only-mode authorization requirement handling
|
||||
- registers workflow instance export naming
|
||||
|
||||
The module extension is [UseWorkflowsApi](../../src/modules/Elsa.Workflows.Api/Extensions/ModuleExtensions.cs).
|
||||
|
||||
## Route Prefix
|
||||
|
||||
The default route prefix is `elsa/api`, defined in [ApiEndpointOptions](../../src/modules/Elsa.Workflows.Api/Options/ApiEndpointOptions.cs). ASP.NET hosts apply it with [UseWorkflowsApi](../../src/common/Elsa.Api.Common/Extensions/WebApplicationExtensions.cs):
|
||||
|
||||
```csharp
|
||||
var routePrefix = app.Services.GetRequiredService<IOptions<ApiEndpointOptions>>().Value.RoutePrefix;
|
||||
app.UseWorkflowsApi(routePrefix);
|
||||
```
|
||||
|
||||
With the default prefix, endpoint paths look like `/elsa/api/workflow-definitions`.
|
||||
|
||||
## FastEndpoints Registration
|
||||
|
||||
FastEndpoints assemblies are collected through module properties:
|
||||
|
||||
- [AddFastEndpointsAssembly](../../src/common/Elsa.Api.Common/Extensions/ModuleExtensions.cs)
|
||||
- [AddFastEndpointsFromModule](../../src/common/Elsa.Api.Common/Extensions/ModuleExtensions.cs)
|
||||
|
||||
This allows multiple features to contribute endpoints before FastEndpoints is registered.
|
||||
|
||||
## Endpoint Categories
|
||||
|
||||
| Category | Folder | Examples |
|
||||
| --- | --- | --- |
|
||||
| Workflow definitions | [Endpoints/WorkflowDefinitions](../../src/modules/Elsa.Workflows.Api/Endpoints/WorkflowDefinitions) | list, get, post, publish, retract, delete, import, export, dispatch, execute, graph, refresh, reload. |
|
||||
| Workflow instances | [Endpoints/WorkflowInstances](../../src/modules/Elsa.Workflows.Api/Endpoints/WorkflowInstances) | list, get, delete, cancel, bulk cancel/delete, import/export, execution state, variables, journal. |
|
||||
| Activity executions | [Endpoints/ActivityExecutions](../../src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutions) and [ActivityExecutionSummaries](../../src/modules/Elsa.Workflows.Api/Endpoints/ActivityExecutionSummaries) | list, get, count, report, call stack, summaries. |
|
||||
| Descriptors | [ActivityDescriptors](../../src/modules/Elsa.Workflows.Api/Endpoints/ActivityDescriptors), [VariableTypes](../../src/modules/Elsa.Workflows.Api/Endpoints/VariableTypes), [StorageDrivers](../../src/modules/Elsa.Workflows.Api/Endpoints/StorageDrivers), [IncidentStrategies](../../src/modules/Elsa.Workflows.Api/Endpoints/IncidentStrategies), [CommitStrategies](../../src/modules/Elsa.Workflows.Api/Endpoints/CommitStrategies), [Scripting](../../src/modules/Elsa.Workflows.Api/Endpoints/Scripting) | designer metadata and option providers. |
|
||||
| Runtime admin | [Endpoints/RuntimeAdmin](../../src/modules/Elsa.Workflows.Api/Endpoints/RuntimeAdmin) | status, pause, resume, force drain. |
|
||||
| Events and tasks | [Endpoints/Events](../../src/modules/Elsa.Workflows.Api/Endpoints/Events), [Endpoints/Tasks](../../src/modules/Elsa.Workflows.Api/Endpoints/Tasks) | trigger event, complete task. |
|
||||
| Package and features | [Endpoints/Package](../../src/modules/Elsa.Workflows.Api/Endpoints/Package), [Endpoints/Features](../../src/modules/Elsa.Workflows.Api/Endpoints/Features) | package version and installed feature metadata. |
|
||||
|
||||
## Common Endpoint Shape
|
||||
|
||||
Endpoint classes typically derive from Elsa API base classes in [Elsa.Api.Common](../../src/common/Elsa.Api.Common). They configure route, verb, permissions, and response shape in `Configure()`, then implement either `ExecuteAsync` or `HandleAsync` depending on the FastEndpoints pattern used by that area of the module.
|
||||
|
||||
When adding endpoints:
|
||||
|
||||
- keep one endpoint per folder/action
|
||||
- keep request and response models near the endpoint
|
||||
- follow the `ExecuteAsync` or `HandleAsync` pattern used by nearby endpoints in the same area
|
||||
- use `ConfigurePermissions` for protected operations
|
||||
- use the configured API serializer rather than custom JSON settings
|
||||
- add route examples to relevant docs when behavior is externally visible
|
||||
|
||||
## Real-Time Workflow Updates
|
||||
|
||||
Real-time updates live under [RealTime](../../src/modules/Elsa.Workflows.Api/RealTime):
|
||||
|
||||
- [WorkflowInstanceHub](../../src/modules/Elsa.Workflows.Api/RealTime/Hubs/WorkflowInstanceHub.cs)
|
||||
- [BroadcastWorkflowProgress](../../src/modules/Elsa.Workflows.Api/RealTime/Handlers/BroadcastWorkflowProgress.cs)
|
||||
- client contract [IWorkflowInstanceClient](../../src/modules/Elsa.Workflows.Api/RealTime/Contracts/IWorkflowInstanceClient.cs)
|
||||
- messages for activity and workflow execution updates
|
||||
|
||||
Hosts map these hubs with `app.UseWorkflowsSignalRHubs()` when SignalR is enabled.
|
||||
|
||||
## Authorization And Read-Only Mode
|
||||
|
||||
Workflow API registers [NotReadOnlyRequirementHandler](../../src/modules/Elsa.Workflows.Api/Requirements/NotReadOnlyRequirement.cs) and the policy name in [AuthorizationPolicies](../../src/modules/Elsa.Workflows.Api/Constants/AuthorizationPolicies.cs). Mutable workflow definition endpoints use this policy to honor management read-only mode.
|
||||
|
||||
Identity and API key setup are supplied by `Elsa.Identity`; see [Identity, Tenancy, And Security](identity-tenancy-security.md).
|
||||
|
||||
## API Client
|
||||
|
||||
The generated or hand-maintained client project is [src/clients/Elsa.Api.Client](../../src/clients/Elsa.Api.Client). When endpoint contracts or enums change, check whether the client has mirrored models that need updating. The graceful shutdown plan explicitly called out mirroring `WorkflowSubStatus.Interrupted` in the API client.
|
||||
|
||||
## JSON Serialization Errors
|
||||
|
||||
Hosts can use [UseJsonSerializationErrorHandler](../../src/modules/Elsa.Workflows.Api/Extensions/ApplicationBuilderExtensions.cs), which installs middleware that returns JSON error responses for serialization failures. The reference server maps it after workflow API endpoints.
|
||||
|
||||
## Endpoint Discovery Command
|
||||
|
||||
To quickly list routes:
|
||||
|
||||
```bash
|
||||
rg "Get\\(|Post\\(|Delete\\(|Put\\(|Patch\\(|Routes\\(|Verbs\\(" src/modules/Elsa.Workflows.Api/Endpoints src/modules/Elsa.Diagnostics.StructuredLogs/Endpoints -g "Endpoint.cs"
|
||||
```
|
||||
152
doc/wiki/workflow-core.md
Normal file
152
doc/wiki/workflow-core.md
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
# Workflow Core
|
||||
|
||||
Workflow core is the engine layer. It defines activities, execution contexts, scheduling primitives, inputs and outputs, variables, bookmarks, serialization, execution pipelines, flowchart behavior, and the core runner.
|
||||
|
||||
Start in [src/modules/Elsa.Workflows.Core](../../src/modules/Elsa.Workflows.Core).
|
||||
|
||||
## Feature Wiring
|
||||
|
||||
[WorkflowsFeature](../../src/modules/Elsa.Workflows.Core/Features/WorkflowsFeature.cs) registers the core services:
|
||||
|
||||
- `IActivityInvoker`
|
||||
- `IWorkflowRunner`
|
||||
- `IActivityTestRunner`
|
||||
- `IActivityVisitor`
|
||||
- `IWorkflowGraphBuilder`
|
||||
- `IWorkflowStateExtractor`
|
||||
- `IActivitySchedulerFactory`
|
||||
- workflow and activity execution pipelines
|
||||
- activity registry, descriptor, factory, and lookup services
|
||||
- storage drivers
|
||||
- serializers
|
||||
- incident strategies
|
||||
- UI hint handlers
|
||||
- identity and hashing services
|
||||
|
||||
The feature also configures default workflow and activity pipelines. The umbrella [ElsaFeature](../../src/modules/Elsa/Features/ElsaFeature.cs) calls `WithDefaultWorkflowExecutionPipeline()` and `WithDefaultActivityExecutionPipeline()`.
|
||||
|
||||
## Activities
|
||||
|
||||
Core activity abstractions live in [Abstractions](../../src/modules/Elsa.Workflows.Core/Abstractions):
|
||||
|
||||
- `Activity`
|
||||
- `Activity<T>`
|
||||
- `CodeActivity`
|
||||
- `WorkflowBase`
|
||||
- `Behavior`
|
||||
- `Trigger`
|
||||
|
||||
Built-in activities live in [Activities](../../src/modules/Elsa.Workflows.Core/Activities). Important families:
|
||||
|
||||
- Primitive control: `Sequence`, `If`, `Switch`, `For`, `ForEach`, `While`, `Parallel`, `Fork`, `Break`, `End`, `Finish`, `Complete`, `Fault`.
|
||||
- Data and runtime helpers: `SetVariable`, `SetName`, `Correlate`, `WriteLine`, `ReadLine`.
|
||||
- Dynamic and missing activity handling: `DynamicActivity`, `NotFoundActivity`.
|
||||
- Flowchart: [Activities/Flowchart](../../src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities).
|
||||
|
||||
Activities are described by `IActivityDescriber` and registered in `IActivityRegistry`. Workflow management adds activities to the available designer/API surface.
|
||||
|
||||
## Execution Contexts And State
|
||||
|
||||
Core execution state lives under [State](../../src/modules/Elsa.Workflows.Core/State) and [Models](../../src/modules/Elsa.Workflows.Core/Models). Important concepts:
|
||||
|
||||
- `WorkflowState`: serializable workflow execution state.
|
||||
- `ActivityExecutionContextState`: serializable activity execution context state.
|
||||
- `ActivityWorkItemState`: queued work item state.
|
||||
- `WorkflowExecutionState`: high-level status and state model.
|
||||
- `ActivityIncident`: fault or incident details.
|
||||
- `WorkflowInput`: input passed into a workflow run.
|
||||
- `ActivityOutputs` and `ActivityOutputRecord`: activity output capture.
|
||||
|
||||
Execution context extension tests live under [test/unit/Elsa.Workflows.Core.UnitTests/Extensions/ActivityExecutionContextExtensions](../../test/unit/Elsa.Workflows.Core.UnitTests/Extensions/ActivityExecutionContextExtensions).
|
||||
|
||||
## Inputs, Outputs, And Expressions
|
||||
|
||||
Inputs and outputs are modeled through:
|
||||
|
||||
- `Input<T>` and `Input`
|
||||
- `Output<T>` and `Output`
|
||||
- `InputDefinition`
|
||||
- `OutputDefinition`
|
||||
- `InputDescriptor`
|
||||
- `OutputDescriptor`
|
||||
- `Argument` and `ArgumentDefinition`
|
||||
|
||||
Expression handling bridges core workflows with language providers through [Expressions](../../src/modules/Elsa.Workflows.Core/Expressions) and the separate expression modules. `DefaultActivityInputEvaluator` evaluates inputs before activity execution.
|
||||
|
||||
## Scheduling Inside A Workflow
|
||||
|
||||
Core scheduling is about which activity work item runs next. Key services:
|
||||
|
||||
- [QueueBasedActivityScheduler](../../src/modules/Elsa.Workflows.Core/Services/QueueBasedActivityScheduler.cs)
|
||||
- [StackBasedActivityScheduler](../../src/modules/Elsa.Workflows.Core/Services/StackBasedActivityScheduler.cs)
|
||||
- [ActivitySchedulerFactory](../../src/modules/Elsa.Workflows.Core/Services/ActivitySchedulerFactory.cs)
|
||||
- [WorkflowExecutionContextSchedulerStrategy](../../src/modules/Elsa.Workflows.Core/Services/WorkflowExecutionContextSchedulerStrategy.cs)
|
||||
- [ActivityExecutionContextSchedulerStrategy](../../src/modules/Elsa.Workflows.Core/Services/ActivityExecutionContextSchedulerStrategy.cs)
|
||||
|
||||
Runtime scheduling and external dispatch are separate and live in `Elsa.Workflows.Runtime`.
|
||||
|
||||
## Bookmarks And Triggers
|
||||
|
||||
Core models define bookmark concepts:
|
||||
|
||||
- [Bookmark](../../src/modules/Elsa.Workflows.Core/Models/Bookmark.cs)
|
||||
- [BookmarkInfo](../../src/modules/Elsa.Workflows.Core/Models/BookmarkInfo.cs)
|
||||
- [CreateBookmarkArgs](../../src/modules/Elsa.Workflows.Core/Models/CreateBookmarkArgs.cs)
|
||||
- [TriggerType](../../src/modules/Elsa.Workflows.Core/Models/TriggerType.cs)
|
||||
|
||||
The runtime persists and indexes bookmarks/triggers. Core activities create bookmarks and signals; runtime services decide how they are stored and resumed.
|
||||
|
||||
## Flowchart Execution
|
||||
|
||||
Flowchart support is split between:
|
||||
|
||||
- [FlowchartFeature](../../src/modules/Elsa.Workflows.Core/Features/FlowchartFeature.cs)
|
||||
- [Flowchart activities](../../src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities)
|
||||
- flowchart extension methods in [Activities/Flowchart/Extensions](../../src/modules/Elsa.Workflows.Core/Activities/Flowchart/Extensions)
|
||||
|
||||
Relevant ADRs:
|
||||
|
||||
- [ADR 0005: Token-Centric Flowchart Execution Model](../adr/0005-token-centric-flowchart-execution-model.md)
|
||||
- [ADR 0007: Explicit Merge Modes For Flowchart Joins](../adr/0007-adoption-of-explicit-merge-modes-for-flowchart-joins.md)
|
||||
|
||||
## Pipelines
|
||||
|
||||
Core has separate workflow and activity execution pipelines:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Runner["IWorkflowRunner"] --> WorkflowPipeline["IWorkflowExecutionPipeline"]
|
||||
WorkflowPipeline --> Scheduler["Activity scheduler"]
|
||||
Scheduler --> ActivityPipeline["IActivityExecutionPipeline"]
|
||||
ActivityPipeline --> Invoker["IActivityInvoker"]
|
||||
Invoker --> Activity["IActivity.ExecuteAsync"]
|
||||
```
|
||||
|
||||
Pipeline extension methods live under [Extensions](../../src/modules/Elsa.Workflows.Core/Extensions) and middleware under [Middleware](../../src/modules/Elsa.Workflows.Core/Middleware). Pipelines are configured by `WorkflowsFeature`.
|
||||
|
||||
## Commit Strategies
|
||||
|
||||
Commit strategies determine persistence boundaries. Related files:
|
||||
|
||||
- [CommitStrategiesFeature](../../src/modules/Elsa.Workflows.Core/CommitStates/CommitStrategiesFeature.cs)
|
||||
- [CommitStrategies](../../src/modules/Elsa.Workflows.Core/CommitStates)
|
||||
- workflow sample configuration in [Elsa.Server.Web/Program.cs](../../src/apps/Elsa.Server.Web/Program.cs)
|
||||
|
||||
Runtime replaces the default no-op commit handler with an execution-cycle-aware handler so state changes are persisted at runtime boundaries.
|
||||
|
||||
## Serialization
|
||||
|
||||
Core serializers live under [Serialization](../../src/modules/Elsa.Workflows.Core/Serialization), including:
|
||||
|
||||
- `JsonWorkflowStateSerializer`
|
||||
- `JsonPayloadSerializer`
|
||||
- `JsonActivitySerializer`
|
||||
- `ApiSerializer`
|
||||
- `SafeSerializer`
|
||||
- `StandardJsonSerializer`
|
||||
|
||||
Custom constructor and additional converter configurators are registered by `WorkflowsFeature`.
|
||||
|
||||
## When To Change This Layer
|
||||
|
||||
Change workflow core only when you are changing engine semantics, activity contracts, execution state, serialization, core activity behavior, or flowchart behavior. If the change is about persisted definitions, API DTOs, background dispatch, or a module-specific transport, start in management, API, runtime, or the extension module instead.
|
||||
129
doc/wiki/workflow-management.md
Normal file
129
doc/wiki/workflow-management.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# Workflow Management
|
||||
|
||||
Workflow management owns workflow definitions and workflow instances as manageable resources. It is the layer used by Studio, import/export, validation, activity descriptors, workflow reference graphs, and many API endpoints.
|
||||
|
||||
Start in [src/modules/Elsa.Workflows.Management](../../src/modules/Elsa.Workflows.Management).
|
||||
|
||||
## Feature Wiring
|
||||
|
||||
[WorkflowManagementFeature](../../src/modules/Elsa.Workflows.Management/Features/WorkflowManagementFeature.cs) registers:
|
||||
|
||||
- memory stores for `WorkflowDefinition` and `WorkflowInstance`
|
||||
- activity providers and descriptor providers
|
||||
- workflow definition and instance managers
|
||||
- serializer, importer, exporter, publisher, validator
|
||||
- materializers for CLR, JSON, and typed workflows
|
||||
- activity registry population
|
||||
- workflow reference graph services
|
||||
- host method activities
|
||||
- workflow definition activities
|
||||
- variable descriptors and expression descriptors
|
||||
- read-only mode and default log persistence mode
|
||||
|
||||
It depends on workflow core, caching, mediator, string compression, system clock, workflow definitions, and workflow instances.
|
||||
|
||||
## Key Entities
|
||||
|
||||
| Entity | File | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `WorkflowDefinition` | [Entities/WorkflowDefinition.cs](../../src/modules/Elsa.Workflows.Management/Entities/WorkflowDefinition.cs) | Persisted definition version and metadata. |
|
||||
| `WorkflowInstance` | [Entities/WorkflowInstance.cs](../../src/modules/Elsa.Workflows.Management/Entities/WorkflowInstance.cs) | Persisted execution instance and workflow state. |
|
||||
|
||||
Management entities are separate from core execution models. Core can run workflows; management stores definitions and instances.
|
||||
|
||||
## Stores
|
||||
|
||||
Contracts:
|
||||
|
||||
- [IWorkflowDefinitionStore](../../src/modules/Elsa.Workflows.Management/Contracts/IWorkflowDefinitionStore.cs)
|
||||
- [IWorkflowInstanceStore](../../src/modules/Elsa.Workflows.Management/Contracts/IWorkflowInstanceStore.cs)
|
||||
|
||||
Defaults:
|
||||
|
||||
- [MemoryWorkflowDefinitionStore](../../src/modules/Elsa.Workflows.Management/Stores/MemoryWorkflowDefinitionStore.cs)
|
||||
- [MemoryWorkflowInstanceStore](../../src/modules/Elsa.Workflows.Management/Stores/MemoryWorkflowInstanceStore.cs)
|
||||
- [CachingWorkflowDefinitionStore](../../src/modules/Elsa.Workflows.Management/Stores/CachingWorkflowDefinitionStore.cs)
|
||||
|
||||
EF Core persistence replaces these stores through [Elsa.Persistence.EFCore/Modules/Management](../../src/modules/Elsa.Persistence.EFCore/Modules/Management).
|
||||
|
||||
## Definition Lifecycle
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Draft["Draft definition"] --> Save["Save draft"]
|
||||
Save --> Validate["Validate"]
|
||||
Validate --> Publish["Publish version"]
|
||||
Publish --> Runtime["Runtime can start or dispatch"]
|
||||
Publish --> Retract["Retract"]
|
||||
Draft --> Delete["Delete definition/version"]
|
||||
```
|
||||
|
||||
Important services:
|
||||
|
||||
- [WorkflowDefinitionManager](../../src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionManager.cs)
|
||||
- [WorkflowDefinitionPublisher](../../src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionPublisher.cs)
|
||||
- [WorkflowDefinitionService](../../src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionService.cs)
|
||||
- [CachingWorkflowDefinitionService](../../src/modules/Elsa.Workflows.Management/Services/CachingWorkflowDefinitionService.cs)
|
||||
- [WorkflowValidator](../../src/modules/Elsa.Workflows.Management/Services/WorkflowValidator.cs)
|
||||
|
||||
Notifications under [Notifications](../../src/modules/Elsa.Workflows.Management/Notifications) allow cache eviction, validation, reference updates, and cascading behavior.
|
||||
|
||||
## Materializers
|
||||
|
||||
Materializers convert persisted or typed representations into executable workflows:
|
||||
|
||||
- [ClrWorkflowMaterializer](../../src/modules/Elsa.Workflows.Management/Materializers/ClrWorkflowMaterializer.cs)
|
||||
- [JsonWorkflowMaterializer](../../src/modules/Elsa.Workflows.Management/Materializers/JsonWorkflowMaterializer.cs)
|
||||
- [TypedWorkflowMaterializer](../../src/modules/Elsa.Workflows.Management/Materializers/TypedWorkflowMaterializer.cs)
|
||||
|
||||
The materializer registry is [MaterializerRegistry](../../src/modules/Elsa.Workflows.Management/Services/MaterializerRegistry.cs), with the contract [IMaterializerRegistry](../../src/modules/Elsa.Workflows.Management/Contracts/IMaterializerRegistry.cs).
|
||||
|
||||
## Import, Export, And Serialization
|
||||
|
||||
Management uses:
|
||||
|
||||
- [WorkflowSerializer](../../src/modules/Elsa.Workflows.Management/Services/WorkflowSerializer.cs)
|
||||
- [WorkflowDefinitionImporter](../../src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionImporter.cs)
|
||||
- [WorkflowDefinitionExporter](../../src/modules/Elsa.Workflows.Management/Services/WorkflowDefinitionExporter.cs)
|
||||
|
||||
These services are used by API endpoints for workflow definition import/export and by tests that load JSON workflow definitions.
|
||||
|
||||
## Activity And Variable Descriptors
|
||||
|
||||
Designer and API clients need metadata about available activities, inputs, outputs, UI hints, variable types, and expressions. Management provides:
|
||||
|
||||
- [TypedActivityProvider](../../src/modules/Elsa.Workflows.Management/Providers/TypedActivityProvider.cs)
|
||||
- [DefaultExpressionDescriptorProvider](../../src/modules/Elsa.Workflows.Management/Providers/DefaultExpressionDescriptorProvider.cs)
|
||||
- [ActivityRegistryPopulator](../../src/modules/Elsa.Workflows.Management/Services/ActivityRegistryPopulator.cs)
|
||||
- [ExpressionDescriptorRegistry](../../src/modules/Elsa.Workflows.Management/Services/ExpressionDescriptorRegistry.cs)
|
||||
|
||||
Modules add activities by calling `Module.UseWorkflowManagement(management => management.AddActivitiesFrom<TMarker>())` or equivalent helpers.
|
||||
|
||||
## Host Method Activities
|
||||
|
||||
Host method activities expose methods from registered host classes as activities. Relevant files:
|
||||
|
||||
- [HostMethodActivity](../../src/modules/Elsa.Workflows.Management/Activities/HostMethod/HostMethodActivity.cs)
|
||||
- [HostMethodActivityProvider](../../src/modules/Elsa.Workflows.Management/Activities/HostMethod/HostMethodActivityProvider.cs)
|
||||
- [HostMethodActivitiesOptions](../../src/modules/Elsa.Workflows.Management/Options/HostMethodActivitiesOptions.cs)
|
||||
|
||||
The reference server registers an activity host with `AddActivityHost<Penguin>()` in [Program.cs](../../src/apps/Elsa.Server.Web/Program.cs).
|
||||
|
||||
## Workflow Definition Activity
|
||||
|
||||
The workflow definition activity allows one workflow to reference another workflow definition:
|
||||
|
||||
- [WorkflowDefinitionActivity](../../src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivity.cs)
|
||||
- [WorkflowDefinitionActivityProvider](../../src/modules/Elsa.Workflows.Management/Activities/WorkflowDefinitionActivity/WorkflowDefinitionActivityProvider.cs)
|
||||
- [WorkflowReferenceGraphBuilder](../../src/modules/Elsa.Workflows.Management/Services/WorkflowReferenceGraphBuilder.cs)
|
||||
- [WorkflowReferenceUpdater](../../src/modules/Elsa.Workflows.Management/Services/WorkflowReferenceUpdater.cs)
|
||||
|
||||
Component tests under [WorkflowReferenceGraph](../../test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowReferenceGraph) exercise this behavior.
|
||||
|
||||
## Read-Only Mode
|
||||
|
||||
`WorkflowManagementFeature.UseReadOnlyMode(bool)` affects mutable workflow definition operations. API authorization uses [NotReadOnlyRequirement](../../src/modules/Elsa.Workflows.Api/Requirements/NotReadOnlyRequirement.cs) and the `NotReadOnlyPolicy` in workflow API.
|
||||
|
||||
## When To Change This Layer
|
||||
|
||||
Change management when the work is about workflow definitions, workflow instances as persisted records, import/export formats, activity metadata, variable metadata, validation, read-only behavior, reference graphs, or workflow store replacement. Do not put runtime dispatch or transport-specific behavior here unless management contracts need to expose it.
|
||||
140
doc/wiki/workflow-runtime.md
Normal file
140
doc/wiki/workflow-runtime.md
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# Workflow Runtime
|
||||
|
||||
Workflow runtime owns starting, dispatching, resuming, canceling, logging, and recovering workflow executions. It is the layer that turns definitions into running instances and responds to triggers, bookmarks, background work, and admin operations.
|
||||
|
||||
Start in [src/modules/Elsa.Workflows.Runtime](../../src/modules/Elsa.Workflows.Runtime).
|
||||
|
||||
## Feature Wiring
|
||||
|
||||
[WorkflowRuntimeFeature](../../src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs) registers and configures:
|
||||
|
||||
- `IWorkflowRuntime`
|
||||
- `IWorkflowDispatcher`
|
||||
- `IStimulusDispatcher`
|
||||
- `IWorkflowCancellationDispatcher`
|
||||
- bookmark, bookmark queue, trigger, workflow execution log, and activity execution stores
|
||||
- workflow matcher, starter, invoker, resumer, canceler, restarter
|
||||
- trigger indexer and bookmark manager
|
||||
- background workflow, stimulus, task, and activity dispatch
|
||||
- bookmark queue worker and queue purger
|
||||
- distributed lock provider
|
||||
- execution cycle registry
|
||||
- graceful shutdown machinery
|
||||
- runtime startup and recurring tasks
|
||||
|
||||
It also configures `WorkflowsFeature` to use the runtime commit state handler.
|
||||
|
||||
## Runtime Stores
|
||||
|
||||
Important runtime entities:
|
||||
|
||||
- [StoredTrigger](../../src/modules/Elsa.Workflows.Runtime/Entities/StoredTrigger.cs)
|
||||
- [StoredBookmark](../../src/modules/Elsa.Workflows.Runtime/Entities/StoredBookmark.cs)
|
||||
- [BookmarkQueueItem](../../src/modules/Elsa.Workflows.Runtime/Entities/BookmarkQueueItem.cs)
|
||||
- [WorkflowExecutionLogRecord](../../src/modules/Elsa.Workflows.Runtime/Entities/WorkflowExecutionLogRecord.cs)
|
||||
- [ActivityExecutionRecord](../../src/modules/Elsa.Workflows.Runtime/Entities/ActivityExecutionRecord.cs)
|
||||
- [WorkflowInboxMessage](../../src/modules/Elsa.Workflows.Runtime/Entities/WorkflowInboxMessage.cs)
|
||||
|
||||
The default runtime feature uses memory stores. EF Core runtime persistence is wired by [EFCoreWorkflowRuntimePersistenceFeature](../../src/modules/Elsa.Persistence.EFCore/Modules/Runtime/WorkflowRuntimePersistenceFeature.cs), which replaces runtime store factories on `WorkflowRuntimeFeature`.
|
||||
|
||||
## Dispatch Paths
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
Start["Start workflow request"] --> Starter["DefaultWorkflowStarter"]
|
||||
Trigger["Trigger/stimulus"] --> Stimulus["StimulusSender / TriggerInvoker"]
|
||||
Bookmark["Bookmark resume"] --> Resumer["BookmarkResumer / WorkflowResumer"]
|
||||
Instance["Dispatch existing instance"] --> Dispatcher["WorkflowDispatcher"]
|
||||
Starter --> Invoker["WorkflowInvoker"]
|
||||
Stimulus --> Matcher["WorkflowMatcher"]
|
||||
Matcher --> Dispatcher
|
||||
Resumer --> Dispatcher
|
||||
Dispatcher --> Runtime["LocalWorkflowRuntime"]
|
||||
Runtime --> Runner["IWorkflowRunner"]
|
||||
```
|
||||
|
||||
Key files:
|
||||
|
||||
- [LocalWorkflowRuntime](../../src/modules/Elsa.Workflows.Runtime/Services/LocalWorkflowRuntime.cs)
|
||||
- [BackgroundWorkflowDispatcher](../../src/modules/Elsa.Workflows.Runtime/Services/BackgroundWorkflowDispatcher.cs)
|
||||
- [ValidatingWorkflowDispatcher](../../src/modules/Elsa.Workflows.Runtime/Services/ValidatingWorkflowDispatcher.cs)
|
||||
- [WorkflowInvoker](../../src/modules/Elsa.Workflows.Runtime/Services/WorkflowInvoker.cs)
|
||||
- [DefaultWorkflowStarter](../../src/modules/Elsa.Workflows.Runtime/Services/DefaultWorkflowStarter.cs)
|
||||
- [WorkflowResumer](../../src/modules/Elsa.Workflows.Runtime/Services/WorkflowResumer.cs)
|
||||
- [BookmarkResumer](../../src/modules/Elsa.Workflows.Runtime/Services/BookmarkResumer.cs)
|
||||
- [TriggerInvoker](../../src/modules/Elsa.Workflows.Runtime/Services/TriggerInvoker.cs)
|
||||
|
||||
## Triggers And Bookmarks
|
||||
|
||||
Triggers start workflows. Bookmarks resume suspended workflow instances. Runtime indexes and queries them through:
|
||||
|
||||
- [TriggerIndexer](../../src/modules/Elsa.Workflows.Runtime/Services/TriggerIndexer.cs)
|
||||
- [DefaultBookmarkManager](../../src/modules/Elsa.Workflows.Runtime/Services/DefaultBookmarkManager.cs)
|
||||
- [BookmarkPersister](../../src/modules/Elsa.Workflows.Runtime/Services/BookmarkPersister.cs)
|
||||
- [BookmarkUpdater](../../src/modules/Elsa.Workflows.Runtime/Services/BookmarkUpdater.cs)
|
||||
- [BookmarkBoundWorkflowService](../../src/modules/Elsa.Workflows.Runtime/Services/BookmarkBoundWorkflowService.cs)
|
||||
- [TriggerBoundWorkflowService](../../src/modules/Elsa.Workflows.Runtime/Services/TriggerBoundWorkflowService.cs)
|
||||
|
||||
Bookmark queue processing is handled by:
|
||||
|
||||
- [StoreBookmarkQueue](../../src/modules/Elsa.Workflows.Runtime/Services/StoreBookmarkQueue.cs)
|
||||
- [BookmarkQueueProcessor](../../src/modules/Elsa.Workflows.Runtime/Services/BookmarkQueueProcessor.cs)
|
||||
- [BookmarkQueueWorker](../../src/modules/Elsa.Workflows.Runtime/Services/BookmarkQueueWorker.cs)
|
||||
- [BookmarkQueueSignaler](../../src/modules/Elsa.Workflows.Runtime/Services/BookmarkQueueSignaler.cs)
|
||||
|
||||
## Execution Logs
|
||||
|
||||
Workflow and activity execution logs flow through sinks and stores:
|
||||
|
||||
- [StoreWorkflowExecutionLogSink](../../src/modules/Elsa.Workflows.Runtime/Services/StoreWorkflowExecutionLogSink.cs)
|
||||
- [StoreActivityExecutionLogSink](../../src/modules/Elsa.Workflows.Runtime/Services/StoreActivityExecutionLogSink.cs)
|
||||
- [WorkflowExecutionLogRecordExtractor](../../src/modules/Elsa.Workflows.Runtime/Services/WorkflowExecutionLogRecordExtractor.cs)
|
||||
- [DefaultActivityExecutionMapper](../../src/modules/Elsa.Workflows.Runtime/Services/DefaultActivityExecutionMapper.cs)
|
||||
|
||||
API endpoints under `WorkflowInstances/Journal`, `ActivityExecutions`, and `ActivityExecutionSummaries` expose this data.
|
||||
|
||||
## Background Work
|
||||
|
||||
Runtime has several background paths:
|
||||
|
||||
- `BackgroundWorkflowDispatcher` for workflow dispatch.
|
||||
- `BackgroundStimulusDispatcher` for stimulus dispatch.
|
||||
- `BackgroundTaskDispatcher` for `RunTask`.
|
||||
- `LocalBackgroundActivityScheduler` for background activity execution.
|
||||
- `BackgroundActivityInvoker` for executing background activity work.
|
||||
|
||||
These paths matter for tests: a workflow may return before background activity or bookmark work has completed.
|
||||
|
||||
## Graceful Shutdown And Recovery
|
||||
|
||||
Recent graceful shutdown work added node-local quiescence and drain concepts. Source landmarks:
|
||||
|
||||
- [QuiescenceSignal](../../src/modules/Elsa.Workflows.Runtime/Services/QuiescenceSignal.cs)
|
||||
- [IngressSourceRegistry](../../src/modules/Elsa.Workflows.Runtime/Services/IngressSourceRegistry.cs)
|
||||
- [DrainOrchestrator](../../src/modules/Elsa.Workflows.Runtime/Services/DrainOrchestrator.cs)
|
||||
- [DrainOrchestratorHostedService](../../src/modules/Elsa.Workflows.Runtime/HostedServices/DrainOrchestratorHostedService.cs)
|
||||
- [InterruptedRecoveryScanner](../../src/modules/Elsa.Workflows.Runtime/Services/InterruptedRecoveryScanner.cs)
|
||||
- [RecoverInterruptedWorkflowsStartupTask](../../src/modules/Elsa.Workflows.Runtime/StartupTasks/RecoverInterruptedWorkflowsStartupTask.cs)
|
||||
|
||||
The design intent is captured in [specs/002-graceful-shutdown/plan.md](../../specs/002-graceful-shutdown/plan.md).
|
||||
|
||||
Ingress source adapters are currently registered by modules such as HTTP and Scheduling so the runtime can pause external event intake during drain.
|
||||
|
||||
## Runtime Admin
|
||||
|
||||
The workflow API includes runtime admin endpoints:
|
||||
|
||||
- `GET /elsa/api/admin/workflow-runtime/status`
|
||||
- `POST /elsa/api/admin/workflow-runtime/pause`
|
||||
- `POST /elsa/api/admin/workflow-runtime/resume`
|
||||
- `POST /elsa/api/admin/workflow-runtime/force-drain`
|
||||
|
||||
Endpoint code lives under [Elsa.Workflows.Api/Endpoints/RuntimeAdmin](../../src/modules/Elsa.Workflows.Api/Endpoints/RuntimeAdmin). The service behind these endpoints is [WorkflowRuntimeAdminService](../../src/modules/Elsa.Workflows.Runtime/Services/WorkflowRuntimeAdminService.cs).
|
||||
|
||||
## Distributed Runtime
|
||||
|
||||
Distributed runtime support lives in [Elsa.Workflows.Runtime.Distributed](../../src/modules/Elsa.Workflows.Runtime.Distributed). It layers distributed coordination and resilience support on top of the base runtime. When making runtime changes, check whether the distributed project has a parallel worker or dispatcher that must honor the same semantics.
|
||||
|
||||
## When To Change This Layer
|
||||
|
||||
Change runtime for dispatch semantics, trigger/bookmark indexing, background work, execution logs, recovery, cancellation, graceful shutdown, or runtime stores. If a change only affects how definitions are saved or described, it belongs in management. If it only changes HTTP endpoint activity behavior, start in `Elsa.Http`.
|
||||
Loading…
Reference in a new issue