Portal Community

TimeoutGuard: Execution Time Enforcement

The Problem

An HTTP node calls a third-party analytics API. Under normal conditions it completes in 200ms. Under load, the API degrades — responses take 45 seconds. Without a timeout guard:

The Solution

TimeoutGuard records start time in Pre and checks elapsed time in Post. Configure action="block" to return a failure after timeoutMs milliseconds.

{
  "name": "TimeoutGuard",
  "enabled": true,
  "config": {
    "timeoutMs": 5000,   // 5 seconds maximum
    "action": "block"    // fail with Blocked result if exceeded
  }
}
Important: TimeoutGuard does not cancel the node execution TimeoutGuard checks elapsed time in the Post phase, after the node has returned (or errored). If you need to interrupt a long-running operation mid-execution, use CancellationToken in the node implementation itself. TimeoutGuard enforces the policy at the workflow level — it blocks the result from being accepted, but the node's async operation may have already completed.

Warning mode vs block mode

ConfigBehaviorUse when
"action": "block" Returns Blocked — the workflow fails with an error Hard SLA requirements; output after timeout is unreliable
"action": "warn" Returns Warning (IsAllowed=true) — workflow continues but violation is logged Monitoring and alerting; tolerant workflows where slow response is still usable

CircuitBreakerGuard: Automatic Dependency Protection

The Problem

The analytics API goes fully down at 2:00 AM. Without circuit breaking:

The Solution

CircuitBreakerGuard opens the circuit after 5 consecutive failures. Subsequent calls are rejected immediately without touching the failing API — fast fail with no resource waste.

{
  "name": "CircuitBreakerGuard",
  "enabled": true,
  "config": {
    "threshold": 5,      // open after 5 consecutive permanent failures
    "timeout": 60000     // stay Open for 60 seconds, then try HalfOpen
  }
}

Circuit breaker state machine

C

Closed Normal

All requests pass through. Failures are tracked in a sliding 5-minute window. When FailureCount ≥ 5 → Open.

O

Open Blocking

All requests blocked immediately. After 60 seconds (OpenDuration) → HalfOpen.

H

HalfOpen Testing

One test request allowed. Success: → Closed (normal operation). Failure: → Open (60 more seconds).

The circuit breaker at the service level (in GuardCircuitBreaker) requires 3 consecutive successes to close from HalfOpen.

Service-level circuit breaker defaults

The GuardCircuitBreaker service (which protects guard infrastructure) uses these defaults, configured in DI:

PolicyDefault
FailureThreshold5 (within the failure window)
OpenDuration60 seconds
SuccessThresholdForHalfOpen3 consecutive successes
FailSecuretrue (security-critical guards block when circuit open)
ResetOnTransienttrue (transient failures don't count toward threshold)
FailureWindow300 seconds (5-minute sliding window)

Combined Configuration: Timeout + Circuit Breaker

{
  "guardRails": {
    "individual": [
      {
        "name": "TimeoutGuard",
        "enabled": true,
        "order": 1,
        "config": { "timeoutMs": 5000, "action": "block" }
      },
      {
        "name": "CircuitBreakerGuard",
        "enabled": true,
        "order": 2,
        "config": { "threshold": 5, "timeout": 60000 }
      }
    ]
  }
}

Result: Slow requests fail fast (5s max). After 5 failures, subsequent requests fail instantly (circuit open). After 60s, one test request probes recovery. On success, normal operation resumes.