Skip to content

Quality pass follow-ups - #912

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

balat merged 6 commits into
masterfrom
follow-ups

Conversation

@balat

@balat balat commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Small follow-ups to the quality pass (#908). Each commit does one thing and builds.

  • Delete unused files: the two api.odocl files (leftovers of the ocamlbuild documentation setup) and the .gitignore pattern for them; src/ppx/ppx_eliom.ml and ppx_eliom.mli (a single comment each, in no dune stanza) and doc/ppx.indexdoc, which only referenced that module and is read by nothing (the PPX manual is doc/ppx-syntax.mld).
  • Client: factor the handling of the load mutex: Client_core.with_load_mutex replaces the four copies of the lock, unlock and recover pattern in call_ocaml_service, set_template_content, set_content_local and set_content. The only difference is on a cancelled wait for the mutex, where set_content_local and set_content no longer end a debug timer they have not started.
  • Client: use Lwt.async instead of Lwt.ignore_result at four sites. The change is not observable for the form handlers (already under Lwt.async) and the initial replaceState (always pending at module initialisation). For popstate, an immediate failure of revisit (the client-app checks, or a synchronous DOM failure in restore_history_dom) now goes to Lwt.async_exception_hook instead of escaping the popstate handler as an uncaught exception; there is no default action to keep. The link handler keeps Lwt.ignore_result, with a comment: when change_page_uri_a fails at once, the exception escapes Client_core.raw_a_handler, the default action is not prevented and the browser follows the link itself.
  • Logging (one commit each, with a CHANGES entry):
    • the Comet client logs its connection and request failures as warnings instead of Logs.app;
    • Mod_sessadmin logs the update of expiry dates at info level instead of Logs.app;
    • Eliom_react logs under its own source, eliom:react, instead of eliom:comet;

Testing

  • dune build @check at every commit; dune build @runtest and dune build @fmt at the head.
  • os_template built against this branch (at bd451bb, before set_content was converted with the same transformation as set_content_local), driven in a headless browser with the wasm and the JavaScript clients: no reload loop; client-side navigation keeps the JavaScript state, with back, forward and reload; RPC with session and persistent Eliom references; Comet notifications between two browser contexts; the sign-up form (an Eliom post_form, which goes through change_page_post_form) is sent by XHR and keeps the JavaScript state. No exception in the server log.

@balat
balat marked this pull request as ready for review September 27, 2026 13:24
The two api.odocl files are leftovers of the ocamlbuild documentation
setup; the odoc index is now doc/*.indexdoc, and .gitignore no longer
needs to ignore *.odocl. src/ppx/ppx_eliom.ml and ppx_eliom.mli hold a
single comment each and no dune stanza lists them; doc/ppx.indexdoc only
referenced that module and is read by nothing (doc/wodoc uses the server
and client indexes), the PPX manual being doc/ppx-syntax.mld.
The four functions that take Client_core.load_mutex while a page is being
put in place (call_ocaml_service, set_template_content, set_content_local
and set_content) each kept a locked flag and a recover function to
release the mutex on failure. Client_core.with_load_mutex now does it
once: it takes the mutex, hands an idempotent unlock function to its
argument and releases the mutex if the argument fails before calling it.

The only difference is when the wait for the mutex is cancelled:
set_content_local and set_content then no longer end a debug timer they
have not started, nor log the cancellation at debug level.
Lwt.ignore_result raises at once when its promise is already rejected,
and passes a later rejection to Lwt.async_exception_hook. Lwt.async sends
both to the hook. The change is not observable at the form handlers,
which already call change_page_get_form and change_page_post_form under
Lwt.async, nor at the initial replaceState, which waits for the end of
the loading phase, always pending when the module is initialised.

For popstate, there is no default action to keep, but the destination of
an immediate failure of revisit changes: it used to escape the popstate
handler as an uncaught exception, it now goes to Lwt.async_exception_hook
like a later failure. This only concerns the client-app checks of
revisit (session changed, page not generable client-side) and a
synchronous DOM failure in restore_history_dom.

The link handler keeps Lwt.ignore_result, with a comment: when
change_page_uri_a fails at once, the exception escapes
Client_core.raw_a_handler, the default action is not prevented and the
browser follows the link itself.
The conversion from Lwt_log turned the notices of the Comet client
(connection failure after the retries, failed command request) into
Logs.app messages, which are meant for the main output of an application
and are printed at every level except quiet. Log them as warnings.
The conversion from Lwt_log turned these notices into Logs.app messages,
printed at every level except quiet. They report routine maintenance
after a change of timeout, so log them at info level.
Eliom_react created a second source named eliom:comet, so its messages
could not be told apart from those of Comet. Give it its own source, as
each Eliom component has.
@balat
balat force-pushed the follow-ups branch 2 times, most recently from 8df543b to 00ae756 Compare September 27, 2026 13:45
@balat
balat merged commit fcca8b7 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