Skip to content

Port Mojolicious 9.49 and stabilize Mojo::IOLoop - #1129

Merged
fglock merged 122 commits into
masterfrom
fix/issue-1115-mojolicious
Aug 29, 2026
Merged

Port Mojolicious 9.49 and stabilize Mojo::IOLoop#1129
fglock merged 122 commits into
masterfrom
fix/issue-1115-mojolicious

Conversation

@fglock

@fglock fglock commented Aug 26, 2026

Copy link
Copy Markdown
Owner

Summary

Adds PerlOnJava support for Mojolicious 9.49 and completes the runtime/compiler compatibility work tracked by #1115. No CPAN module sources are patched.

The final changes include:

  • durable JVM ownership for process-pipe handles returned through lists and stored in nested argument aggregates;
  • bounded 4 MiB process-pipe buffering with backpressure and complete post-exit draining;
  • deterministic socket EOF and descriptor recycling;
  • interrupted blocking select returning -1 with EINTR;
  • completed package-alias and UNIVERSAL behavior required by core UAT;
  • Perl-correct compound-assignment lvalue order and vivification on JVM and interpreter backends;
  • verifier-safe implicit defer returns, safe PerlIO->import, and writable repeated $#array lvalues;
  • Windows-correct raw sysopen defaults, lexical use open handling, and exact emulated mode reporting;
  • a loopback Mojolicious task-board example covering HTML, JSON, timers, and chunked output.

Final validation

  • Exact current head: 4d289549f (post-UAT runtime fix 9b2377b6f; current master merge 9daa1be73).
  • Immutable full gate on exact current head: nice -n 10 timeout 1200 make — PASS, all five unit shards, Joni, packaging, and shadow JAR in 3m44s. Log: /tmp/issue1115_uat_regressions_4d289549f_make.log.
  • Previous hosted CI run 33224975225 on c0499c80e — PASS: Ubuntu 32m43s; Windows 30m10s. Hosted CI for 4d289549f is pending; review readiness will be reconfirmed when it is green.
  • Core UAT through perl_test_runner.pl: 4/4 files and 261/261 assertions PASS:
    • perl5_t/t/mro/package_aliases.t
    • perl5_t/t/mro/package_aliases_utf8.t
    • perl5_t/t/mro/isa_aliases.t
    • perl5_t/t/op/universal.t
    • Log: /tmp/issue1115_9daa1be73_core_uat.log.
  • Post-UAT focused regressions: system Perl, JVM, and interpreter all PASS, 5/5 assertions for implicit defer return cleanup, PerlIO->import injection safety, and repeated $#array lvalue identity. Logs: /tmp/issue1115_9b2377b6f_system_perl_regressions.log and /tmp/issue1115_9b2377b6f_{defer,perlio,repeat}_{jvm,int}.log.
  • Reported five-file UAT slice on 9b2377b6f: defer.t 25/33, caller.t 96/115, splice.t 33/34, perlio.t 38/48, and repeat.t 49/50. This restores every behavior present in the current corpus. The 11-test caller.t and 2-test splice.t differences from the supplied baseline are tests absent from the current imported corpus, not failing assertions. Log: /tmp/issue1115_uat_regressions_9b2377b6f_runner.log.
  • Process-pipe post-exit drain: system Perl, JVM, and interpreter PASS; exact 65,536-byte stderr, empty stdout, child exit 0.
  • Regex debug-region regression: JVM and interpreter PASS, 4/4.
  • Returned lexical handle coverage: system Perl, JVM, and interpreter PASS, 4/4.
  • Interrupted blocking select: system Perl, JVM, and interpreter PASS, 2/2.
  • Nested process handle in IO::Select aggregate: system Perl, JVM, and interpreter PASS, 3/3.
  • Socket scope/EOF guard: JVM and interpreter PASS, 35/35.
  • Compound-assignment evaluation order: system Perl, JVM, and interpreter PASS, 5/5.
  • Windows integration matrix: system Perl 17/17; JVM/interpreter PerlIO layers 8/8, sysopen mode 4/4, threaded in-place editing 3/3, process drain 3/3, and socket lifetime 35/35.

Framework acceptance

  • Mojolicious 9.49: 109/109 files, 4,194 tests, PASS in 955 seconds. Log: /tmp/issue1115_9daa1be73_mojolicious.log.
  • Catalyst::Runtime 5.90132: 199/199 supported files, 3,774/3,774 assertions, 19 skips, 9 TODOs, PASS in 2,260 elapsed seconds. Only real-fork-only t/live_fork.t is excluded. Log: /tmp/issue1115_9daa1be73_catalyst_199_correct.log.
  • DBIx::Class 0.082844: 325/325 files, 43,020 tests, PASS in 1,759 wallclock seconds, including t/52leaks.t, t/storage/error.t, and t/storage/txn_scope_guard.t. Log: /tmp/issue1115_9daa1be73_dbix_class.log.
  • Mojolicious task board: JVM and interpreter both PASS readiness, rendered /, /health, /api/tasks, and all three /activity chunks. Logs: /tmp/issue1115_9daa1be73_task_board_jvm_* and /tmp/issue1115_9daa1be73_task_board_interpreter_*.

Real fork/prefork servers remain outside PerlOnJava's process model and are tracked separately in #1144.

Fixes #1115.

fglock and others added 30 commits August 25, 2026 14:26
Add a focused regression for the IO::Poll semantics used by
Mojolicious reactors when a listener is watched for both directions.

Issue: #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
IO::Poll now limits POLLOUT registration to selectable channels that
support OP_WRITE, while retaining OP_CONNECT for pending client sockets.
This prevents Mojolicious reactors from crashing when they watch a
listener for both readable and writable events.

Issue: #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Add a focused regression for issue #1115 covering real-file open,
syswrite, selected output, and read behavior when a filename is an
overloaded blessed scalar reference.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Treat only unblessed scalar references as scalar-backed open targets.
Blessed references remain filename values so overload can produce paths,
preventing Mojolicious log and asset writes from corrupting path scalars.

Fixes #1115.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Lock down Perl 5.38 semantics that module_true does not replace the
value returned by do FILE, including application-like object and false
results.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Apply the module_true true-value substitution only while loading files
through require. Preserve the actual value from do FILE so application
loaders retain blessed objects and false results retain Perl semantics.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Add a focused Compress::Raw::Zlib regression for the split gzip header
used by Mojolicious response parsing in issue #1115.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Add a focused regression for the Mojo::Promise pattern where a weak
attribute points to a destructor-enabled singleton retained by a state
lexical while another temporary alias is released.

Refs #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Lock down Perl-compatible missing-delimiter and EOF diagnostics for the
incomplete bareword block used by Mojolicious loader exception tests.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Reproduce the Mojo::Promise ownership shape where a weak-accessor clone is
returned, discarded by the caller, and retained through a callback closure
stored on the source object. Perl keeps the clone and its weak loop attribute
alive until the callback graph is released.

Refs #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Use callable syntax for imported Compress::Raw::Zlib constants so the
Mojolicious gzip regression compiles under both PerlOnJava backends.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Teach the Compress::Raw::Zlib Java backend to consume split RFC 1952
headers, inflate the raw payload, validate the trailer, and report stream
completion so Mojolicious can replace compressed response headers.

Issue: #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Detect EOF after parsing an unresolved bareword call's block argument and
route it through the established Perl-compatible missing-right-curly
formatter instead of emitting an empty generic syntax context.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Reproduce the stale input-handle context exposed by Mojolicious template
exceptions after earlier lexical file reads.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Require malformed source loaded from a real temporary file to report its last
content line rather than the synthetic line after a trailing newline.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Attribute missing-delimiter diagnostics in newline-terminated loaded files to
the final physical source line while retaining eval and -e next-line behavior.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Use a temporary input file because the Gradle unit harness supplies a logical
relative __FILE__ name that is not readable from its process directory.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Strengthen the closure-retained Promise regression with deterministic
destruction checks for both an explicitly released source and an entirely
discarded chain at the statement boundary.

Refs #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Return an empty list from Scalar::Util::weaken in list context, matching its
void XS semantics. This keeps Mojo::Base weak accessors from injecting an
undef argument while cloning Promise objects.

Traverse persistent state slots from installed code roots so weak-reference
sweeps retain singleton objects such as Mojo::IOLoop.

Refs #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Verify that subroutine-exit diagnostic cleanup does not close or unregister a
lexical filehandle returned to its caller.

Generated with [OpenAI Codex](https://openai.com/codex)

Co-Authored-By: OpenAI Codex <codex@openai.com>
Model rejected Promise propagation through a next-tick callback queue and
require discarded-chain destruction while the warning handler is localized.

Refs #1115

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Clear the JVM's last-read handle when an unaliased lexical IO owner leaves via
the subroutine return cleanup path. Preserve holder counts, descriptors, and
returned or copied handle aliases.

Generated with [OpenAI Codex](https://openai.com/codex)

Co-Authored-By: OpenAI Codex <codex@openai.com>
Strengthen the warning cleanup regression with Mojo's wait callback shape so
the interpreter-specific destruction timing failure is isolated.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Model Mojo::Promise's paired resolve and reject callback arrays so the
interpreter must release the unselected branch before warning scope exit.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Require Config to advertise either real fork or the standard non-real fork
classification so upstream suites can avoid process-only tests.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Require File::Temp to identify a nonexistent parent directory before retrying
temporary-file creation.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Advertise the non-real fork classification while keeping d_fork disabled so
portable upstream suites skip process-only semantics.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Validate the template parent before retrying exclusive creation and preserve
the standard diagnostic distinction between missing and non-directory paths.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Model Mojo::Promise settlement, finally chaining, and wait cleanup closely
enough to expose the interpreter's delayed unhandled-rejection warning.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Require make_path to initialize its error collector and remove_tree to honor
keep_root while deleting descendants.

Refs #1115

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
fglock and others added 18 commits August 28, 2026 09:36
Register UNIVERSAL import and unimport. Empty import succeeds while requested
exports report the standard no-exports diagnostic; add focused regression.

Generated with Codex (https://openai.com/codex/)
Co-Authored-By: Codex <223556219+chatgpt-codex-connector[bot]@users.noreply.github.com>
Add bounded process-pipe draining and preserve anonymous IO holders across JVM aggregate return cleanup.

System Perl regression passes; full make reached test class compilation but did not emit a final result in the sandbox runner.

Generated with Codex (https://openai.com/codex/)\n\nCo-Authored-By: Codex <223556219+chatgpt-codex-connector[bot]@users.noreply.github.com>
Preserve the WIP process-pipe checkpoint alongside the completed UNIVERSAL compatibility fixes.

Generated with Codex (https://openai.com/codex/)\n\nCo-Authored-By: Codex <223556219+chatgpt-codex-connector[bot]@users.noreply.github.com>
Record the pushed WIP checkpoint and remaining validation blockers.

Generated with Codex (https://openai.com/codex/)\n\nCo-Authored-By: Codex <223556219+chatgpt-codex-connector[bot]@users.noreply.github.com>
Materialize anonymous I/O aliases before JVM scope cleanup, retain process
handles at creation, and preserve descriptor ownership through final return
copies. Strengthen the post-exit drain regression and update the operational
handoff with focused evidence and the remaining gates.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record the green process, regex, returned-handle, and socket parity matrix,
along with the infrastructure-only Gradle shard EOF blocking the full gate.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Cover the direct UNIVERSAL::DOES diagnostic for unblessed references and
explicit UNIVERSAL parents inherited by otherwise undeclared class names.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Preserve the DOES method name in unblessed-reference diagnostics and allow
plain class invocants to inherit an explicit UNIVERSAL parent hierarchy.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record both successful full gates, the focused UNIVERSAL regression matrix,
and the 261/261 core UAT result before framework acceptance.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record the authoritative 109-file, 4,194-test Mojolicious result and classify
the discarded socket-restricted sandbox run.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record the complete 199-file supported Catalyst::Runtime result and classify
the superseded contention-sensitive timeout.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Verify that a signal interrupting a blocking select returns -1 and exposes
EINTR, matching system Perl and preventing empty readiness results.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Consume the JVM wakeup used for Perl signal delivery, dispatch the pending
signal, and return the select syscall's interrupted result instead of an
empty successful readiness set.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Reproduce TAP::Parser::Multiplexer's IO::Select storage shape and require a
process handle nested in a durable array to survive the creator's scope exit.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Defer aggregate cleanup while an active pristine argument frame still points
at the referent, then reconsider cleanup as call frames unwind. This prevents
IO::Select's nested process handle from losing its descriptor in _fileno.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Require string and numeric compound assignments to resolve negative-index
lvalues before a mutating right-hand side, matching system Perl and the JVM.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Compile and vivify compound-assignment lvalues before evaluating a mutating
right-hand side on both backends. This restores system-Perl evaluation order
and lets Mojolicious templates render under the interpreter.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record the green DBIx::Class suite, both task-board backends, final focused
regressions, elapsed times, commit, and exact evidence-log paths.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
@fglock fglock changed the title WIP: Port Mojolicious 9.49 and stabilize Mojo::IOLoop Port Mojolicious 9.49 and stabilize Mojo::IOLoop Aug 28, 2026
@fglock
fglock marked this pull request as ready for review August 28, 2026 21:14
fglock and others added 8 commits August 28, 2026 23:14
Mark implementation, acceptance, publication, and PR evidence complete so
review and merge are the only remaining repository workflow steps.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Resolve PR #1129 against current master while retaining the completed
Mojolicious, process-pipe ownership, and backend parity fixes. Use master's
complete File::Path 2.18 implementation and retain both changelog sections.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record the current-master merge gate, focused regressions, core UAT,
framework acceptance, and task-board smoke evidence for PR #1129.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Keep sysopen raw by default on Windows while honoring lexical use open
hints, and retain exact Perl mode bits across the non-POSIX stat fallback.
Include complete TAP output in unit-test failures for hosted CI diagnosis.

Update the issue 1115 handoff with the Windows CI classification and local
gate evidence.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record the green Ubuntu and Windows hosted run for the final runtime head and
mark the operational handoff complete for review.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Keep value-producing defer bodies stack-balanced, give PerlIO its safe
no-op import surface, and preserve $#array lvalues through list repetition
on both execution backends.

Add system-Perl-compatible focused regressions for each behavior.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Document the exact-commit gate, focused backend matrix, restored core UAT
counts, and the imported-corpus explanation for caller and splice totals.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
Record the green exact-head Ubuntu and Windows CI jobs and leave only normal
review and merge as the resume point.

Generated with [Codex](https://openai.com/codex)

Co-Authored-By: Codex <codex@openai.com>
@fglock
fglock merged commit e115730 into master Aug 29, 2026
2 checks passed
@fglock
fglock deleted the fix/issue-1115-mojolicious branch August 29, 2026 13: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.

Port Mojolicious 9.49 and stabilize Mojo::IOLoop

1 participant