Portal Community

The dataStateMachine Block

Add a dataStateMachine property to the node's settings JSON in Flow Studio. The platform reads it via BaseNodeExecutorSettings.DataStateMachineConfig using ReadConfigDictionaryByKey("dataStateMachine").

{
  "myNodeSetting1": "value",
  "myNodeSetting2": 42,
  "dataStateMachine": {
    "handler": "built-in",
    "scope":   "Element",
    "options": {}
  }
}

Properties Reference

Property Type Required Values Default
handler string No "built-in", "sales-leads", or any registered HandlerKey "built-in"
scope string No "App", "Process", "Thread", "Element", "ProcessExecution", "ThreadExecution", "ElementExecution" "Element"
options object No Handler-specific key-value pairs {}

Scope Selection Guide

Choose the scope based on the granularity of idempotency you need. The scope determines which context fields are included in the state record lookup.

Scope When to Use Example
App Global deduplication — once per tenant per key, regardless of workflow Daily digest email — send once per day globally
Process Dedup within a specific workflow definition Invoice workflow — don't re-process same invoice in this workflow
Thread Dedup within a specific thread Approval thread — same approver can't act twice in same thread
Element Node-level idempotency (recommended default) HttpCall node — don't call same endpoint twice for same entity
ProcessExecution Per-run tracking (different runs = different records) Audit log — record every run separately
ThreadExecution Per-thread-run tracking Timing metrics per thread run
ElementExecution Finest — separate record per node per run Debug tracking for every individual execution

Handler-Specific Options

The options object is passed through to the handler as a dictionary. The handler reads it from ctx.HandlerConfig.Options. The built-in handler currently uses no options, but custom handlers can declare their own.

{
  "dataStateMachine": {
    "handler": "my-blockchain-handler",
    "scope": "Element",
    "options": {
      "networkId": "ethereum-mainnet",
      "contractAddress": "0x...",
      "confirmationsRequired": 3
    }
  }
}
// Inside MyBlockchainHandler
var networkId = ctx.HandlerConfig.Options.GetValueOrDefault("networkId", "testnet");
var confirmations = int.Parse(ctx.HandlerConfig.Options.GetValueOrDefault("confirmationsRequired", "1"));

What Happens When the Block Is Absent

If the dataStateMachine section is missing from the node settings, DataStateMachineFactory returns NullDataStateMachine.Instance. All calls on IDataStateMachine become no-ops. Nothing is written to the database.

// DataStateMachineFactory.CreateAsync (simplified)
if (config == null)
    return NullDataStateMachine.Instance;

// resolve handler, build context, return ContextualDataStateMachine...
You can safely call DataStateMachine.ExistsAsync() and all other methods even when NullDataStateMachine is active. The no-op returns safe defaults — false for exists checks, true for lock acquisition — so the node logic flows naturally without any null checks.

Reading Config in Your Settings Class

Your custom node settings class inherits from BaseNodeExecutorSettings. DataStateMachineConfig is already declared there — you don't need to add it.

// BaseNodeExecutorSettings (in ProcessEngine.Domain — already exists)
public abstract class BaseNodeExecutorSettings
{
    // ... other base properties ...

    public DataStateMachineConfig? DataStateMachineConfig =>
        ReadConfigDictionaryByKey("dataStateMachine") is { } d
            ? new DataStateMachineConfig(d)
            : null;
}

// Your settings class — DataStateMachineConfig inherited automatically
public class InvoiceDispatchSettings : BaseNodeExecutorSettings
{
    public string ApiEndpoint { get; set; } = "";
    public int RetryCount { get; set; } = 3;
    // DataStateMachineConfig is inherited — no action needed
}
DataStateMachineConfig includes a static DataStateMachineConfig.Empty instance for use in tests and NullDataStateMachine scenarios — it has HandlerKey = "built-in", Scope = "Element", and an empty options dictionary.