Using callbacks and custom events - gregtampa/PHP-Daemon GitHub Wiki

Using Callbacks and Custom Events

Version 2.0

Callbacks: What and Why

Callbacks and custom events were introduced in v2.0 to give built-in API components and the applications built with them access to daemon state transitions with some level of decoupling.

Events

All built-in events are aliased as class constants in the Core_Daemon class.

  • Core_Daemon::ON_ERROR

    Dispatched when the log() method is called with an $is_error=true argument. The message passed to log() is passed through to the event. See the logging documentation for more details.

  • Core_Daemon::ON_SIGNAL

    Dispatched every time your daemon application receives a signal. This can be used in your application to create custom signal handlers. The signal (int) is passed as an argument.

  • Core_Daemon::ON_INIT

    The static getInstance constructor starts daemon applications in INIT state. Callbacks you register to the state will be called immediately after plugins and workers are setup, before your daemon setup() method is called.

  • Core_Daemon::ON_PREEXECUTE and Core_Daemon::ON_POSTEXECUTE

    These callbacks are dispatched each time the daemon's main event loop iterates, right before and after your execute() method is called, respectively. The PRE event is dispatched after system-level tasks are taken care of, and before your execute() method is called. The POST right after.

    You can use it to create new system-level services that run transparently to your application, split-up work that would normally be incongruously lumped together in the execute() method into their own objects and methods that register themselves and run in beautifully decoupled bliss.

  • Core_Daemon::ON_FORK

    Dispatched in your background process immediately after it is forked from your daemon, before any Task or Worker code is run.

  • Core_Daemon::ON_PIDCHANGE

    After processes are forked the system will dispatch an event to inform listeners that the PID has changed. This is important to you if you're caching the pid in a variable the way we do in lock plugins and the Core_Daemon class itself.

  • Core_Daemon::ON_IDLE

    When using a timer-based event loop (by setting the $loop_interval property), this event will be dispatched if there is idle time at the end of the loop.

    In applications that do not use loop_interval, the Core_Daemon::idle_probability value is used to dispatch the ON_IDLE event periodically. The probability value can be modified in your application: Increase it to run ON_IDLE events more often. You can set it to 0 to turn off automatic dispatch of ON_IDLE events, but only do this if you intend to dispatch them manually. The library uses ON_IDLE to run periodic housekeeping tasks.

    The library will perform necessary housekeeping tasks in this down time, and this event is dispatched to give your application a chance to do the same. Any remaining time after this event is completely dispatched will be spent in a sleep().

  • Core_Daemon::ON_SHUTDOWN

    The ON_SHUTDOWN event is dispatched as the daemon begins its shutdown process -- before any plugin or worker teardown() methods are called.

Callbacks

You can add callbacks to these events very easily using the on() method. The first argument is the event, the second is a closure or callback. The third argument is an optional throttle length. You can supply a throttle value, in seconds, if you want to limit the rate at which your callback is called even if your given event is dispatched frequently.

For example, your application may dispatch an ON_IDLE event every iteration if your execute() method runs quicker than your $loop_interval. And maybe you have a method that will delete old records from a database table that you'd like to run when the application has a few idle seconds. But you don't want that delete query run every second just because you happen to have idle time. In this example, you could throttle it at 60 seconds, or even longer,

The on() method returns a callback tuple that can be used later to turn off the callback using the off() method.

Custom Events

Creating custom events is very simple.

  1. Add a class-constant using the same style as built-in event constants using numeric values > 100 to prevent conflict with any future built-in events.
  2. In your code at the event point, call the dispatch() method. The first argument informs the event that is being dispatched, the second is an optional array of arguments to be passed with the event.

The first argument can either be an array with a single element -- the event constant, or it can be the 2-element array that was returned when you registered a callback using on(). In other words, you can pass that return tuple to dispatch() to call a function you've previously registered. While this is admittedly slightly obtuse and without wide use cases, it does give you the ability to dispatch an event handler by ID only without concern to the implementation of the underlying function.

Dispatching a Fork event in Core_Daemon:

$this->dispatch(array(self::ON_FORK));