Repository navigation
Skip no-op payload passes and context lookups without a codec or external storage - #2090
Open
tonypodero wants to merge 1 commit into
Open
tonypodero wants to merge 1 commit into
tonypodero wants to merge 1 commit into
Conversation
tonypodero
force-pushed
the
skip-noop-payload-passes
branch
from
November 6, 2026 07:25
9bc9d39 to
c1a34f7
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
DataConverter._decode_payload_has_effecthad no callers. It is now_has_codec_or_external_storage, and both the bridge and the workflow worker use it.Why
Since 1.23 the payload passes in
decode_activation/encode_completionrun unconditionally (#1288, #1341). 1.25 split them into two passes per direction (#1394) and 1.35 into three (#1946). From 1.25, each visited payload sequence also asks the workflow instance for its serialization context (#1387). For a sandboxed workflow, each of those lookups is anexecinto the sandbox. With the default converter, none of this work changes a payload.We hit this after upgrading 1.22 → 1.35. Long-running workflows (3k–8k events) are rebuilt from history after each deploy, and those replays became 1.3–1.6× slower, which pushed the largest past the workflow task timeout. On three of our own histories (2.6k–7.4k events), this change brings replay time back to 1.22.0's, 25–38% less than on 1.35.0.
Replay of a synthetic history (activity + 5-minute timer in a loop, default converter, default sandbox), relative to 1.22.0. Median of 3 interleaved rounds × 5 replays; macOS arm64, Python 3.12, protobuf 5.29.6:
Where the time went (1.35.0, 7,705-event history, 1,402 activations)
_run_codecalls per replay: 1,406 on 1.24.0 (oneactivateper activation), 6,310 on 1.35.0. The extra calls are 4,203get_serialization_contextand 701get_external_store_context.decode_activation/encode_completionalone, with the default converter, per call: 0.1 / 0.1 µs on 1.22.0 and 10.9 / 12.9 µs on 1.35.0.How it was tested
test_command_context_resolved_only_with_codec_or_external_storage: a workflow without a codec makes no context lookups, and one with a codec still does. It fails on 1.35.0 (3 lookups) and passes with this change.mainapart from unrelated lines) and ran the 1.35.0 tests against it:test_serialization_context.py,test_extstore.pyandworker/test_extstore.py: 88 passed, the same as unpatched.worker/test_workflow.py,worker/test_replayer.py,worker/test_activity.py, andtest_serialization_context.pywith the new test: 348 passed, 2 skipped, 0 failed.poe lint-typesand the fullpoe testonmain.