-
Notifications
You must be signed in to change notification settings - Fork 134
Q & A
Versions: 1.1, 2.0
Your first step should be a walk through the applications in the Examples
directory. They are contrived and simple but will give you a place to start.
Creating Your Application Structure
You can start by creating a new directory for your application then copying the config.php
, error_handlers.php
and run.php
from any example app. While there's nothing in these files that is required by the library, this is the quickest way to get to a running prototype. Later you can integrate your own bootstrap, autoloader and error handling code if you're so inclined.
Next, create a new application class. This class will extend Core_Daemon
. If you're building a simple application, it could be entirely implemented in this main class. For more complex applications, this could merely become the trunk of your application, providing the infrastructure and access to the Core_Daemon
API.
Set protected/public variables
The Core_Daemon
base class is abstract: You will need to implement a few protected class properties and methods in your application class. The PHP Simple Daemon idiom is to set these in your class definition. Your daemon class does not need and should not implement a __construct
method.
-
protected $loop_interval = 2.5;
If you're building a server or using a blocking api in your event loop like socket_listen or LibEvent, you should omit this.
How often (in seconds) should your
execute()
method be called. For example, you could have it run every second, or every 5 seconds, or every 60 seconds, etc. If yourexecute()
method takes longer than$loop_interval
to return, an error will be logged. -
protected $idle_probability = 0.1;
If you're building a timer-based daemon using a
$loop_interval
, you should omit this.The probability (from 0.0 to 1.0) that garbage collection and other
ON_IDLE
tasks will run during this iteration of the event loop. -
protected $auto_restart_interval = 60 * 60 * 2;
How often (in seconds) should the application restart itself? This will only be activated if you run in daemon mode (
-d
at the commandline.) If you omit, the application will restart every 8 hours. -
protected $install_instructions = array();
This is an array of plain-text instructions that will be displayed when you pass
-i
at the command prompt. Gives administrators and other users the information they may need to run your daemon. Optional, but encouraged.protected $install_instructions = array ( 'Create /var/log/mydaemon directory with 0755 with write access for the application', 'Setup sendmail', 'Update config.ini with production database credentials' );
Create a setup_plugins()
Method
-
Use this method to setup any plugins. Optional, but most often this will at least be used to implement a Lock plugin. You can choose one of the Lock providers in the
Core/Lock
directory or write your own that extends theCore_Lock_Lock
class. They are used to prevent more than one instance of your application from running at any given time. -
Writing your own plugins is a fantastic way to create modular and reusable code and is very simple with the PHP Simple Daemon API. And don't forget pull requests: We will gladly accept pull requests for any non-proprietary plugins.
Create a setup_workers()
Method
- Optional, omit this method if you're not using the Worker API in your application.
- Use this method to setup any workers. See related documentation for more information.
Create a setup()
Method
- Required. Implement any run-once functionality.
- If your application uses database connections, listens to message queues, etc, this is where you should set that all up.
- Setup any event handlers using the
on()
method. - (Upgrade Note: In v2.0, this method is not called in background processes and using
$this->is_parent()
is no longer necessary or encouraged)
Create an execute()
Method
-
The actual work of your application begins here. In most of our production daemons, we use many classes and libraries, and the execute() method is just a few lines to bootstrap and run them.
-
You can implement all of your event loop functionality in the
execute()
method, or you could keep it very sparse and instead build an application that uses classes and components that are passed-in as callbacks to theCore_Daemon::ON_PREEXECUTE
andCore_Daemon::ON_POSTEXECUTE
events using theon()
method. You can callon()
multiple times, creating multiple callbacks for any given event. Theon()
method implements a simple first-in-first-called queue. -
NOTE: If you've developed applications like this before, you know that you need a
while(true)
event loop. This is why your application stays running. You stop it by interrupting the loop with abreak
statement or kill signal. Remember that PHP Simple Daemon implements the event loop for you when you callrun()
. Your execute() method is called inside this event loop. -
If you set
$loop_interval=0
or omit it altogether, your daemon will sleep for just a fraction of a second in betweenexecute()
calls to manage events and defer to the Kernel scheduler. You should use this technique if you're creating a server and using a blocking API like listening on a socket, waiting for user input, or using LibEvent. Creating an event loop without a$loop_interval
and without using a blocking API, you should expect your event loop to iterate very fast and for CPU usage to run at unacceptable levels.
You have several options to control/break the event loop from your application code.
-
Graceful Shutdown. When a
ctrl+c
orkill [pid]
signal is sent to your application, it will do a graceful shutdown: It will finish the current iteration of the while() loop, run its destructors, runteardown()
on all loaded plugins, release the lock, wait for any worker processes to exit, and exit cleanly. Any running processes using the Task API will continue running until their task is complete and then exit cleanly. You can also initiate this in your code by calling$this->shutdown(true)
. -
Exception. You can throw an exception from within the event loop that will break the loop and trigger a fatal error. In daemon-mode, your application will attempt to recover by restarting itself.
-
You can manipulate the loop frequency. You can change the
$loop_interval
while the daemon is running using theloop_interval()
method.