Skip to content

fix: daemon mode wasn't reporting progress - #264

Merged
epmog merged 1 commit into
OpenJobDescription:mainlinefrom
epmog:fix-progress
Jun 17, 2026
Merged

fix: daemon mode wasn't reporting progress#264
epmog merged 1 commit into
OpenJobDescription:mainlinefrom
epmog:fix-progress

Conversation

@epmog

@epmog epmog commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Fixes: #109

What was the problem/requirement? (What/Why)

In daemon mode, update_status() in BaseAdaptor wrote openjd_progress: and openjd_status: messages
directly to stdout via sys.stdout.write(). However, the background process's stdout is redirected to a
bootstrap output file and the logging stream handler is replaced with a LogBufferHandler.

Since sys.stdout.write() bypasses the logging framework entirely, progress/status messages never reached the log buffer, never got sent to the foreground via heartbeats, and the worker agent never saw them. Therefore no progress updates in any service.

   sequenceDiagram
      participant App as Application
      participant BG as Background Adaptor Process
      participant LB as LogBufferHandler
      participant FG as Foreground Adaptor Process
      participant WA as Worker Agent

      App->>BG: stdout: "Rendering 50 percent"
      BG->>BG: RegexHandler detects progress<br/>calls update_status(progress=50)
      BG--xBG: sys.stdout.write("openjd_progress: 50")<br/>fd 1 points to bootstrap file, nobody reads it
      Note over LB: LogBuffer never receives the message
      Note over FG: Heartbeat response has no progress data
      Note over WA: Never sees openjd_progress: 50
Loading

The run command worked fine because the process's stdout is directly monitored by the worker agent.

What was the solution? (How)

Changed update_status() to route messages through the logger at _ADAPTOR_OUTPUT_LEVEL instead of writing to sys.stdout directly.

  sequenceDiagram
      participant App as Application
      participant BG as Background Adaptor Process
      participant LB as LogBufferHandler
      participant FG as Foreground Adaptor Process
      participant WA as Worker Agent

      App->>BG: stdout: "Rendering 50 percent"
      BG->>BG: RegexHandler detects progress<br/>calls update_status(progress=50)
      BG->>LB: _logger.log(ADAPTOR_OUTPUT,<br/>"openjd_progress: 50")
      LB->>FG: Heartbeat response carries<br/>buffered output via socket
      FG->>FG: _logger.log(ADAPTOR_OUTPUT,<br/>"openjd_progress: 50")
      FG->>WA: StreamHandler writes to stdout<br/>"openjd_progress: 50"
      Note over WA: Worker agent detects progress
Loading

This works in both modes:

  • Run mode: The logger's StreamHandler(sys.stdout) with ConditionalFormatter outputs openjd_* prefixed
    messages without the level prefix — identical behavior to before.
  • Daemon mode: The LogBufferHandler captures the log record → heartbeat carries it to the frontend →
    frontend logs it at _ADAPTOR_OUTPUT_LEVEL through its own stdout stream handler → worker agent sees it.

What is the impact of this change?

Progress and status messages now correctly propagate from background adaptors to the worker agent in daemon mode. No change in behavior for run mode.

How was this change tested?

Added a new integration test (test_progress_in_background_mode.py) that:

  1. Starts a daemon with an adaptor that calls update_status(progress=50) during on_run
  2. Asserts openjd_progress: 50 appears on the frontend's stdout
  3. Includes a sanity check confirming run mode still works

Updated existing unit tests in test_base_adaptor.py to use caplog instead of capsys since messages now go through the logger. All existing integration tests (test_integration_entrypoint.py, test_background_mode.py) pass.

I also tested this manually in deadline-cloud with an updated adaptor for Blender.

Before

ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:8.42M (Peak 8.52M) | Time:00:00.03 | Mem:0.09M, Peak:0.09M | Scene, ViewLayer | Sample 0/4096
ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:119.33M (Peak 119.33M) | Time:00:00.17 | Remaining:09:19.35 | Mem:110.83M, Peak:110.83M | Scene, ViewLayer | Sample 1/4096
ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:119.33M (Peak 119.33M) | Time:00:22.15 | Remaining:05:30.33 | Mem:110.83M, Peak:110.83M | Scene, ViewLayer | Sample 257/4096
ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:119.33M (Peak 119.33M) | Time:00:44.07 | Remaining:05:07.60 | Mem:110.83M, Peak:110.83M | Scene, ViewLayer | Sample 513/4096
ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:119.33M (Peak 119.33M) | Time:01:06.02 | Remaining:04:45.46 | Mem:110.83M, Peak:110.83M | Scene, ViewLayer | Sample 769/4096

After

ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:8.42M (Peak 8.52M) | Time:00:00.03 | Mem:0.09M, Peak:0.09M | Scene, ViewLayer | Sample 0/20000
openjd_progress: 0
ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:119.33M (Peak 119.33M) | Time:00:00.17 | Remaining:45:12.50 | Mem:110.83M, Peak:110.83M | Scene, ViewLayer | Sample 1/20000
openjd_progress: 0
ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:119.33M (Peak 119.33M) | Time:00:22.17 | Remaining:28:21.02 | Mem:110.83M, Peak:110.83M | Scene, ViewLayer | Sample 257/20000
openjd_progress: 1
ADAPTOR_OUTPUT: STDOUT: Fra:1 Mem:119.33M (Peak 119.33M) | Time:00:44.15 | Remaining:27:55.85 | Mem:110.83M, Peak:110.83M | Scene, ViewLayer | Sample 513/20000
openjd_progress: 2

Was this change documented?

N/A

Is this a breaking change?

Fixing!

Does this change impact security?

N/A


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@epmog
epmog requested a review from a team as a code owner June 16, 2026 22:38
Signed-off-by: Morgan Epp <60796713+epmog@users.noreply.github.com>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just purely for testing right ?

@epmog
epmog merged commit ceff17f into OpenJobDescription:mainline Jun 17, 2026
23 checks passed
@epmog
epmog deleted the fix-progress branch June 17, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: daemon adaptors do not report progress or status messages

3 participants