Skip to content

fix: Prevent losing a status message when redirecting Actor run logs - #1036

Merged
vdusek merged 3 commits into
masterfrom
fix/actor-call-redirect-logger-race
Aug 27, 2026
Merged

fix: Prevent losing a status message when redirecting Actor run logs#1036
vdusek merged 3 commits into
masterfrom
fix/actor-call-redirect-logger-race

Conversation

@vdusek

@vdusek vdusek commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

What

ActorClient.call built its two log redirectors inside a single with statement:

with run_client.get_status_message_watcher(to_logger=logger), run_client.get_streamed_log(to_logger=logger):

with A(), B(): enters A before constructing B, so the status watcher's polling thread was already running - and already logging into apify.<actor> runId:<id> - when get_streamed_log called create_redirect_logger on that same logger. That call reconfigures the logger from scratch (propagate = False, removeHandler, addHandler), so a status message emitted in that window went to a logger that was mid-rebuild and was dropped.

Both redirectors are now constructed before either one starts polling, which is what the async call already did.

Why

This surfaced as a flaky unit test - CI run 32853344220, test_actor_call_redirect_logs_to_default_logger_sync on ubuntu-latest / 3.13. Status: RUNNING, Message: Initial message appeared in captured stderr but not in caplog, i.e. the record reached the logger's own handler while propagate was False. Only the sync test ever flaked, because the async call constructs both redirectors up front and so has no such window.

The nondeterminism is in the client, not in the test: under real usage the same window can silently drop a status message.

Test

The new test pins the damaging interleaving with two events instead of relying on thread scheduling, so it is deterministic in both directions - it fails on master and passes with this change, at the same runtime either way.

Verification: the new test fails without the actor.py change and passes with it; full unit suite (911 passed), lint, type check and docstring check all pass. The original flake does not reproduce naturally on an 8-core machine (0 failures in 40 x tests/unit/test_logging.py under --numprocesses=16 before the change), which is why the regression test forces the interleaving rather than hammering for it.

✍️ Drafted by Claude Code

@vdusek vdusek added adhoc Ad-hoc unplanned task added during the sprint. t-tooling Issues with this label are in the ownership of the tooling team. labels Aug 25, 2026
@vdusek vdusek self-assigned this Aug 25, 2026
@github-actions github-actions Bot added this to the 148th sprint - Tooling team milestone Aug 25, 2026
@github-actions github-actions Bot added the tested Temporary label used only programatically for some analytics. label Aug 25, 2026
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.18%. Comparing base (514848f) to head (93a3f45).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1036      +/-   ##
==========================================
- Coverage   95.23%   95.18%   -0.06%     
==========================================
  Files          58       58              
  Lines        5436     5438       +2     
==========================================
- Hits         5177     5176       -1     
- Misses        259      262       +3     
Flag Coverage Δ
integration 91.70% <100.00%> (-0.37%) ⬇️
unit 87.21% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@vdusek
vdusek requested a review from Pijukatel August 26, 2026 15:46
@vdusek
vdusek marked this pull request as ready for review August 26, 2026 15:47
@vdusek
vdusek merged commit dba6aba into master Aug 27, 2026
30 checks passed
@vdusek
vdusek deleted the fix/actor-call-redirect-logger-race branch August 27, 2026 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

adhoc Ad-hoc unplanned task added during the sprint. t-tooling Issues with this label are in the ownership of the tooling team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants