Harden console, server, and HTTP runtime lifecycles#450
Conversation
Resolve each configured cache repository and underlying store once per operation, then use the exact instance for lock or repository semantics. Make command mutex probes non-destructive, normalize force-release success to the declared boolean contract, and replace PHPStan workarounds with truthful lock-provider narrowing. The focused mutex regression proves existence checks do not acquire ownership and preserves repository-backed behavior for stores without native locks.
Retain the exact isolation mutex acquired by a command and release it through an exhaustive terminal path. Preserve the earliest command, lifecycle-event, or cleanup failure while still attempting independent teardown, and include trait setup inside the signal cleanup boundary. Guard optional observational events when no listeners exist. Extend command regressions across setup, handler, exit, event, and mutex failures so ownership and throwable precedence remain deterministic.
Reapply the parent command's complete prompt configuration after every nested command invocation, including exceptional exits. Delete the partial output-only restoration helper so process-global prompt callbacks and fallbacks cannot remain bound to the child command. Regression coverage verifies output, validation, fallback, and cancellation configuration are restored without masking the nested command result or failure.
Port the current CommandInput value API and expose merged command data through InteractsWithIO. Restore truthful Symfony argument and option types, normalize integer argument lookups at the string boundary, and accept iterable completion sources and indeterminate progress input. Update console view metadata and regressions for argument precedence, nested data access, generator completion choices, and generator-backed progress without eager counting.
Write iterable output one item at a time instead of materializing it into an intermediate array. Preserve caller-supplied newline semantics, interpret Symfony verbosity bitmasks correctly, and update visible-output state only after a successful write. Regression coverage exercises generators, suppressed verbosity, explicit and embedded newlines, empty values, and write failures. This removes duplicate memory growth while keeping output state truthful.
Move callback results, callback failures, process handles, exit codes, and overlap status to exact-event coroutine slots for each invocation. Initialize state at run start, retain live processes through terminal callbacks, forget owned resources on every exit, and preserve the earliest failure while attempting output, after callbacks, and mutex cleanup. Require exact output writes and checked filesystem reads, port current callback dependency injection, and accept all valid callable filters. Deterministic regressions cover sequential and concurrent runs, terminal-phase failures, process lifetime, output boundaries, callback injection, and cleanup precedence.
Evaluate between and unless-between constraints when an event is checked rather than freezing Carbon values when the worker-singleton schedule is built. Represent last-day-of-month with cron's dynamic L syntax and reject zero or negative sub-minute divisors before modulo evaluation. Regression coverage advances the framework clock across interval boundaries, exercises overnight ranges and timezones, proves dynamic month-end behavior, and validates the truthful positive repeat range.
Track scheduler failure and overlap decisions in invocation-local variables instead of rendering from mutable Event snapshots. Treat observed non-zero foreground and background exits as failures, keep same-Event background registration reference-counted, and preserve established lifecycle-event then report ordering. The scheduler regressions cover thrown work, non-zero exits, overlap skips, concurrent runs of one Event object, cleanup, context propagation, event ordering, and earliest-failure behavior without relying on scheduling luck.
Stop schedule:test from mutating the stored Event's background flag. Hypervel owns background submission in ScheduleRunCommand, so direct Event execution is already synchronous and must retain the original object to preserve framework-created callback bindings. The integration regression proves success callbacks execute against the configured Event, its background setting remains unchanged, and the command still describes the normal background behavior accurately.
Add current environment-based schedule filtering while preserving events without an environment restriction. For scheduled unique jobs, apply connection and queue metadata before locking, register the exact transient job in the existing Bus payload sidecar, and release its lock only when failure occurs before payload creation consumes ownership. Unit and integration coverage verifies environment matching plus both unique-job failure boundaries: safe pre-payload release and conservative post-payload retention when transport ownership is ambiguous.
Port schedule:list environment filtering and expose the timezone in which each raw cron expression is evaluated. Keep the expression unchanged because a fixed-offset rewrite cannot preserve ranges, month boundaries, special syntax, or daylight-saving transitions, while continuing to render next-due timestamps in the requested display timezone. Use the same resolved expression timezone for due-date calculation and display, including a directly constructed Schedule with no timezone. Integration coverage verifies JSON and CLI output, filtering, sorting, explicit timezones, and application-timezone fallback.
Make MigrationCreator own custom-stub reads, placeholder population, collision-free path selection, atomic publication, and post-create hook ordering. Keep transient path selection coroutine-local on the worker-shared creator, use the framework clock consistently, and convert native glob failure into a descriptive exception. Regression coverage proves hooks see the final file, read and publication failures expose no partial migration, prefixes remain collision-free across concurrent paths, and protected prefix generation respects the framework clock.
Route Console, Cache, and Queue migration generators through MigrationCreator's single final-publication boundary instead of creating a generic file and overwriting it afterward. Check migration glob results through the shared owner and remove call-site configuration defaults already guaranteed by merged package configuration. Focused generator coverage proves custom stubs are published once, modes and placeholders are correct, collisions advance safely, native scan failures surface, and success is not reported after incomplete generation.
Replace live deferred-webhook timers and timing sleeps with the manager's existing injectable Timer boundary. Assert each owned timer ID is cleared exactly once across cancel-all and per-key cancellation paths. This removes a race from the full parallel gate while testing the real ownership contract directly, without adding production hooks or changing Reverb runtime behavior.
Declare every runtime symbol owner required by the standalone Console subtree, including native extensions, Symfony components, Guzzle, Carbon, Termwind, PSR HTTP client, and Hypervel Log. Keep constraints aligned with the monorepo's existing package versions. Add a split-metadata regression that enumerates the complete non-PHP runtime dependency boundary and verifies every declared constraint is present and non-empty.
Document the CommandInput API for reading merged arguments and options, including argument precedence for duplicate keys and nested data access. Explain command trait setup hooks and their lifecycle so application commands can prepare resources without bypassing framework cleanup. Keep the guidance task-focused and aligned with the current Console implementation and Laravel-shaped command APIs.
Document environment-filtered schedule listings, callback dependency injection, and expression timezone output. Clarify that cron expressions remain in their real evaluation timezone while next-due timestamps use the requested display timezone. The guidance reflects Hypervel's Swoole scheduling ownership without exposing internal coroutine machinery or implying that display conversion changes task execution.
Add the Console package's Laravel provenance and record the intentional schedule-list presentation difference. Explain that Hypervel preserves raw cron expressions because fixed-offset conversion is not truthful across ranges, month boundaries, special syntax, and daylight-saving transitions. Keep the package README concise and reserve user-facing task guidance for the Boost documentation.
Record the final Console findings, accepted fixes, rejected speculative mechanisms, cross-package ownership, regression strategy, validation, performance assessment, and signed-off review result. Preserve the Database migration and Reverb timer findings for their later full package audits. Mark Console complete, close its carried revalidation entries, route the active audit to Server with core-06, and retain exact checklist parity with all 72 source packages.
Treat false returns from Swoole server configuration, listener registration, event registration, and startup as package-level server failures instead of allowing boot to continue in a partially initialized state. Normalize invalid server-type failures onto the package exception hierarchy and add focused regressions for every native boundary, including failures while registering listeners and callbacks.
Validate the configured master PID and report reload success only when the selected Swoole signal is actually delivered. Preserve task-worker reload support while removing the signal-zero preflight race and exposing a narrow signal seam for deterministic tests. Default task workers to zero so a standard installation does not imply a process pool it has not configured, document standalone server reloads, and cover invalid PIDs, failed signals, worker selection, and configuration defaults.
Inject the configuration repository into the process-title listener and read the application name when each worker lifecycle event fires. Replacement workers created after a reload now use current configuration rather than a value captured during initial provider registration. Retain the existing platform and configuration guards, and exercise server, worker, task-worker, and user-process titles alongside disabled and unsupported environments.
Initialize server and listener builders with Swoole-valid process, socket, and HTTP defaults so omitted optional configuration produces a usable HTTP server instead of invalid zero-valued native constants. Remove the unused top-level server type from ServerConfig and add regressions for default construction as well as explicit overrides.
Remove the concrete constructor signature from ServerInterface because construction dependencies are an implementation detail, not behavior every custom server must share. Accept any ServerInterface in ServerFactory so applications can replace the built-in server without extending its concrete class. Add focused coverage proving an arbitrary interface implementation can be installed and returned by the factory.
Depend on the Foundation application contract directly instead of a concrete application singleton plus a generic container. Resolve collaborators consistently through that application and return Symfony's named success status. Keep host and port overrides valid for servers that rely on the HTTP default type, preserve rejection for non-HTTP configurations, and update the command regressions around the tightened configuration contract.
Declare the native extensions and Hypervel packages used directly by the Server component, remove the reverse http-server dependency, and record the package's Hyperf provenance. Add metadata coverage that validates the direct dependency boundary and prevents the server/http-server cycle from returning.
Restore APP_RUNNING_IN_CONSOLE after each test instead of leaking process-global state into later tests and construct the command through the application contract it now requires. Strengthen the serve-command coverage for current environment ownership and the default HTTP server shape without changing the production Testbench machinery.
Record the Server audit's native startup boundaries, reload semantics, process-title freshness, default configuration, public API cleanup, package metadata, and test ownership decisions. Capture the validated regressions and residual PID-reuse tradeoff, mark the package complete, and route the next audit work to HTTP Server response and streaming lifecycle revalidation.
Reconstruct Swoole request URIs from the split request_uri and query_string fields before applying trailing-slash normalization. Preserve already-combined inputs without duplicating their query and retain the root path for slash-only request targets. Add focused coverage for split and combined queries, empty query strings, ordinary trailing slashes, the root URI, and all-slash paths so native request conversion remains faithful across Swoole input shapes.
Make iterable response cleanup exhaustive without allowing generator finalization failures to replace the original producer or transport failure. Apply the same earliest-failure rule to direct sendContent consumption and clear retained producers on every terminal path. Expand regression coverage for callback failures, writer failures, throwing generator cleanup, direct content sending, idempotent completion, and reference release so lazy stream ownership is deterministic.
Return lazy iterable streamed responses from local, scoped, and pooled filesystem adapters instead of emitting through a response-owned socket. Keep resources leased until generator completion, stop reads when the transport rejects a chunk, and preserve the first read, write, close, or lease-release failure. Reflect the truthful Symfony response types in filesystem contracts and facade metadata, preserve range and download behavior, and expand coverage for middleware-safe lazy execution, disconnect cleanup, native read failures, pooled lease ownership, and failure precedence.
Make ResponseBridge the sole owner of native status, headers, cookies, streamed chunks, binary files, and terminal response completion. Preserve raw and partitioned cookies, prepared range and HEAD semantics, trusted X-Sendfile delegation, temporary and delete-after-send ownership, and earliest-failure cleanup. Keep ordinary HTTP/1 files on zero-copy sendfile while streaming HTTP/2 and deletion-owned files through bounded checked chunks. Propagate protocol and request evidence through HTTP Server, WebSocket, Reverb, and gRPC consumers, and make request handling, response emission, kernel termination, and RequestTerminated observation exhaustive under failures and cancellation. Delete the obsolete ResponseContext, writable connection contract and adapter, direct Response streaming surface, and StreamOutput path. Bind mutable responses transiently and update focused lifecycle, transport, context, binary, and binding regressions to the single-owner design.
Remove the response-context and fake writable setup from in-process HTTP tests now that transport emission belongs exclusively to HTTP Server. Delete the obsolete Swoole socket and writable connection fakes rather than retaining a second testing-only transport model. Restore current Laravel binary-file streamedContent behavior and suppress streamed producers for HEAD requests while preserving cached content semantics. Add regressions for binary content, repeated reads, callback and iterable HEAD responses, streamed JSON, and ordinary non-stream responses.
Add one Testbench-backed Swoole server to the existing engine harness and exercise the complete RequestBridge to kernel and middleware to ResponseBridge path over HTTP/1.1 and HTTP/2. Cover native query, form, JSON, and multipart conversion; request-context isolation; cookies; callback, iterable, and filesystem streaming; ranges; HEAD; temporary and delete-after-send files; disconnect cleanup; and lifecycle liveness. Use per-test random tokens and a token-keyed consume-on-read lifecycle fixture so serial and parallel workers can share the server without cross-test state. Wire the integration group into the engine workflow, server launcher, and contributor test guidance.
Declare the native Swoole extension and coroutine package used directly by HTTP Server, and remove the former Engine and Server dependency edges after deleting the writable transport stack. Keep the split manifest aligned with the package actual imports. Add concise Hyperf provenance and a metadata regression that pins every required dependency and verifies the two removed edges stay absent.
Scan the installed, version-matched Swoole HTTP Response and Server declarations so native cookie, listener, and response APIs are analyzed against the runtime package rather than stale broad assumptions. Remove the imprecise local bool-or-port annotation from listener creation and let the checked native false branch narrow the authoritative return type without runtime code or suppression machinery.
Remove guidance for the deleted ResponseContext placeholder and explain that responses remain in the request control flow until the HTTP server emits them after middleware unwinds. Clarify the testing boundary: requests are coroutine-local through RequestContext, while mutable response objects resolve transiently instead of being published as worker-global container instances or coroutine-context placeholders.
Record the final implementation, regression coverage, cross-package revalidation, validation, Laravel-facing result, performance impact, and overengineering assessment for the unified HTTP response-emission work. Check off HTTP Server, close the carried Filesystem, Foundation, Testing, and gRPC revalidations, retain pending consumer audits, and route the next package cycle to WebSocket Server with its exact context-copy and prepared-response dependencies.
Integrate the latest 0.4 changes, including the framework-wide immutable-date default and its package, documentation, and regression updates. Resolve Console scheduling conflicts by combining CarbonImmutable with the audited execution-time interval evaluation, native last-day cron expression, timezone-correct schedule display, and truthful failure and skip reporting. Update the remaining Console input assertion to the new immutable default. Revalidate the affected Console and HTTP Server surfaces and pass the complete composer fix gate after the merge.
|
Important Review skippedToo many files! This PR contains 128 files, which is 28 over the limit of 100. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (134)
You can disable this status message by setting the ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR hardens the lifecycle of the Console scheduler, HTTP server, and Swoole response transport across 134 files. The central theme is single ownership: every resource from command output files and overlap mutexes to file streams and binary response chunks now has one explicit owner from creation through cleanup, with independent cleanup paths and earliest-failure preservation throughout.
Confidence Score: 4/5Safe to merge after resolving the double event dispatch in ScheduleRunCommand; everything else is a net improvement in lifecycle ownership and cleanup. In ScheduleRunCommand::runEvent, dispatching ScheduledTaskFinished unconditionally before the exit-code check and then throwing a RuntimeException causes both ScheduledTaskFinished and ScheduledTaskFailed to fire for the same task run when the command exits with a non-zero code. Listener code that treats these events as mutually exclusive for a given run will behave incorrectly. src/console/src/Commands/ScheduleRunCommand.php — the event dispatch ordering around the exit-code check. Important Files Changed
Reviews (2): Last reviewed commit: "fix(runtime): harden schedule config and..." | Re-trigger Greptile |
Read the required application timezone through the typed configuration repository at both schedule-list boundaries so invalid merged configuration fails with the framework's descriptive contract. Move binary delete-after-send unlinking behind the existing style of protected native boundary. This preserves the checked deletion postcondition and earliest failure while allowing the failure path to be exercised deterministically under root-run CI containers. Replace permission-based failure injection with a test-only bridge override, retain proof that response emission completes first, and assert both the deletion exception and surviving file without catching PHPUnit's own assertion failure.
|
@greptile-apps Followed up on the complete review and the root-container CI failure. Changes landed:
Two findings were intentionally left unchanged:
Validation is green through |
|
All three original findings are resolved or confirmed intentional — the PR is in good shape: Acknowledged as fixed:
My original P1 was incorrect:
Intentional and documented:
Shall I remember the following rule to avoid the same mistake in future reviews: "Hypervel's |
Summary
This PR completes the Console, Server, and HTTP Server runtime lifecycle work units.
The common theme is ownership. Commands, scheduled runs, native server operations, response streams, files, and test fixtures now have one clear owner from creation through cleanup. Failures are checked where they occur, independent cleanup still runs, and the earliest failure remains the one callers observe.
It also brings the affected Laravel-facing Console and testing APIs up to date while keeping Hypervel's Swoole-specific behavior explicit.
Console and scheduling
lastDayOfMonth()at execution time instead of freezing dates on the worker-lifetime schedule.Server lifecycle
ServerInterfaceimplementation.HTTP transport
ResponseBridgethe sole owner of Swoole response emission.TestResponsebehavior without invoking stream producers for HEAD requests.Integration coverage
The HTTP Server now has a real Testbench-backed integration fixture in the existing engine test group. It exercises the complete native path over HTTP/1.1 and HTTP/2:
The fixture uses runner-owned worker identity and consume-on-read state, so parallel workers do not share lifecycle observations.
Compatibility and performance
Laravel's supported Console, response, streaming, Filesystem, and testing APIs remain intact or gain current parity. The only removed public surface is Hypervel's
ResponseContextplaceholder, which had no Laravel equivalent and never represented the response returned by the application. The Server cleanup affects Hyperf-derived infrastructure rather than a Laravel-facing API.Ordinary request and response paths gain no lock, registry, retry, polling loop, or extra container lookup. Optional event guards remove work when unused, iterable output no longer buffers the complete input, and HTTP/2 file memory is bounded per request. HTTP/1.1 preserves zero-copy delivery wherever native deletion ownership permits it.
Validation
composer fix