Skip to content

refactor(room): Move validateTimer() out of getLobbyState()/getLobbyTimer() getters#17810

Merged
nickvergessen merged 1 commit into
mainfrom
refactor/noid/move-room-validateLobbyTimer
May 6, 2026
Merged

refactor(room): Move validateTimer() out of getLobbyState()/getLobbyTimer() getters#17810
nickvergessen merged 1 commit into
mainfrom
refactor/noid/move-room-validateLobbyTimer

Conversation

@miaulalala
Copy link
Copy Markdown
Contributor

@miaulalala miaulalala commented Apr 25, 2026

Make getLobbyState() and getLobbyTimer() pure getters by moving the timer-expiry side effect into an explicit RoomService::validateLobbyTimer() method called at the three entry points that gate all interactive user flows.

What changed

  • getLobbyState() and getLobbyTimer() are now pure getters (removed bool $validateTime parameter)
  • Timer-expiry logic extracted to RoomService::validateLobbyTimer(Room $room) with proper constructor DI
  • Called explicitly from RoomFormatter::formatRoomV4(), InjectionMiddleware::checkLobbyState(), and RoomPropertiesHelper::getPropertiesForSignaling()
  • ITimeFactory is no longer needed in Room's constructor

On the secondary callers

cc @nickvergessen

Some callers (Chat/Notifier, Dashboard/TalkWidget, Search, background jobs) read getLobbyState() without an explicit validateLobbyTimer() call. These callers only use the lobby state for display or notification decisions — not to gate access. Every interactive user flow (joining a room, sending a message, any API response) goes through InjectionMiddleware or RoomFormatter first, which validates the timer before the secondary callers are reached.

Making getLobbyState() auto-validate on every call is not feasible:

  • It causes infinite recursion: getLobbyState()validateLobbyTimer()setLobby()getLobbyState() (which reads old state before updating)
  • It breaks the federation sync comparison in syncProperties(), which intentionally reads the raw stored value to diff against the host

A background job running every minute was investigated but rejected — the documented recommendation is a 5-minute cron interval, which is too coarse for lobby timer precision.

AI (if applicable)

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

🛠️ API Checklist

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not possible
  • 📘 API documentation in docs/ has been updated or is not required
  • 🔖 Capability is added or not needed

@miaulalala miaulalala added this to the 🏖️ Next Major (34) milestone Apr 25, 2026
@miaulalala miaulalala self-assigned this Apr 25, 2026
@miaulalala miaulalala added feature: api 🛠️ OCS API for conversations, chats and participants feature: meetings 📅 Covering the webinary usecase incl. Lobby labels Apr 25, 2026
Comment thread lib/Room.php Outdated
@miaulalala miaulalala force-pushed the refactor/noid/move-room-validateLobbyTimer branch from cbdac8f to d094467 Compare April 25, 2026 12:57
@miaulalala miaulalala force-pushed the refactor/noid/move-room-validateLobbyTimer branch from d094467 to 20e762a Compare April 25, 2026 13:01
Comment thread tests/php/RoomTest.php
…imer() getters

getLobbyState() and getLobbyTimer() previously triggered a database write as a
side effect when called — if the lobby timer had expired, they would silently
reset the lobby state in the DB and fire events. This is incompatible with
Entity's assumption that getters are pure.

- Make getLobbyState() and getLobbyTimer() pure getters (remove bool $validateTime
  parameter)
- Extract the timer check into RoomService::validateLobbyTimer(Room $room) using
  proper constructor DI
- Call it explicitly at the three entry points that gate interactive user flows:
  RoomFormatter::formatRoomV4(), InjectionMiddleware::checkLobbyState(), and
  RoomPropertiesHelper::getPropertiesForSignaling()
- ITimeFactory is no longer needed in Room's constructor

The remaining callers (Chat/Notifier, Dashboard, search, background jobs) only
read lobby state for display or notification decisions — not to gate access. All
interactive flows (join, send message, API responses) go through InjectionMiddleware
or RoomFormatter first, which validates the timer before any secondary callers are
reached.

Making getLobbyState() always auto-validate is not feasible: it would cause infinite
recursion in setLobby() (which reads getLobbyState() to get the old state), and
would break the federation sync comparison in syncProperties() which intentionally
reads the raw stored value.

AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anna Larch <anna@nextcloud.com>
@miaulalala miaulalala force-pushed the refactor/noid/move-room-validateLobbyTimer branch from 93fe18d to e394740 Compare May 6, 2026 14:27
@miaulalala miaulalala requested a review from nickvergessen May 6, 2026 14:28
@nickvergessen nickvergessen merged commit 6fe980b into main May 6, 2026
79 checks passed
@nickvergessen nickvergessen deleted the refactor/noid/move-room-validateLobbyTimer branch May 6, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: api 🛠️ OCS API for conversations, chats and participants feature: meetings 📅 Covering the webinary usecase incl. Lobby

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants