Skip to content

Fix/presence user syncing nonblocking#19885

Open
shcherbak wants to merge 8 commits into
element-hq:developfrom
shcherbak:fix/presence-user-syncing-nonblocking
Open

Fix/presence user syncing nonblocking#19885
shcherbak wants to merge 8 commits into
element-hq:developfrom
shcherbak:fix/presence-user-syncing-nonblocking

Conversation

@shcherbak

Copy link
Copy Markdown
Contributor

presence: run set_state in background during user_syncing to unblock sync

user_syncing() was awaiting set_state() before returning the context
manager, causing every /sync request to block on presence I/O (DB
read/write on the presence writer, or an HTTP RPC from workers). Move
the counter increment and mark_as_coming_online ahead of the call, then
fire set_state via run_in_background consistent with how _end() is
already handled.

…sync

user_syncing() was awaiting set_state() before returning the context
manager, causing every /sync request to block on presence I/O (DB
read/write on the presence writer, or an HTTP RPC from workers). Move
the counter increment and mark_as_coming_online ahead of the call, then
fire set_state via run_in_background  consistent with how _end() is
already handled.
@shcherbak
shcherbak requested a review from a team as a code owner June 26, 2026 20:57
…sync

user_syncing() was awaiting set_state() before returning the context
manager, causing every /sync request to block on presence I/O (DB
read/write on the presence writer, or an HTTP RPC from workers). Move
the counter increment and mark_as_coming_online ahead of the call, then
fire set_state via run_in_background  consistent with how _end() is
already handled.
…sync

user_syncing() was awaiting set_state() before returning the context
manager, causing every /sync request to block on presence I/O (DB
read/write on the presence writer, or an HTTP RPC from workers). Move
the counter increment and mark_as_coming_online ahead of the call, then
fire set_state via run_in_background  consistent with how _end() is
already handled.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prevents /sync from blocking on presence state updates by moving the set_state call in user_syncing() to a background task, reducing sync-start latency when presence I/O is slow (DB/RPC).

Changes:

  • Stop awaiting set_state() in user_syncing() and instead schedule it via run_in_background() to avoid blocking sync start.
  • Reorder sync-tracking updates so the “currently syncing” counters and “coming online” bookkeeping happen before the presence update is dispatched.
  • Add a Towncrier newsfragment documenting the /sync unblocking behavior change.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
synapse/handlers/presence.py Makes user_syncing() fire-and-forget the presence set_state() update to avoid blocking /sync on presence I/O.
changelog.d/19885.bugfix Adds a changelog entry noting /sync is no longer blocked by presence updates when enabled.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +611 to +619
# Note that this causes last_active_ts to be incremented which is not
# what the spec wants. Run in background to avoid blocking sync start.
run_in_background(
self.set_state,
UserID.from_string(user_id),
device_id,
{"presence": presence_state},
is_sync=True,
)
Comment on lines 1181 to 1185
# Note that this causes last_active_ts to be incremented which is not
# what the spec wants.
await self.set_state(
# what the spec wants. Run in background to avoid blocking sync start.
run_in_background(
self.set_state,
UserID.from_string(user_id),

@anoadragon453 anoadragon453 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shcherbak have you observed a noticeable difference in real-world usage with this change? I ask, as this is the first time I'm hearing of /sync being slow due to setting presence. I would expect /sync to take much more resources than updating presence state.

It also appears that presence tests are failing with this change.

@shcherbak

Copy link
Copy Markdown
Contributor Author

enabling presence on my instance caused massive key synchronization problems because of blocking. Yes, I saw the failing tests. This mr is a draft , I need advice to move forward with it. @anoadragon453 do You see any posiible sollutions?

@anoadragon453

Copy link
Copy Markdown
Member

Thanks for your initial work on this @shcherbak. Heads up that #19946 might end up superseding this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants