Skip to content

fix(chat): wait for the Matrix session restore before asking to reconnect - #421

Merged
tompscanlan merged 2 commits into
mainfrom
fix/matrix-chat-waits-for-session-restore
Oct 27, 2026
Merged

tompscanlan merged 2 commits into
mainfrom
fix/matrix-chat-waits-for-session-restore

Conversation

@tompscanlan

Copy link
Copy Markdown
Contributor

Problem

Some people get "Matrix Connection Required" on an event chat even though their Matrix session is still valid. Clicking "Connect to Matrix" sends them through the Matrix sign-in again. It happens some of the time, not every time.

On a fresh page load the Matrix session is restored in the background. The event page can mount the chat before that restore has created the client. The chat's mount check saw "tokens stored, no working client" and decided the session was broken. It showed the connect prompt and ran a cleanup that reset the restore halfway through.

A second problem sits next to it. Each tab claims a Matrix device with Web Locks, which is what lets several tabs chat at once. Web Locks are not re-entrant. If two restores in the same tab claim a device at the same moment, the second finds the tab's own lock taken, gets no device, and ends up in a full sign-in.

Change

  • waitForStartupRestore() on the Matrix client manager resolves once any in-flight restore settles. Concurrent startup calls share one restore.
  • The chat waits on it before judging the stored session. The rest of its setup does not wait. A session that really is unusable still gets the connect prompt.
  • The auth store starts the restore synchronously, so the restore is already visible when the store reports it is initialized.
  • Concurrent device claims in one tab share a single claim. Claims across tabs work as before: first tab gets the primary device, other tabs use the pool.

Tests

  • New: chat does not show "Connect to Matrix" while the restore runs, keeps the chat when the restore succeeds, and still shows it when the restore ends without a client.
  • New: waitForStartupRestore() waits for the restore, survives a failed restore, and returns at once when nothing is running.
  • New: two concurrent device claims in one tab both get the primary device. This test returned null for the second claim before the fix.
  • The device ID test's private-access type collapsed to never. Fixed, so that file has no type errors now.
  • Full unit suite: 818 passed, 42 failed. The same 42 fail on main (calendar, date picker, profile form, group events page). Type errors go from 305 on main to 279, and none are in the changed files.

Not tested in a real browser yet.

…nect

On a fresh page load the Matrix session is restored in the background. The
event page can mount chat before that restore has created the client. The
chat's stored-session check treated that moment as "tokens but no working
client". It showed "Connect to Matrix" for a valid session, and its cleanup
reset the restore halfway through, which lets a later restore start
alongside the first one.

- Add waitForStartupRestore() to the Matrix client manager. It resolves once
  any in-flight restore settles. Concurrent startup calls now share one
  restore.
- The chat waits on it before judging the stored session, without holding up
  the rest of its setup. A session that really is unusable still gets the
  connect prompt.
- The auth store starts the restore synchronously, so the restore is visible
  before the store reports it is initialized.
- Concurrent device ID claims in one tab now share a single claim. Web Locks
  are not re-entrant, so a second claim found the tab's own device lock taken
  and fell through to a new device, which means a full Matrix sign-in.

The device ID test's private-access type no longer collapses to never, which
clears that file's type errors.
…when it stalls

Review of the previous commit found two problems with sharing one startup
restore.

Logout stays in the app, so the shared restore outlived it. If a restore was
still running, the next login reused it instead of starting its own. That
login could end up with no chat, or, when switching accounts, with a restore
started for the previous account. The shared restore is now tied to the
signed-in user, logout drops it, and a restore that was dropped or replaced
can no longer clear the one that replaced it. Dropping it does not cancel it.

Some restore requests have no timeout. With chat now waiting for the restore,
a stuck one would leave "Loading chat room..." on screen with no way out.
After 15 seconds the chat now offers a reload. Nothing is cleared, so a
restore that finishes late still brings the chat up.

Tests cover logout during a restore, a second user, an unmount before the
restore settles, and the slow-restore message. The component tests now
unmount their wrappers.
@tompscanlan
tompscanlan merged commit 4eb227d into main Oct 27, 2026
3 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