nikeshn commited on
Commit
75a0dbf
·
verified ·
1 Parent(s): 3b63aaf

Upload 12 files

Browse files
Files changed (1) hide show
  1. src/agentcore/orchestrator.py +47 -1
src/agentcore/orchestrator.py CHANGED
@@ -184,6 +184,22 @@ def analytics_log_status() -> dict:
184
  }
185
 
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  async def _send_log_payload(worker_url: str, token: str, payload: dict):
188
  """POST one analytics payload.
189
 
@@ -208,6 +224,34 @@ async def _send_log_payload(worker_url: str, token: str, payload: dict):
208
  return resp.status_code, report
209
 
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  async def _flush_pending(worker_url: str, token: str, max_items: int = 5):
212
  """Re-attempt parked payloads oldest-first; stop at the first failure so a
213
  still-blocked Worker is not hammered."""
@@ -272,7 +316,7 @@ def _log_agent_query(question: str, response: AgentResponse, start_time: float)
272
  except Exception:
273
  pass
274
  try:
275
- status, report = await _send_log_payload(worker_url, _token, _payload)
276
  except Exception as _exc:
277
  _PENDING_LOGS.append(_payload)
278
  _record_attempt("unreachable", f"{type(_exc).__name__}: {_exc}")
@@ -320,6 +364,8 @@ def _log_agent_query(question: str, response: AgentResponse, start_time: float)
320
 
321
  if not _spawn_background(_post_to_worker()):
322
  logger.warning("D1 logging skipped: no running event loop")
 
 
323
  except Exception:
324
  pass
325
 
 
184
  }
185
 
186
 
187
+ async def _send_with_retry(worker_url: str, token: str, payload: dict,
188
+ attempts: int = 2, backoff: float = 2.0):
189
+ """_send_log_payload with one retry after a short backoff. Connectivity to
190
+ workers.dev from this host drops for short windows; a single immediate
191
+ retry recovers a meaningful fraction of those without involving the buffer."""
192
+ last_exc = None
193
+ for i in range(attempts):
194
+ try:
195
+ return await _send_log_payload(worker_url, token, payload)
196
+ except Exception as exc:
197
+ last_exc = exc
198
+ if i + 1 < attempts:
199
+ await asyncio.sleep(backoff)
200
+ raise last_exc
201
+
202
+
203
  async def _send_log_payload(worker_url: str, token: str, payload: dict):
204
  """POST one analytics payload.
205
 
 
224
  return resp.status_code, report
225
 
226
 
227
+ _FLUSHER_STARTED = {"on": False}
228
+
229
+
230
+ def _ensure_periodic_flusher(worker_url: str, token: str) -> None:
231
+ """Start (once) a background loop that retries buffered rows every 90s, so
232
+ parked writes land as soon as connectivity returns instead of waiting for
233
+ the next user query. The task holds a strong reference via _spawn_background.
234
+ Lost on container restart - like the buffer itself - which the keep-alive
235
+ pings are there to make rare."""
236
+ if _FLUSHER_STARTED["on"]:
237
+ return
238
+
239
+ async def _loop():
240
+ while True:
241
+ await asyncio.sleep(90)
242
+ if _PENDING_LOGS:
243
+ try:
244
+ n = await _flush_pending(worker_url, token, max_items=10)
245
+ if n:
246
+ _record_attempt("flushed", f"{n} buffered row(s) delivered")
247
+ except Exception:
248
+ pass
249
+
250
+ if _spawn_background(_loop()):
251
+ _FLUSHER_STARTED["on"] = True
252
+ logger.info("Analytics flusher started (90s interval)")
253
+
254
+
255
  async def _flush_pending(worker_url: str, token: str, max_items: int = 5):
256
  """Re-attempt parked payloads oldest-first; stop at the first failure so a
257
  still-blocked Worker is not hammered."""
 
316
  except Exception:
317
  pass
318
  try:
319
+ status, report = await _send_with_retry(worker_url, _token, _payload)
320
  except Exception as _exc:
321
  _PENDING_LOGS.append(_payload)
322
  _record_attempt("unreachable", f"{type(_exc).__name__}: {_exc}")
 
364
 
365
  if not _spawn_background(_post_to_worker()):
366
  logger.warning("D1 logging skipped: no running event loop")
367
+ else:
368
+ _ensure_periodic_flusher(worker_url, _token)
369
  except Exception:
370
  pass
371