mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 06:51:16 +08:00
fix(debug): sweep expired paste.rs uploads on a real timer (#16431)
Previously 'hermes debug share' uploads only got DELETEd when the user ran 'hermes debug share' again — opportunistic-sweep-on-invoke was the only cleanup path. A user who uploaded once and never ran debug again left pastes up until paste.rs's retention kicked in (which, empirically, never actually expires them). Hook _sweep_expired_pastes into the gateway cron ticker at the same hourly cadence as the image/document cache cleanups. The opportunistic sweep in 'hermes debug share' stays as a fallback for CLI-only users who never start the gateway.
This commit is contained in:
@@ -11153,13 +11153,16 @@ def _start_cron_ticker(stop_event: threading.Event, adapters=None, loop=None, in
|
|||||||
cron delivery path so live adapters can be used for E2EE rooms.
|
cron delivery path so live adapters can be used for E2EE rooms.
|
||||||
|
|
||||||
Also refreshes the channel directory every 5 minutes and prunes the
|
Also refreshes the channel directory every 5 minutes and prunes the
|
||||||
image/audio/document cache once per hour.
|
image/audio/document cache + expired ``hermes debug share`` pastes
|
||||||
|
once per hour.
|
||||||
"""
|
"""
|
||||||
from cron.scheduler import tick as cron_tick
|
from cron.scheduler import tick as cron_tick
|
||||||
from gateway.platforms.base import cleanup_image_cache, cleanup_document_cache
|
from gateway.platforms.base import cleanup_image_cache, cleanup_document_cache
|
||||||
|
from hermes_cli.debug import _sweep_expired_pastes
|
||||||
|
|
||||||
IMAGE_CACHE_EVERY = 60 # ticks — once per hour at default 60s interval
|
IMAGE_CACHE_EVERY = 60 # ticks — once per hour at default 60s interval
|
||||||
CHANNEL_DIR_EVERY = 5 # ticks — every 5 minutes
|
CHANNEL_DIR_EVERY = 5 # ticks — every 5 minutes
|
||||||
|
PASTE_SWEEP_EVERY = 60 # ticks — once per hour
|
||||||
|
|
||||||
logger.info("Cron ticker started (interval=%ds)", interval)
|
logger.info("Cron ticker started (interval=%ds)", interval)
|
||||||
tick_count = 0
|
tick_count = 0
|
||||||
@@ -11200,6 +11203,17 @@ def _start_cron_ticker(stop_event: threading.Event, adapters=None, loop=None, in
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("Document cache cleanup error: %s", e)
|
logger.debug("Document cache cleanup error: %s", e)
|
||||||
|
|
||||||
|
if tick_count % PASTE_SWEEP_EVERY == 0:
|
||||||
|
try:
|
||||||
|
deleted, remaining = _sweep_expired_pastes()
|
||||||
|
if deleted:
|
||||||
|
logger.info(
|
||||||
|
"Paste sweep: deleted %d expired paste(s), %d pending",
|
||||||
|
deleted, remaining,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug("Paste sweep error: %s", e)
|
||||||
|
|
||||||
stop_event.wait(timeout=interval)
|
stop_event.wait(timeout=interval)
|
||||||
logger.info("Cron ticker stopped")
|
logger.info("Cron ticker stopped")
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,13 @@ def _pending_file() -> Path:
|
|||||||
Each entry: ``{"url": "...", "expire_at": <unix_ts>}``. Scheduled
|
Each entry: ``{"url": "...", "expire_at": <unix_ts>}``. Scheduled
|
||||||
DELETEs used to be handled by spawning a detached Python process per
|
DELETEs used to be handled by spawning a detached Python process per
|
||||||
paste that slept for 6 hours; those accumulated forever if the user
|
paste that slept for 6 hours; those accumulated forever if the user
|
||||||
ran ``hermes debug share`` repeatedly. We now persist the schedule
|
ran ``hermes debug share`` repeatedly.
|
||||||
to disk and sweep expired entries on the next debug invocation.
|
|
||||||
|
Deletion is now driven by the gateway's cron ticker
|
||||||
|
(``gateway/run.py::_start_cron_ticker``) which calls
|
||||||
|
``_sweep_expired_pastes`` once per hour. ``hermes debug share`` also
|
||||||
|
runs an opportunistic sweep on entry as a fallback for CLI-only users
|
||||||
|
who never start the gateway.
|
||||||
"""
|
"""
|
||||||
return get_hermes_home() / "pastes" / "pending.json"
|
return get_hermes_home() / "pastes" / "pending.json"
|
||||||
|
|
||||||
@@ -223,9 +228,10 @@ def _schedule_auto_delete(urls: list[str], delay_seconds: int = _AUTO_DELETE_SEC
|
|||||||
interpreters that never exited until the sleep completed.
|
interpreters that never exited until the sleep completed.
|
||||||
|
|
||||||
The replacement is stateless: we append to ``~/.hermes/pastes/pending.json``
|
The replacement is stateless: we append to ``~/.hermes/pastes/pending.json``
|
||||||
and rely on opportunistic sweeps (``_sweep_expired_pastes``) called from
|
and the gateway's cron ticker sweeps expired entries once per hour.
|
||||||
every ``hermes debug`` invocation. If the user never runs ``hermes debug``
|
``hermes debug share`` also runs an opportunistic sweep as a fallback
|
||||||
again, paste.rs's own retention policy handles cleanup.
|
for CLI-only users. If neither runs again, paste.rs's own retention
|
||||||
|
policy handles cleanup.
|
||||||
"""
|
"""
|
||||||
_record_pending(urls, delay_seconds=delay_seconds)
|
_record_pending(urls, delay_seconds=delay_seconds)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user