WIP: Recover presence leases after Redis state loss #47
Draft
KofTwentyTwo wants to merge 6 commits from
feature/presence-recovery-1300 into feature/collab
pull from: feature/presence-recovery-1300
merge into: QRun-IO:feature/collab
QRun-IO:develop
QRun-IO:fix/read-path-statements-develop
QRun-IO:release/1.2
QRun-IO:fix/read-path-statements-1.2
QRun-IO:fix/aurora-full-page-writes-1.2
QRun-IO:release/1.1
QRun-IO:fix/aurora-full-page-writes-develop
QRun-IO:fix/aurora-full-page-writes-1.1
QRun-IO:feat/custom-field-validation-forge
QRun-IO:fix/custom-field-length-and-help-20261106
QRun-IO:feature/kof22-collab-canonical
QRun-IO:feat/record-files-standalone
QRun-IO:main
QRun-IO:ci-qrun-release-caller-develop-v2
QRun-IO:feat/per-session-presence
QRun-IO:archive/qrun-github-cutover-20261101/1ae65087936e/develop
QRun-IO:fix/presence-empty-viewers
QRun-IO:feature/collab-int-20261029
QRun-IO:integration/redis-collaboration-20261029
QRun-IO:fix/mywork-query-bounds-1291
QRun-IO:test/presence-capacity-1302
QRun-IO:dependabot/maven/develop/maven-minor-and-patch-c55d8d628c
QRun-IO:dependabot/github_actions/develop/github-actions-0fdda1077f
QRun-IO:feature/field-values-1196
QRun-IO:fix/attachment-transactions-1289
QRun-IO:feature/collab
QRun-IO:feature/orb-0.8-track
QRun-IO:feature/orb-0.7.18
QRun-IO:feature/orb-0.7.17
QRun-IO:release/0.1
QRun-IO:feature/orb-standardize-release-0.1
QRun-IO:feature/orb-main-standardization
QRun-IO:feature/shared-codeql
QRun-IO:feature/orb-0712-stable-gate
QRun-IO:feature/orb-rc-worker
QRun-IO:feature/orb-0.7.11
QRun-IO:feature/central-ci
QRun-IO:ci/release-rc-secrets-inherit
QRun-IO:dependabot/maven/develop/com.puppycrawl.tools-checkstyle-14.3.0
QRun-IO:feature/ui-api-1.6
QRun-IO:fix/producer-version-from-build
QRun-IO:fix/help-bundle-version-test
QRun-IO:fix/help-bundle-version
QRun-IO:feature/help-bundle
QRun-IO:feature/tables-populated-defaults
QRun-IO:feature/qqq-rc7
QRun-IO:fix/issues-20-21
QRun-IO:feature/email-api
QRun-IO:feature/orb-0.6.9
QRun-IO:feature/object-storage-rc4
QRun-IO:feature/email-qbit
QRun-IO:fix/live-review
QRun-IO:feature/demo-dev-server
QRun-IO:feature/presence-custom-fields
QRun-IO:feature/ui-api-endpoints
QRun-IO:feature/contingent-fields
QRun-IO:fix/object-storage-api-only
QRun-IO:feature/sharing-tasks
QRun-IO:feature/tags
QRun-IO:feature/comments-follow-timeline
QRun-IO:feature/attachments
QRun-IO:feature/favorites-recents
QRun-IO:feature/scaffold-and-settings
No Reviewers
Labels
Clear labels
architecture
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
java
question
secuurity
wontfix
Architecture review: coupling, cohesion, UI API
Something isn't working
Improvements or additions to documentation
This issue or pull request already exists
New feature or request
Pull requests that update GitHub Actions code
Good for newcomers
Extra attention is needed
This doesn't seem right
Pull requests that update java code
Further information is requested
This will not be worked on
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: QRun-IO/qbit-collaboration#47
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Redis data loss can make an empty presence snapshot look like a room with no viewers. This candidate preserves a per-table recovery guard, returns 503 during recovery, and rejects invalidated leases so clients rejoin. A host-configured generation separates restored Redis state from current authority; nodes sharing a namespace must agree on lease lifetime.
The v2 key prefix requires coordinated rollout. Cold namespaces enter recovery; ordinary idle expiry retains a known-empty guard. Controlled restore requires stopped old nodes and a never-reused generation outside Redis. Host tooling to enforce this remains incomplete; this does not claim arbitrary rollback or split-brain recovery.
Validation on runtime commit
4b0d6a3: full wrapper verify passed 184 tests with no failures/errors/skips, packaging and coverage passed, and CircleCI job160 passed. Tests cover total loss, retained-guard projection loss, guard loss across untouched records, restored bytes under a fresh generation, HTTP 503/409/rejoin and preserved access checks.The final browser matrix passed Chromium, Firefox, WebKit, Pixel 7 emulation and iPad emulation against two independent JVMs. Both pages clear stale people during Redis loss and restore viewers without reload. Source/compiled Lua hashes were checked around every profile. This uses fixture authentication and an existing local frontend export, not a newly published frontend artifact, physical devices or deployed Kof22.
The controlled-restore harness saves a real Redis RDB image, verifies both old processes and listeners have stopped, clears and reloads the image, then starts two nodes with a fresh external generation. It requires old-lease rejection on both nodes before normal expiry, recovery 503s, and fresh cross-node rejoin. Redis DEBUG RELOAD is enabled only on the owned disposable loopback fixture.
Local cost diagnostics at 1,000 and 10,000 leases are documented in docs/acceptance/RECOVERY-COST.md. Removing repeated table scans reduced 1,000-lease recovery-renewal p95 from 4.20 ms to 0.82 ms in these individual runs. Single-connection loopback measurements without TLS/HTTP do not establish production capacity or an SLA.
Remaining before adoption: enforced host maintenance/reset and generation wiring, compatible artifact integration, deployed-host qualification, sustained capacity qualification. No recovery snapshot has been published or deployed.
Tracks QRun-IO/qqq#1300; does not close it.
Additional focused verification covers shared cold readiness, persistent known-empty state after normal expiry, and loss of each state/expiry half of record and table projections using server-issued leases. The surviving projection must remain unchanged on rejected renewal.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.