NAME

IPC::Manager::Service::State - Internal implementation of ipcm_service and ipcm_worker

DESCRIPTION

This module is the implementation backing the ipcm_service and ipcm_worker exports provided by IPC::Manager. It also acts as its own -M boot module when a service is started via exec: in that case Perl loads this module with -MIPC::Manager::Service::State, which reads the serialised service parameters from @ARGV and arranges for the service to start running once the Perl runtime exits BEGIN.

Callers should interact with this module only through the exports of IPC::Manager; direct use is not part of the public API.

EXPORTS

These functions are re-exported through IPC::Manager; see that module for the primary documentation.

$handle = ipcm_service($name, \&on_all_callback)
$handle = ipcm_service($name, \%params, \&on_all_callback)
$handle = ipcm_service($name, %params)

Fork a new service process. The return value depends on calling context and where the call is made:

  • When called outside a service, returns an IPC::Manager::Service::Handle connected to a newly spawned IPC bus. ipcm_service blocks until the service signals that it is ready.

  • When called from inside a running service (from a service callback), the new service shares the existing IPC bus. Returns an IPC::Manager::Service::Peer that the calling service can use to send requests to the nested service. ipcm_service blocks until the nested service is ready.

  • When called in void context from inside a service, the nested service is started but ipcm_service returns immediately without waiting for the service to be ready. The caller is responsible for waiting before sending messages; see "ipcm_service" in IPC::Manager for details.

$pid = ipcm_worker($name, \&callback)

Fork a worker process from inside a running service. The worker runs \&callback in place of a normal service loop and is registered with the parent service so that it is reaped when the service exits. Dies if called outside a service.

Returns the PID of the newly forked worker to the parent; in the worker process the callback is invoked and the function never returns.

EXEC AND STAY-IN-BEGIN MODE

When ipcm_service is invoked with an exec parameter, the freshly-forked child does not re-enter the in-process service loop directly; instead it execs a new perl with -MIPC::Manager::Service::State and a serialised parameter blob on @ARGV. Perl loads this module at boot, which means import runs at BEGIN time of the -e snippet that follows on the command line.

By default import stashes a closure on the module so that the service starts only once the Perl runtime exits BEGIN and runs the -e snippet, which calls _post_exec_run. This is the right shape for normal services: the interpreter is fully past BEGIN by the time the service event loop spins up, so anything the loop does happens in a "running program" context.

The exec => { stay_in_begin => 1 } variant flips that: import calls _ipcm_service synchronously, while the -M hook is still on the stack and Perl has not yet finished parsing the -e entry script. This mode exists for services that need to keep the interpreter in "parsing the entry script" state while the service loop runs -- typically so they can, on some incoming request, hand the entry script's source off to a source filter like goto::file and let the test (or other target) compile in main with a shallow stack.

For that hand-off to be usable, _ipcm_service must eventually return all the way back through import and out of BEGIN, instead of calling exit once run() finishes. Services that want this behaviour must consume IPC::Manager::Role::Service and override run_returns_to_caller to return true. The combination -- exec.stay_in_begin = 1 on the launching side, run_returns_to_caller true on the consuming class -- is the supported pattern for "preload services that hand off to a forked, freshly-goto::file'd test grandchild". The Test2-Harness preload service is the canonical example consumer.

For every other service the default (run_returns_to_caller returning 0) keeps the existing "always exit after run() returns" behaviour.

SOURCE

The source code repository for IPC::Manager can be found at https://github.com/exodist/IPC-Manager.

MAINTAINERS

Chad Granum <exodist@cpan.org>

AUTHORS

Chad Granum <exodist@cpan.org>

COPYRIGHT

Copyright Chad Granum <exodist7@gmail.com>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See https://dev.perl.org/licenses/