Skip to content

Commit b2f7c32

Browse files
committed
Fix: Improve object addition synchronization in LiveBackend to handle cross-thread signal processing
1 parent ea1b39e commit b2f7c32

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

datalab_kernel/workspace.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -485,14 +485,28 @@ def add(self, name: str, obj: DataObject, overwrite: bool = False) -> None:
485485
# Set the title on the object
486486
obj.title = name
487487

488-
# add_object auto-detects panel based on object type
488+
# Determine which panel the object will be added to
489+
from sigima import SignalObj # pylint: disable=import-outside-toplevel
490+
491+
panel = "signal" if isinstance(obj, SignalObj) else "image"
492+
493+
# add_object uses cross-thread Qt signals - it returns before the signal
494+
# is processed by the main thread. We must poll until the object appears.
489495
self.proxy.add_object(obj)
490496

491-
# Force synchronization: add_object uses Qt signals without @remote_call
492-
# decorator, so it returns before the object is actually added.
493-
# Calling get_current_panel() (which has @remote_call) forces the Qt event
494-
# loop to process pending signals including SIG_ADD_OBJECT.
495-
self.proxy.get_current_panel()
497+
# Wait for object to appear (cross-thread signal processing)
498+
# On slow CI (Python 3.9), the signal may take time to be processed
499+
for _ in range(100): # 10 seconds total timeout
500+
try:
501+
titles = self.proxy.get_object_titles(panel=panel)
502+
if name in titles:
503+
return # Object successfully added
504+
except Exception: # pylint: disable=broad-exception-caught
505+
pass
506+
time.sleep(0.1)
507+
508+
# If we get here, the add failed (shouldn't happen normally)
509+
raise RuntimeError(f"Timeout waiting for object '{name}' to appear in DataLab")
496510

497511
def remove(self, name: str) -> None:
498512
"""Remove an object from the workspace.
@@ -821,14 +835,7 @@ def add(self, name: str, obj: DataObject, overwrite: bool = False) -> DataObject
821835
ValueError: If object exists and overwrite=False
822836
"""
823837
self._backend.add(name, obj, overwrite=overwrite)
824-
# For live backend, allow retry window for object to appear
825-
# This handles race conditions with XML-RPC (especially on Python 3.9)
826-
if isinstance(self._backend, LiveBackend):
827-
for _ in range(50): # 5 seconds total timeout
828-
try:
829-
return self._backend.get(name)
830-
except KeyError:
831-
time.sleep(0.1)
838+
# LiveBackend.add() waits for the object to appear, so get() should work
832839
return self._backend.get(name)
833840

834841
def remove(self, name: str) -> None:

0 commit comments

Comments
 (0)