fix(concurrent-source): surface stalled reads instead of hanging silently - #1084
Draft
devin-ai-integration[bot] wants to merge 2 commits into
Draft
fix(concurrent-source): surface stalled reads instead of hanging silently#1084devin-ai-integration[bot] wants to merge 2 commits into
devin-ai-integration[bot] wants to merge 2 commits into
Conversation
Co-Authored-By: bot_apk <apk@cognition.ai>
Co-Authored-By: bot_apk <apk@cognition.ai>
Contributor
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksTesting This CDK VersionYou can test this version of the CDK using the following: # Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@devin/1785239104-cdk-no-progress-watchdog#egg=airbyte-python-cdk[dev]' --help
# Update a connector to use the CDK from this branch ref:
cd airbyte-integrations/connectors/source-example
poe use-cdk-branch devin/1785239104-cdk-no-progress-watchdogPR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
|
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.
Summary
When a worker thread wedges inside
Partition.read(), the concurrent read path today produces nothing at all: no log, no trace, no state.ConcurrentSource._consume_from_queue()blocks on an untimedqueue.get(),PartitionReader.process_partition()only enqueues on return-or-raise, and the platform's 24hheartbeat_timeoutends up being the only detector. This PR closes the detection gap; it does not attempt to fix whatever wedges the worker.The consumer now polls instead of blocking forever, and tracks a monotonic "last time anything came off the queue" marker:
Two deliberate design choices:
no_progress_timeout_secondsis passed orAIRBYTE_NO_PROGRESS_TIMEOUT_SECONDSis set (non-integer / non-positive values are ignored with a warning). With no configuration, the only behaviour change is a periodic WARNING naming the streams that are generating partitions and the streams with running partitions — enough for a support engineer to see which stream is wedged, well before the 24h heartbeat.timeout_secondsis repurposed rather than newly enforced.DEFAULT_TIMEOUT_SECONDS = 900was plumbed throughcreate()/__init__but never passed toqueue.get()— its docstring promised behaviour that did not exist. It is now the warning interval, and the docstring says so. Enforcing it as a hard 15-minute kill would have been a breaking behaviour change for legitimately slow connectors.The warning/hard-fail checks are evaluated independently, so a
no_progress_timeout_secondssmaller thantimeout_secondsstill fires on time.Supporting changes:
ConcurrentReadProcessor.get_in_flight_streams_description()(deterministic, sorted) for the diagnostic detail, and a publicThreadPoolManager.shutdown()so the hard-fail path doesn't hang on exit.Declarative-First Evaluation
Not applicable — this is a CDK core change in the concurrent read path, not a connector change; no declarative/manifest feature can express a watchdog over the shared queue.
Test Coverage
New
unit_tests/sources/concurrent_source/test_no_progress_watchdog.py(8 tests in the package pass) using a deterministic fake clock: a stalled queue warns and does not raise when the hard timeout is unset; it raisesAirbyteTracedExceptionwithFailureType.system_errorwhen the timeout comes from the constructor and when it comes from the env var; normal reads and slow-but-progressing reads complete unchanged and do not trip the watchdog.Also verified:
unit_tests/sources/streams/concurrent(242 passed),ruff check,ruff format,mypy airbyte_cdk/sources/concurrent_source.Verification not done
I could not reproduce the original stall — it needs a GA4 property with a slice exceeding the 100,000-row
runReportpage limit, and no workspace/connection/job ID was available on the issue. The claim that this path is silent is verified by code read and by the production stack sample in #1015 (main thread parked inqueue.get() → not_empty.wait()); the claim that memory exhaustion is what wedges the worker is the reporter's hypothesis and is unverified here.Related to https://github.com/airbytehq/oncall/issues/13165:
The connector-side trigger is tracked separately in airbytehq/oncall#13164 / airbytehq/airbyte#82766.
Requested by
airbyte-support-botvia the/ai-fixautomation on the oncall issue.Link to Devin session: https://app.devin.ai/sessions/a787e277eee34a19827948340f9ad782