Skip to content

fix(updater): Prevent EventSource auto-reconnect from triggering concurrent upgrades#59143

Draft
joshtrichards wants to merge 3 commits intomasterfrom
jtr/fix-updater-disable-EventSource-auto-reconnect
Draft

fix(updater): Prevent EventSource auto-reconnect from triggering concurrent upgrades#59143
joshtrichards wants to merge 3 commits intomasterfrom
jtr/fix-updater-disable-EventSource-auto-reconnect

Conversation

@joshtrichards
Copy link
Member

  • Resolves: #

Summary

The native EventSource API automatically reconnects when a connection drops. For the web updater, this is dangerous: core/ajax/update.php is not idempotent -- it runs database migrations, toggles maintenance mode, and modifies app state. A silent reconnect spawns a second PHP process that races against the still-running first one, which can cause migration deadlocks, database corruption, or inconsistent app state.

The auto-reconnect is dangerous specifically because it re-enters core/ajax/update.php directly, which has no guard against concurrent execution -- it just checks Util::needUpgrade() and calls $updater->upgrade(). A manual reload goes through normal routing (e.g. OC::handleRequest()) which respects maintenance mode.

This is especially insidious because the reconnect is invisible to the user. Resulting failures (stuck maintenance mode, broken apps, corrupted schema) would never be traced back to the SSE transport layer.

Changes:

  • Add an onerror handler to the underlying EventSource that immediately closes the connection instead of allowing auto-reconnect.
  • Display a warning message advising the user to reload the page to check the current upgrade status.

TODO

  • Decide whether to backport

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

The browser's native EventSource API silently reconnects on connection loss. Since core/ajax/update.php is non-idempotent (it runs database migrations, enables/disables apps, toggles maintenance mode), a reconnect causes a second concurrent upgrade process to race against the first. This can result in duplicate migrations, deadlocks, or silent data corruption -- none of which would be traceable back to the SSE transport layer.

Explicitly close the EventSource on error and inform the user that the connection was lost, advising them to reload to check status.

Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
@joshtrichards
Copy link
Member Author

/compile

Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
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.

2 participants