With POE
calling POE::Kernel->stop()
results in immediately shutdown. How does one request a graceful shutdown, waiting for the yield, post, call FIFO to be empty before shutting down?
3 Answers
I don't think this is entirely clear..
the yield, post etc. will empty and ultimately your script will shut down. A 'graceful shut down' is a concept used when, say, you have a socket driven application and you want to make sure all active activities spawned via a socket finish before 'shutting down/closing the socket'.
So maybe the solution isn't something within POE::Kernel, but in your own code?

- 146
- 7
-
Yes, I usually have both listeners and timers, POE::Kernel->delay that calls itself, amp queue subscribers and so one. What would be the recommended approach to end up the event loop waiting for certain tasks while ignoring others? – lnrdo Feb 27 '15 at 20:34
If you create an inline state that removes aliases and any outstanding alarms your session should end gracefully. It will only remain if it's waiting for an event to return or being used by another session.

- 503
- 3
- 11
What would be the recommended approach to end up the event loop waiting for certain tasks while ignoring others?
First, wait for the tasks you want to finish.
After they've finished, you have a few options to end the event loop before the remaining tasks are through.
One is to call POE::Kernel->stop()
. That will stop the event loop, and the main POE::Kernel->run()
call will return. Usually there's nothing to do after that, but some programs do one-time finalization there.
Another is to kill the process. kill(TERM => $$)
. Use a signal that will cause your operating system to terminate the process. This is pretty harsh, though.
You can soften the blow by registering a SIGTERM handler with the POE::Kernel->sig()
call. That will let you run some code when SIGTERM arrives, but once again it puts the burden of shutting everything down upon your program.
Other harsh options include exit()
, which will at least allow objects to DESTROY
and END
blocks to run. If you'd rather they didn't, there's always POSIX::_exit()
instead. There's also die()
, of course.
If you'd rather not involve the operating system, the POE::Kernel->signal(TERM => $kernel)
call can be used to inject a fake SIGTERM. This is effectively what POE::Kernel does behind the scenes when a real SIGTERM arrives.
You can also use POE::Kernel->signal()
to send signals to individual sessions. One of the perks of being a simulated signal is that it's not necessarily scoped to the whole program.
In most- to least-recommended order:
- Shut everything down with proper intent.
- Using
POE::Kernel->signal()
to kill specific recalcitrant sessions. POE::Kernel->stop()
.exit()
and its ilk.

- 104
- 3