Skip to content

The Room class moves to src/room/php_room.c - #165

Merged
EdmondDantes merged 1 commit into
mainfrom
refactor/room-class-own-file
Aug 16, 2026
Merged

The Room class moves to src/room/php_room.c#165
EdmondDantes merged 1 commit into
mainfrom
refactor/room-class-own-file

Conversation

@EdmondDantes

Copy link
Copy Markdown
Contributor

http_server_class.c carried the whole PHP object layer over rooms: the Room
class with its object handlers and transfer_obj, the delivery/knob helpers, and
the six HttpServer methods that address a room by name — 850 lines of a
subsystem the server owns only a hub of, in the largest file in the tree. They
move to src/room/php_room.c, beside the core they drive.

The move is verbatim. Four substitutions were applied to the moved text, because
http_server_object's layout is private to http_server_class.c:

Z_HTTP_SERVER_P(ZEND_THIS)  ->  http_server_object_from_zend(Z_OBJ_P(ZEND_THIS))
server->running             ->  http_server_is_running(server)
server->topic_hub           ->  http_server_get_topic_hub(server)
server->topic_hub = room_hub_create(…)  ->  http_server_topic_hub_ensure(server)

The last two are new pinpoint accessors, declared in php_http_server.h — the
pattern src/http3/ already uses against the same opaque struct.
http_server_topic_hub_ensure() is now the only place a hub is created, and
the worker-clone rule that used to be spelled at one of the three creation sites
and omitted at another is stated once, inside it. A clone inherits its parent's
hub through the transfer shell; one minted on a clone would be attached by
nobody, and every publish through it would report served=0 with nothing to show
for it.

What review caught, and it was not visible from any green build

php_room.c first went into config.m4 inside the PHP_WEBSOCKET=yes block,
where its neighbours live. But the generated HttpServer.php_arginfo.h registers
all six room methods unconditionally, so a --disable-websocket build linked
cleanly — a shared object may carry undefined symbols — and then failed at
dlopen:

undefined symbol: zim_TrueAsync_HttpServer_enableRooms

The file is in the unconditional source list now. Measured after the fix, in a
separate build tree: --disable-websocket compiles with no warnings, nm -u
shows no undefined symbol of ours, the extension loads, and
class_exists('TrueAsync\Room') is correctly false while
TrueAsync\HttpServer is true.

No CI job builds --disable-websocket. That is S6.4's business, and this is the
second finding in two steps that only a build of that configuration could reach.

Also taken from the review: the ensure() comment claimed an exclusivity it did
not have; php_room_minit()'s stated MINIT dependency was on a class it does not
touch, while the real one — room_delivery_exception_ce, registered earlier by
ws_php_classes_register() — was unwritten; and three pieces of dead scaffolding
went (an empty #ifdef/#endif pair, a NULL check the accessor already makes, an
unused include).

Left deliberately

RoomDeliveryException's stub declares it extends WebSocketException, so
php_room.c still includes websocket/php_websocket.h for its class entry, and
every send()/trySend() failure path goes through it. Giving that exception a
base of its own is a PHP-visible contract change, not a file move; the file header
names it as the blocker where the next step will hit it.

Measured

  • phpize && ./configure && make -j12: no warnings of ours; nm -u clean.
  • tests/phpt: 381 passed, 0 failed, 1 warned (an XFAIL section on a passing
    test, pre-existing).
  • tests/valgrind-rooms.sh: 9 tests, 0 leaked.
  • Regenerating the stubs produces no content change (only the gen_stub.php
    version hash differs locally, so nothing is committed there).

http_server_class.c carried the whole PHP object layer over rooms — the
Room class with its handlers and transfer_obj, the helpers, and the six
HttpServer methods that address a room by name. That is 850 lines of a
subsystem the server only owns a hub of, in a file that is already the
largest in the tree.

The server object stays opaque: the moved code reaches it through two
pinpoint accessors, http_server_is_running() and
http_server_topic_hub_ensure(), which is the pattern src/http3/ already
uses. The ensure accessor is now the only place a hub is created, so the
worker-clone rule is stated once instead of at two of three call sites.

php_room.c compiles in every configuration, because the generated arginfo
registers those six HttpServer methods whether or not WebSocket is built:
a --disable-websocket build that omitted the file linked cleanly and then
failed at dlopen with an undefined symbol.
@github-actions

Copy link
Copy Markdown
Contributor

Coverage

Total lines: 82.32% → 82.19% (-0.12 pp)

File Baseline Current Δ Touched
src/core/http_connection.c 75.74% 75.55% -0.19 pp
src/http2/http2_session.c 88.68% 88.55% -0.13 pp
src/http3/http3_listener.c 77.33% 76.88% -0.45 pp
src/http3/http3_packet.c 90.43% 85.22% -5.22 pp
src/http_request.c 83.94% 80.83% -3.11 pp
src/http_server_class.c 75.87% 75.03% -0.84 pp
src/http_server_config.c 92.41% 92.47% +0.06 pp
src/room/php_room.c 0.00% 82.37% +82.37 pp
src/websocket/ws_session.c 90.59% 90.04% -0.55 pp

@EdmondDantes
EdmondDantes merged commit 43bfa1b into main Aug 16, 2026
8 checks passed
@EdmondDantes
EdmondDantes deleted the refactor/room-class-own-file branch August 16, 2026 09:05
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