fix: Prevent losing a status message when redirecting Actor run logs - #1036
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
vdusek
marked this pull request as ready for review
August 26, 2026 15:47
Pijukatel
approved these changes
Aug 27, 2026
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
ActorClient.callbuilt its two log redirectors inside a singlewithstatement:with A(), B():entersAbefore constructingB, so the status watcher's polling thread was already running - and already logging intoapify.<actor> runId:<id>- whenget_streamed_logcalledcreate_redirect_loggeron 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
callalready did.Why
This surfaced as a flaky unit test - CI run 32853344220,
test_actor_call_redirect_logs_to_default_logger_synconubuntu-latest/ 3.13.Status: RUNNING, Message: Initial messageappeared in captured stderr but not incaplog, i.e. the record reached the logger's own handler whilepropagatewasFalse. Only the sync test ever flaked, because the asynccallconstructs 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
masterand passes with this change, at the same runtime either way.Verification: the new test fails without the
actor.pychange 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 xtests/unit/test_logging.pyunder--numprocesses=16before the change), which is why the regression test forces the interleaving rather than hammering for it.✍️ Drafted by Claude Code