Portal Community

Automatic Reconnect Configuration

The retry delay sequence is configured when the HubConnection is built. Flow Studio uses four escalating delays before giving up:

// useExecutionSignalR.ts
const connection = new HubConnectionBuilder()
  .withUrl('/hubs/execution', {
    accessTokenFactory: () => getAuthToken()
  })
  .withAutomaticReconnect([1000, 2000, 5000, 10000]) // ms delays between attempts
  .configureLogging(LogLevel.Warning)
  .build();

The four configured delays total 18 seconds of retry time. After the fourth attempt fails, SignalR fires the onclose callback and does not retry further. At that point, the polling fallback activates automatically.

Reconnection State Machine

1

Connection Lost

Network interruption or server restart drops the WebSocket. SignalR fires onreconnecting(error).

Reconnecting…
2

Retry Attempts (1s → 2s → 5s → 10s)

SignalR automatically retries. The reconnecting banner in the Observer Panel shows the attempt count. Execution continues on the server during this window — events are queued server-side.

3a

Reconnect Succeeded

SignalR fires onreconnected(connectionId). The client re-joins the execution group and performs an event replay catch-up to fill any gaps.

Connection Restored
3b

All Retries Exhausted → Polling Fallback

SignalR fires onclose(error). The polling fallback activates and the "Live updates unavailable" banner replaces the reconnecting indicator.

Live updates unavailable

Reconnection Event Handlers

// useExecutionSignalR.ts — lifecycle hooks
connection.onreconnecting((error) => {
  setConnectionState('reconnecting');
  uiStore.showReconnectingBanner(error?.message);
  // Don't clear existing node states — they remain visible during reconnect
});

connection.onreconnected(async (connectionId) => {
  setConnectionState('connected');
  uiStore.hideReconnectingBanner();

  // Re-join the execution group (server forgets group membership on disconnect)
  await connection.invoke('JoinExecutionGroup', executionId);

  // Catch up on events missed during the disconnect window
  await replayMissedEvents(executionId, lastReceivedEventTimestamp);
});

connection.onclose((error) => {
  setConnectionState('disconnected');
  // Activate polling fallback
  setPollingEnabled(true);
  uiStore.showPollingFallbackBanner();
});

Event Replay on Reconnect

When the connection is re-established, the client may have missed events that occurred during the disconnection window. The replayMissedEvents function fetches a snapshot from the REST API and reconciles it with current UI state:

// executionReplay.ts
async function replayMissedEvents(
  executionId: string,
  since: string           // ISO 8601 timestamp of last received event
) {
  const snapshot = await fetch(
    `/api/v1/process-engine/executions/${executionId}/snapshot?since=${since}`
  ).then(r => r.json());

  // Apply each node's current status from the snapshot
  for (const node of snapshot.nodes) {
    designerModeStore.setNodeStatus(node.nodeId, {
      status: node.status,
      durationMs: node.durationMs,
      output: node.output
    });
  }

  // If the execution finished during the disconnect, handle completion
  if (['completed', 'failed', 'cancelled'].includes(snapshot.executionStatus)) {
    designerModeStore.setExecutionComplete(snapshot.executionStatus);
  }
}
Snapshot Endpoint The /snapshot?since= endpoint returns the current state of all nodes in the execution, not a list of events. This is intentional — replaying individual events in order would be complex and error-prone. Instead, the snapshot gives a consistent point-in-time view that the client applies as a batch update.

UI Indicators During Reconnection

StateBanner TextColorNode Canvas
Reconnecting (attempt 1–4)"Reconnecting… (attempt N of 4)"YellowNode states frozen; no new updates
Reconnected"Connection restored" (auto-dismisses after 3s)GreenSnapshot applied; states updated
All retries failed"Live updates unavailable — polling every 2s"RedPolling takes over; slower updates

Server-Side Behaviour During Disconnect

The execution continues running on the server regardless of whether the client is connected. SignalR buffers outgoing messages for a configurable duration (default 30 seconds). If the client reconnects within the buffer window, no events are lost. If the buffer expires, the client uses the snapshot endpoint to catch up.

Group Re-Join is Required SignalR SignalR does not automatically restore Hub group memberships after a reconnect. The client must explicitly call connection.invoke('JoinExecutionGroup', executionId) in the onreconnected handler. Failure to do so means the client reconnects to the hub but receives no execution events.