polling: Support service handler for ADR003#103
Open
absoludity wants to merge 5 commits intomasterfrom
Open
Conversation
…et_handler() NewDataDetectionPipeline previously required result_handler via __init__, which Temporal cannot satisfy when instantiating workflow classes. Extract polling, change-detection, and handler coordination to PollDataUseCase. Subclasses override get_handler() to supply a handler without constructor injection. PollingManager.start_polling gains a workflow_name parameter (replacing the unused downstream_pipeline arg) to enable subclass-based routing.
absoludity
commented
Feb 26, 2026
Comment on lines
+27
to
+30
| info: list[str] = Field( | ||
| default_factory=list, | ||
| description="Informational messages about handler processing", | ||
| ) |
Collaborator
Author
There was a problem hiding this comment.
I couldn't see a reason for the other 3 string arrays that are on here in the ADR (debug, warning, error). It read as though we expected to gather all log messages during the handler's execution or something, but that clearly isn't the case (we just start it - so the only info we can return is related to starting, or why we didn't start it (no-comply) etc.). So I've just used info only. Let me know if there's some other reason I'm missing.
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.
The polling contrib module needed to trigger domain-specific downstream workflows when new data was detected, but couldn't do this without knowing about those workflows — a cross-BC coupling problem.
The previous approach used "bridge pipelines" (
PollingDataPreparationPipeline), an extra intermediate workflow for each integration point. This worked but required solution providers to maintain a dedicated pipeline just to hand off between the polling system and their processing workflows.This PR implements the ADR 003 handler pattern for polling, replacing bridge pipelines with injected handler services. The polling system recognises a condition (new data detected) and hands off to whatever the solution provider has configured — without knowing what that is.
Temporal instantiation bug fixed
NewDataDetectionPipeline.__init__previously required aresult_handlerargument that Temporal could never provide — the worker registers the workflow class and Temporal instantiates it with no arguments. The handler was structurally unreachable.The fix moves the handler lookup to
get_handler(), an instance method that subclassing pipelines can override. Temporal instantiates the base class (no-op, returnsNone) or a subclass (returns the appropriate handler). No constructor injection required.Business logic extracted to use case
The polling, change-detection, and handler coordination logic that lived directly in the workflow
run()method has been extracted toPollDataUseCase. The pipeline is now pure Temporal orchestration. The use case can be tested standalone without Temporal.PollingManager.start_pollingfixedThe manager was passing
args=[config, downstream_pipeline]to the scheduled workflow, butrun()only acceptsconfig— a silent mismatch. Thedownstream_pipelinearg is replaced byworkflow_name, which lets solution providers schedule a specific subclass for a polling change detection pipeline.