Repository navigation
Tighten remaining micro package behavior gaps in PHP #42
Description
Summary
This issue is about the remaining micro behavior gaps that are still meaningful in PHP.
The previous version leaned too much on direct nats.go helper/API shape parity. The more important PHP problem is that the package already advertises micro support, but several public fields and lifecycle paths still behave like a smaller subset than the API surface suggests.
PHP-applicable gaps
1. ServiceConfig::endpoint is still decorative
Service::create() skips installing the configured default endpoint, and the current EndpointConfig shape does not actually carry enough runtime behavior to make the field work as advertised.
2. stop() is still more abrupt than graceful
Service::stop() unsubscribes endpoint/control subscriptions directly instead of treating shutdown as a coordinated drain/graceful stop path.
3. Connection-event/error integration is still weak
The current service layer has much weaker visibility into NATS-side subscription/connection failures than the Go implementation does.
The exact Go callback shape is not the target, but the capability gap is real in PHP too.
4. reset() does not fully mirror the service lifecycle semantics the API suggests
PHP reset() clears counters but still does not fully align service timing/state semantics with the rest of the package's lifecycle expectations.
5. Request/response helpers still hide response-send failures too much
The current request API is simpler, but it also makes it easy to hide or lose response-send errors.
In PHP, that does not need to mean Go-style return signatures. Exceptions or another PHP-native error path are fine. The important part is that failures are not silently hidden.
Expected direction
A PHP-native target here is:
- make decorative
microconfig fields real or remove them - make service stop graceful rather than immediate-unsubscribe only
- improve service visibility into NATS-side failures
- tighten reset/lifecycle semantics
- expose response-send failures through a real PHP error path
Out of scope for this issue
This issue does not require exact Go helper names such as ContextHandler, nor exact Go return-value signatures.
The target is honest and usable micro behavior in PHP.
Acceptance criteria
- public
microconfig fields correspond to real runtime behavior - service stop is graceful rather than abrupt
- reset/lifecycle semantics are internally consistent
- NATS-side failures are observable from the service layer
- response-send failures are not silently hidden
Detailed breakdown
This epic should be executed as a replacement implementation from main, not by continuing to accrete architecture onto PR #70. Keep the desired behavior and regression coverage, but do not treat PR #70's implementation as the target design.
Child issues
- Micro Runtime Cleanup 1: Slim the public Request API #71 Micro Runtime Cleanup 1: Slim the public Request API
- Micro Runtime Cleanup 2: Remove or implement decorative ServiceConfig::endpoint #72 Micro Runtime Cleanup 2: Remove or implement decorative ServiceConfig::endpoint
- Micro Runtime Cleanup 3: Add service lastError() and centralize runtime error recording #73 Micro Runtime Cleanup 3: Add service lastError() and centralize runtime error recording
- Micro Runtime Cleanup 4: Align reset() with stats-window lifecycle semantics #74 Micro Runtime Cleanup 4: Align reset() with stats-window lifecycle semantics
- Micro Runtime Cleanup 5: Keep single-reply enforcement inside the micro layer #75 Micro Runtime Cleanup 5: Keep single-reply enforcement inside the micro layer
- Micro Runtime Cleanup 6: Harden control-subject callbacks and throwing stats handlers #76 Micro Runtime Cleanup 6: Harden control-subject callbacks and throwing stats handlers
- Micro Runtime Cleanup 7: Refactor Service::stop() into explicit graceful-drain phases #77 Micro Runtime Cleanup 7: Refactor Service::stop() into explicit graceful-drain phases
- Micro Runtime Cleanup 8: Refresh micro docs and examples after the API cleanup #78 Micro Runtime Cleanup 8: Refresh micro docs and examples after the API cleanup
Suggested execution lanes
- Lane A: Micro Runtime Cleanup 1: Slim the public Request API #71 -> Micro Runtime Cleanup 5: Keep single-reply enforcement inside the micro layer #75 -> Micro Runtime Cleanup 8: Refresh micro docs and examples after the API cleanup #78
- Lane B: Micro Runtime Cleanup 2: Remove or implement decorative ServiceConfig::endpoint #72
- Lane C: Micro Runtime Cleanup 3: Add service lastError() and centralize runtime error recording #73 -> Micro Runtime Cleanup 4: Align reset() with stats-window lifecycle semantics #74 and Micro Runtime Cleanup 6: Harden control-subject callbacks and throwing stats handlers #76 and Micro Runtime Cleanup 7: Refactor Service::stop() into explicit graceful-drain phases #77
- Lane D: Micro Runtime Cleanup 8: Refresh micro docs and examples after the API cleanup #78 after the earlier lanes settle
Coordination notes
- Micro Runtime Cleanup 6: Harden control-subject callbacks and throwing stats handlers #76 and Micro Runtime Cleanup 7: Refactor Service::stop() into explicit graceful-drain phases #77 both rewrite
src/Micro/Service.php; serialize implementation or give one owner final merge responsibility. - Micro Runtime Cleanup 1: Slim the public Request API #71 is intentionally API-breaking. That is acceptable here if the package is still pre-adoption; the point is to remove the raw-message escape hatch before it becomes sticky.
- Micro Runtime Cleanup 5: Keep single-reply enforcement inside the micro layer #75 is where we keep the duplicate-reply rule, but it should not reintroduce micro-specific hooks into
src/Message.php.
Activity
[-]Close remaining micro package parity gaps vs nats.go[/-][+]Tighten remaining micro package behavior gaps in PHP[/+]matkomat-agent-2 commentedon Mar 26, 2026
I narrowed this issue to the
microbehavior gaps that are still meaningful in PHP. The updated scope keeps the runtime and API-honesty problems, but drops exact Go helper names and return-signature parity as the target.