Skip to content

Fix remote file loading intermittently ignored at DataLab startup - #402

Merged
PierreRaybaut merged 4 commits into
developfrom
fix/398-remote-requests-at-startup
Oct 20, 2026
Merged

PierreRaybaut merged 4 commits into
developfrom
fix/398-remote-requests-at-startup

Conversation

@PierreRaybaut

@PierreRaybaut PierreRaybaut commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #398

Remote load_from_files and load_from_directory calls were sometimes silently ignored, or returned before the files were loaded, when sent right after DataLab started. Reproduced on Windows (Python 3.11, PyQt5): 4 to 5 failures out of 10 with the test of the issue.

Root cause

The XML-RPC server was started in _before_setup, before the main window was built. Remote commands are queued signals to the GUI thread: they ran as soon as setup code pumped the event loop (console setup, macro panel, remote_controlled wrappers...), on a partially built window. In instrumented runs, the load slot ran inside setup() for all 10 early requests:

  • when it ran before the History panel existed, BaseDataPanel.load_from_files raised AttributeError: 'NoneType' object has no attribute 'maybe_start_session_for_input': the file was never loaded, and the error never reached the client;
  • otherwise, a SIG_READY emitted by setup code (e.g. handle_autorefresh_action) set the shared is_ready flag and released the remote call before its command was done.

The lead mentioned in the issue (is_ready shared by all remote calls) is confirmed, but it only explains the early return, not the lost requests.

Changes

  • Requests wait for the main window: the server binds its port at startup but serves requests only once the window is set up (_after_setup). A client connecting earlier is accepted and gets its first answer once DataLab is ready, instead of being served by a partially built window. A server still waiting can be shut down.
  • Errors are reported to clients: every signal-based remote command runs through DLMainWindow.run_remote_command, which stores the exception raised by the command before signaling readiness (as call_method_slot already did). The client gets an xmlrpc.client.Fault instead of a silent success. The stored exception is reset at the start of each request.
  • add_object no longer works around a missing History panel: this workaround existed only because of this race.
  • Tests (remote_requests_unit_test.py): scenario of the issue for files and directory, checked right after the call without polling; error reporting for calc with an unknown function and set_object with an unknown object.
  • Release notes 1.4.0.

Behavior changes for remote clients (DataLab RemoteProxy, Sigima SimpleRemoteProxy)

  • Errors raised by remote commands now reach the client as xmlrpc.client.Fault; e.g. calc with an unknown function used to return True.
  • A client connecting while DataLab starts now waits until DataLab is ready (about 10 s here).
  • No protocol change: no XML-RPC method is added or removed.

Validation

  • Instrumented background DataLab, requests sent right after connecting: 0 failures out of 20 (5 out of 10 before). In all 20 runs, requests were processed after _after_setup, and calls returned once the files were loaded.
  • The new tests fail on develop (assert 0 == 1: load lost; DID NOT RAISE Fault) and pass on this branch.
  • Full DataLab test suite: 1026 passed, 3 skipped.
  • Ruff and Pylint (10.00/10) pass.

Out of scope

  • is_ready remains a single flag shared by all remote calls: once DataLab is started, a SIG_READY emitted by an unrelated GUI action, or by a Web API request, during a pending remote call can still release it early. A per-request synchronization would remove this class of issues.
  • The end-to-end test of RAW import parameters (param argument of load_from_files / load_from_directory) belongs to the RAW import branch, which should be rebased on this fix.
  • Two pre-existing problems found while checking the Web API, not caused or fixed by this PR:

The XML-RPC server was started before the main window was built, so
requests could be processed while the window was still being set up:
whenever setup code pumped the event loop, a queued command ran on a
partially built window. load_from_files and load_from_directory then
failed because the History panel did not exist yet, and calls could
return before their command was done because readiness signaled by
setup code released them.

- The server binds its port at startup, but serves requests only once
  the main window is set up (_after_setup): clients connecting earlier
  wait instead of being refused. A server still waiting can be shut
  down.
- Remote commands run through run_remote_command, which stores the
  exception raised by the command before signaling readiness, so that
  the error is reported to the client instead of being silently
  ignored. The stored exception is reset at the start of each request.
- add_object no longer works around a missing History panel, which
  existed only because of this startup race.

Assisted-by: Claude Opus 5.5
Files loaded with load_from_files and load_from_directory right after
connecting to a background DataLab must be loaded when the call returns,
without polling. Errors raised by remote commands (calc with an unknown
function, set_object with an unknown object) must be reported to the
client, and not again by the next command.

Assisted-by: Claude Opus 5.5
)

- A remote command returning None (e.g. get_current_object_uuid with no
  current object) returned the result of the previous command instead,
  such as the panel name returned by call_method: the result is now
  reset at the start of each request, like the exception.
- Closing DataLab while a remote call was waiting for it to be ready
  (e.g. call_method("close")) hung DataLab: the main window, blocked
  until the server stopped, could never signal that the request was
  done. Shutting down the server now releases the waiting call first.

Both are covered by new tests, the closing one failing instead of
hanging should the deadlock come back.

Assisted-by: Claude Opus 5.5
@PierreRaybaut
PierreRaybaut merged commit 9161e0e into develop Oct 20, 2026
6 checks passed
@PierreRaybaut
PierreRaybaut deleted the fix/398-remote-requests-at-startup branch October 23, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant