Commit Graph
2 Commits
Author SHA1 Message Date
Lotus CIandClaude Opus 5.5 8cdf192b56 fix(status): status changes apply at once instead of waiting out the rate limit
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Build & Quality Checks (pull_request) Successful in 3m55s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 27s
CI / Playwright smoke (e2e) (pull_request) Successful in 33m26s
Synapse allows one presence write per 10 s per user (shared by every
device). The heartbeat wrote presence at startup and on every tab
switch, so a status save right after usually got a 429 and waited 7-25 s,
with the whole status section (quick statuses, input, Clear) locked and
the Save spinner going.

- One shared presence queue (heartbeat + status save), newest write wins:
  changes made while a write waits out a 429 replace it, so only the latest
  is sent, as soon as the server allows.
- The status UI no longer waits on the server: the status applies locally,
  Save switches off (it compared with the server echo, so it stayed lit
  and invited a second, guaranteed-429 write), the controls stay usable,
  and a short note shows until the write lands.
- The heartbeat skips writes the server already reflects (e.g. "online"
  at startup), so it stops spending the budget for nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-25 20:14:12 -04:00
jaredandClaude Opus 5 f5e7fb4746 fix(status): status save no longer fails on Synapse's 1-per-10s presence limit
Reported: 'Failed to save status — server may be rate limiting. Try again.'
on the first status change in a month. Root cause: Synapse rate-limits
PUT /presence/{user}/status to ONE request per 10 s per user by default
(rc_presence.per_user: per_second 0.1, burst_count 1), shared across all of
the user's devices, and our presence heartbeat (online/away on visibility and
activity changes, from every open tab/device) spends that budget — so a manual
save that lands within 10 s of a heartbeat gets a 429, which the form showed
as a dead end.

Two fixes: (1) the status save waits out Retry-After (bounded to ~25 s) via
setPresenceWithRetry instead of failing, and the error text now says what
actually happened (rate limit / server text / offline); (2) the heartbeat
dedupes — it only sends when presence or status actually changes (/sync
already keeps us online), so it stops burning the budget in the first place.
Unit-tested; reproduced headless with a routed 10 s limiter: heartbeat ok →
save 429 → retried 8 s later → saved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-19 17:41:09 -04:00