Skip to content

Suggest continue-as-new before hitting maximumSignalsPerExecution#10989

Open
nitishagar wants to merge 1 commit into
temporalio:mainfrom
nitishagar:nitishagar/10941-suggest-can-signals
Open

Suggest continue-as-new before hitting maximumSignalsPerExecution#10989
nitishagar wants to merge 1 commit into
temporalio:mainfrom
nitishagar:nitishagar/10941-suggest-can-signals

Conversation

@nitishagar

Copy link
Copy Markdown

What changed?

Adds a fourth SuggestContinueAsNewReasonTOO_MANY_SIGNALS — so the server advises a workflow to continue-as-new when its signal count reaches a configurable fraction of maximumSignalsPerExecution, before the hard ErrSignalsLimitExceeded rejection bites. This is the signals analog of the existing TOO_MANY_UPDATES suggest-CAN feature.

  • New namespace-scoped dynamic-config key history.maximumSignalsPerExecution.suggestContinueAsNewThreshold (float, default 0 = disabled).
  • The suggestion is computed inline in getHistorySizeInfo alongside the existing history-size and history-event-count reasons: it fires when SignalCount >= ceil(maximumSignalsPerExecution * threshold), mirroring the updates path's rounding.
  • Extends the existing workflow_suggest_continue_as_new_count counter with a fourth boolean tag SuggestContinueAsNewReasonTooManySignalsTag.
  • The hard-limit rejection path (signal_workflow_util.go) is unchanged.

The new enum value SUGGEST_CONTINUE_AS_NEW_REASON_TOO_MANY_SIGNALS = 5 is added upstream in temporalio/api#822.

Why?

Closes #10941. Today the only signal feedback is a hard rejection at the limit; workers get no advance warning to drain and continue-as-new. A soft, opt-in suggestion gives them that headroom, consistent with how history size, event count, and updates already behave. Defaulting the threshold to 0 (disabled) makes it a strict no-op on upgrade — signals are far more common than updates, so a non-zero default would newly emit suggestions on countless existing executions.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s) — service/history/workflow/workflow_task_state_machine_signals_test.go covers: threshold 0 / max 0 disable (INV-3), below/at(inclusive >=)/above boundary, threshold 1.0 at the hard limit and below, coexistence with the history-size reason (INV-7), and continue-as-new reset (INV-4).
  • added new functional test(s) — tests/signal_suggest_can_test.go: overrides both knobs, sends signals to the boundary and asserts SuggestContinueAsNew + the TOO_MANY_SIGNALS reason on the started event; asserts the hard limit still rejects end-to-end (INV-2); and asserts no reason appears under the disabled default.

go test -tags test_dep ./service/history/workflow/... is green; golangci-lint reports 0 new issues. The functional test requires the docker test cluster to run.

Potential risks

  • Upstream API dependency. This depends on Add SUGGEST_CONTINUE_AS_NEW_REASON_TOO_MANY_SIGNALS enum value api#822. Until that merges and a go.temporal.io/api release contains the enum, go.mod points at a fork (github.com/nitishagar/api-go) via a replace directive (the standard "Working with local API changes" flow). The replace must be swapped for the released version before merge.
  • Additive only; the feature is disabled by default, so existing deployments are unaffected.

@nitishagar nitishagar requested review from a team as code owners July 9, 2026 04:54
Add a fourth SuggestContinueAsNewReason, TOO_MANY_SIGNALS, so the server
advises a workflow to continue-as-new when its signal count reaches a
configurable fraction of maximumSignalsPerExecution, before the hard
ErrSignalsLimitExceeded rejection bites. This is the signals analog of
the existing TOO_MANY_UPDATES suggest-CAN feature.

The suggestion is computed inline in getHistorySizeInfo alongside the
existing history-size and history-event-count reasons (signals have no
registry, so inline computation reuses the scope already established
there). It fires when SignalCount >= ceil(maximumSignalsPerExecution *
threshold), mirroring the updates path's rounding.

The threshold is a new namespace-scoped dynamic-config key
history.maximumSignalsPerExecution.suggestContinueAsNewThreshold that
defaults to 0 (disabled), so the feature is opt-in and a strict no-op on
upgrade. The hard-limit rejection path is unchanged.

Requires go.temporal.io/api to export
SUGGEST_CONTINUE_AS_NEW_REASON_TOO_MANY_SIGNALS (added in temporalio/api#822);
go.mod temporarily points at a fork until that version is released.

Closes temporalio#10941.
@nitishagar nitishagar force-pushed the nitishagar/10941-suggest-can-signals branch from 12a69e1 to 3b79549 Compare July 9, 2026 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggest continue as new before hitting the maximumSignalsPerExecution limit

1 participant