Skip to content

Remove eager full sync from RemoteEventsList#67

Merged
rbren merged 3 commits intomainfrom
remove-eager-full-sync
Mar 4, 2026
Merged

Remove eager full sync from RemoteEventsList#67
rbren merged 3 commits intomainfrom
remove-eager-full-sync

Conversation

@rbren
Copy link
Contributor

@rbren rbren commented Mar 4, 2026

Problem

RemoteEventsList eagerly fetches all events (paginating with limit=100) in its constructor via doFullSync(). This fires on every conversation load — even though the only production consumer (the conversations UI) exclusively uses .search() with its own params and never touches the cache-backed methods.

This means every conversation load makes a superfluous GET /events/search?limit=100 call that downloads data nobody reads.

Changes

  • Remove doFullSync(), syncPromise, ensureSynced(), and AsyncLock from RemoteEventsList — the constructor no longer fires any network requests
  • getEvents() now fetches from the server on-demand (same pagination logic), merging in any locally-cached WebSocket events not yet persisted server-side
  • addEvent() still appends to the local cache for WebSocket events
  • search(), count(), and all other methods are unchanged

What still works

  • SDK users calling getEvents() / async iterator still get the full event history (fetched on demand instead of eagerly)
  • WebSocket events are still cached locally via addEvent()
  • search() is completely unaffected

Testing

  • tsc --noEmit passes
  • All 118 unit tests pass

rbren and others added 3 commits March 4, 2026 18:49
The constructor was eagerly calling doFullSync() which paginated through
ALL events (100 per page) on every conversation load. This caused a flood
of search?limit=100 requests even though the UI only needs the last 10
events initially and uses WebSocket for new events.

Now doFullSync() is only triggered when getEvents() or ensureSynced() is
explicitly called, which the conversations UI never does.

Co-authored-by: openhands <openhands@all-hands.dev>
The constructor was firing a doFullSync() that paginated through ALL events
(limit=100 per page) on every instantiation — even when no caller ever used
the cache-backed methods (getEvents, getEvent, length, asyncIterator).

The only production consumer (the conversations UI) exclusively uses .search()
which hits the API directly, so the sync was pure waste.

Changes:
- Remove doFullSync(), syncPromise, ensureSynced(), and the AsyncLock from
  RemoteEventsList
- Make getEvents() fetch from the server on demand instead of reading from
  a pre-populated cache, merging in any WebSocket-delivered events not yet
  persisted server-side
- addEvent() still appends to the local cache for WebSocket events

Co-authored-by: openhands <openhands@all-hands.dev>
@rbren rbren force-pushed the remove-eager-full-sync branch from ee2931c to ae545fd Compare March 4, 2026 19:03
@rbren rbren merged commit 39dedf0 into main Mar 4, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant