Skip to content

Commit 7fb5724

Browse files
committed
fix tests
1 parent caac58d commit 7fb5724

File tree

1 file changed

+61
-23
lines changed

1 file changed

+61
-23
lines changed

sentience/cloud_tracing.py

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -148,40 +148,78 @@ def close(
148148

149149
self._closed = True
150150

151-
# Flush and sync file to disk before closing to ensure all data is written
152-
# This is critical on CI systems where file system operations may be slower
153-
self._trace_file.flush()
151+
if not blocking:
152+
# Fire-and-forget background finalize+upload.
153+
#
154+
# IMPORTANT: for truly non-blocking close, we avoid synchronous work here
155+
# (flush/fsync/index generation). That work happens in the background thread.
156+
thread = threading.Thread(
157+
target=self._close_and_upload_background,
158+
args=(on_progress,),
159+
daemon=True,
160+
)
161+
thread.start()
162+
return # Return immediately
163+
164+
# Blocking mode: finalize trace file and upload now.
165+
if not self._finalize_trace_file_for_upload():
166+
return
167+
self._do_upload(on_progress)
168+
169+
def _finalize_trace_file_for_upload(self) -> bool:
170+
"""
171+
Finalize the local trace file so it is ready for upload.
172+
173+
Returns:
174+
True if there is data to upload, False if the trace is empty/missing.
175+
"""
176+
# Flush and sync file to disk before closing to ensure all data is written.
177+
# This can be slow on CI file systems; in non-blocking close we do this in background.
178+
try:
179+
self._trace_file.flush()
180+
except Exception:
181+
pass
154182
try:
155-
# Force OS to write buffered data to disk
156183
os.fsync(self._trace_file.fileno())
157184
except (OSError, AttributeError):
158-
# Some file handles don't support fsync (e.g., StringIO in tests)
159-
# This is fine - flush() is usually sufficient
185+
# Some file handles don't support fsync; flush is usually sufficient.
186+
pass
187+
try:
188+
self._trace_file.close()
189+
except Exception:
160190
pass
161-
self._trace_file.close()
162191

163192
# Ensure file exists and has content before proceeding
164-
if not self._path.exists() or self._path.stat().st_size == 0:
165-
# No events were emitted, nothing to upload
166-
if self.logger:
167-
self.logger.warning("No trace events to upload (file is empty or missing)")
168-
return
193+
try:
194+
if not self._path.exists() or self._path.stat().st_size == 0:
195+
if self.logger:
196+
self.logger.warning("No trace events to upload (file is empty or missing)")
197+
return False
198+
except Exception:
199+
# If we can't stat, don't attempt upload
200+
return False
169201

170202
# Generate index after closing file
171203
self._generate_index()
204+
return True
172205

173-
if not blocking:
174-
# Fire-and-forget background upload
175-
thread = threading.Thread(
176-
target=self._do_upload,
177-
args=(on_progress,),
178-
daemon=True,
179-
)
180-
thread.start()
181-
return # Return immediately
206+
def _close_and_upload_background(self, on_progress: Callable[[int, int], None] | None = None) -> None:
207+
"""
208+
Background worker for non-blocking close.
182209
183-
# Blocking mode
184-
self._do_upload(on_progress)
210+
Performs file finalization + index generation + upload.
211+
"""
212+
try:
213+
if not self._finalize_trace_file_for_upload():
214+
return
215+
self._do_upload(on_progress)
216+
except Exception as e:
217+
# Non-fatal: preserve trace locally
218+
self._upload_successful = False
219+
print(f"❌ [Sentience] Error uploading trace (background): {e}")
220+
print(f" Local trace preserved at: {self._path}")
221+
if self.logger:
222+
self.logger.error(f"Error uploading trace (background): {e}")
185223

186224
def _do_upload(self, on_progress: Callable[[int, int], None] | None = None) -> None:
187225
"""

0 commit comments

Comments
 (0)