Skip to content

Session group and client logging fixes - #914

Merged
balat merged 6 commits into
masterfrom
follow-up-fixes
Sep 27, 2026
Merged

balat merged 6 commits into
masterfrom
follow-up-fixes

Conversation

@balat

@balat balat commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Bug fixes found after the quality pass (#908). Each commit does one thing, builds, and has a CHANGES entry.

  • Close the service and data sessions of a group separately. Each site has one group of groups, a dlist that limits the number of groups of browser sessions. Mod_sessiongroups.Serv and Data both add an entry to it for a group, but its finaliser did not know which one had added the entry and always closed the data sessions of the group and removed its group data. As a result:

    • closing the last service session of a group closed the data sessions of the group and removed its group data;
    • State.discard_services ~scope:(Session_group _)closed the data sessions of the group and left its service sessions open, soState.discard` with that scope did not close them;
    • evicting the service entry of a group, when a site has too many groups, did the same.

    The entries now carry the kind of their sessions (Common.group_of_groups_entry) and the finaliser closes the sessions of that kind. New unit tests (test/unit/test_sessiongroups.ml) check, on each level (tab sessions of a browser session, browser sessions of a group, groups of a site) and for both kinds of sessions, that closing a state, emptying or evicting a group, or lowering a limit closes exactly the states it holds, and never those of the other kind. Without the fix, the service cases on the group and site levels fail.

  • State: list each session group once in get_session_group_list. A group with both kinds of sessions has two entries, so its name was returned twice.

  • Document the levels of State.set_max_*_states_for_group_or_subnet. The scope gives the level of the states that are limited, in the state that contains them: tab sessions in the browser session, browser sessions in the group or subnet, and groups in the group of groups of the site (a limit shared by service and data states). The documentation spoke of the sessions of the current group for every scope. The CHANGES entry of an earlier fix of these functions (Fix latent bugs found during the pre-release review #907), which said that the limit reached the wrong group, is corrected: it only did nothing when the group had no state of the other kind.

  • Lib (client): honour ~encode in Url.string_of_url_path. The client version ignored it and printed a warning; it now encodes each segment, like the server version.

  • Lib (client): log the exceptions of Lwt.async with Logs. The client Lwt.async_exception_hook used console.error, bypassing Logs. It now uses Logs.err, followed by the JavaScript stack of the error attached to the exception, when there is one.

Testing

  • dune build @check at every commit; dune build @runtest (32 tests) and dune build @fmt at the head.
  • os_template built against this branch (before the test and documentation changes), driven in a headless browser with the wasm and the JavaScript clients: no reload loop, client-side navigation and history, RPC with session and persistent Eliom references, Comet between two browser contexts, the sign-up form. Every browser session there goes through the group of groups (subnet groups). No exception in the server log.

The client version ignored ~encode and printed a warning, while the
server version percent-encodes each path segment. Encode each segment
with Url.encode ~plus:false, as Eliom_uri does for the paths it builds.
The client Lwt.async_exception_hook wrote the exception with
console.error, bypassing Logs, its reporter and its levels. Log it with
Logs.err on the eliom source instead. The console showed the exception
object, whose only useful part is the JavaScript error it may carry: the
message now ends with the stack of that error, when there is one.
@balat
balat force-pushed the follow-up-fixes branch 2 times, most recently from e83c8c5 to 125dd88 Compare September 27, 2026 14:03
@balat
balat marked this pull request as ready for review September 27, 2026 14:06
Each site has one group of groups, a dlist that limits the number of
groups of browser sessions. Mod_sessiongroups.Serv and Data both add an
entry to it for a group, and remove it when the group becomes empty or
is closed. Its finaliser did not know which module had added the entry
and always closed the data sessions of the group and removed its group
data. So:
- closing the last service session of a group closed the data sessions
  of the group and removed its group data;
- closing a group of service sessions closed its data sessions and left
  its service sessions open;
- evicting the service entry of a group, when the site has too many
  groups, did the same.

The entries now carry the kind of their sessions
(Common.group_of_groups_entry), and the finaliser closes the sessions of
that kind, removing the group data only for data sessions. When a group
is removed because it has become empty, closing its sessions does
nothing, as before.

New unit tests check, on each level (tab sessions of a browser session,
browser sessions of a group, groups of a site) and for both kinds of
sessions, that closing a state, emptying or evicting a group, or lowering
a limit closes exactly the states it holds, and never those of the other
kind. Without this change, the service cases on the group and site levels
fail: the three cases above, and lowering the maximum number of groups of
the site.
A group of browser sessions with both service and data sessions has two
entries in the group of groups of the site, one for each kind, so
get_session_group_list returned its name twice. Remove the duplicates.
The entry said that the limit reached the wrong group. With a
`Session_group scope, these functions change the maximum number of
groups of the site, held by the group of groups, which holds the entries
of both kinds: looking the group up in the other table reached the same
limit, and only did nothing when the group had no state of the other
kind.
The documentation spoke of the sessions of the current group for every
scope. The scope gives the level of the states that are limited, in the
state that contains them: tab sessions in the browser session, browser
sessions in the group or subnet, and groups in the group of groups of the
site, whose limit is shared by service and data states.
@balat
balat merged commit 121990f into master Sep 27, 2026
5 checks passed
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