Getting started
Download
Download the latest source from Sourceforge: http://sourceforge.net/projects/fat-controller/
Install
tar -zxvf fatcontroller-0.0.5.tar.gz cd fatcontroller-0.0.5/ make sudo make install
Configuration
The next step is to configure The Fat Controller so it knows what you want it to do. If you open the configuration file (/etc/fatcontroller) then you will see a list of options which are described in detail in the manual.
Probably the best way to see how the configuration works is to look at a few examples.
Running
The shell script /etc/init.d/fatcontrollerd provides a simple way to start, stop and configure The Fat Controller. More information on this can be found in the manual.
Note that you must be logged in as root or precede these commands with sudo
Starting
/etc/init.d/fatcontrollerd start
Stopping
/etc/init.d/fatcontrollerd stop
Is it running?
/etc/init.d/fatcontrollerd status
Examples
All the following examples run PHP scripts but The Fat Controller can just as easily run Python, Shell, Perl, Ruby - anything.
Running a PHP script as a daemon
Let's say you have a PHP script that you want to run as a background process; it runs and does its job and then waits 1 minute before starting again. The script is located at /var/www/mysite/backgroundJob.php and takes one argument to denote how many items it should process. Here's what the configuration file /etc/fatcontroller should look like:
# --------------------------- # FatController user settings # --------------------------- APPLICATION_NAME="fatcontroller" WORKING_DIRECTORY="/var/www/mysite/" COMMAND="/usr/bin/php" ARGUMENTS="-f backgroundJob.php -- --items-to-process=10" # Make sure the log file exists and has correct permissions LOG_FILE="/var/log/${APPLICATION_NAME}.log" SLEEP=60 SLEEP_ON_ERROR=300 THREADS=1 # Thread models: DEPENDENT, INDEPENDENT, FIXED THREAD_MODEL=DEPENDENT # Zero means disables warning PROC_RUN_TIME_WARN=3600 # Zero means disables max execution duration PROC_RUN_TIME_MAX=0 PROC_TERM_TIMEOUT=30 # Only used in FIXED thread model (-1 means will wait indefinitely) FIXED_INTERVAL_WAIT=-1 # If using this and running php and your script doesn't take any arguments itself, make sure the ARGUMENTS fields ends with -- APPEND_THREAD_ID=0 # --------------- # System settings # --------------- # Make sure the pid file exists and has correct permissions PID_FILE="/tmp/${APPLICATION_NAME}.pid" APPLICATION="/usr/local/bin/fatcontroller"
Note that in the ARGUMENTS option, the arguments to PHP are separated from the arguments to the script by two hyphens. This is specific to PHP and is documented here http://www.php.net/manual/en/features.commandline.usage.php.
Output from the PHP script will be logged to /var/log/fatcontroller.log but error messages won't be. That is because they are sent to STDERR, a different output stream. The next verson of The Fat Controller will support STDERR as well as STDOUT.
Processing a queue
In this example, consider a video sharing website. Users can upload media in a variety of formats which all need to a format that the site's Flash player can play. When a user uploads a video, the file gets stored on disk and an entry is created in the database for this file. The original solution was to use CRON to run a PHP script every minute that took the entry in the database for the oldest, unprocessed video, and covert the video into the required format. As the site got more popular, at peak times users were uploading videos at a greater rate than one per minute and so the conversion started to lag behind and users had to wait longer and longer for their videos to be converted.
The solution was to use The Fat Controller to run the script which was modified slightly to return an exit code of 64 (in PHP: exit(64);) if there were still unprocessed items in the database. This would tell The Fat Controller to immediately start another instance of the script and also one more, so two files could be processed. In this way, the system can react to increased demand and process more files in parallel, up to a maximum of four concurrent instances. If any of the instances determined that there were no more items left in the queue to be processed then it returns and exit status of 0 telling The Fat Controller not to start another instance of script for another minute.
# --------------------------- # FatController user settings # --------------------------- APPLICATION_NAME="fatcontroller" WORKING_DIRECTORY="/var/www/mysite/" COMMAND="/usr/bin/php" ARGUMENTS="-f processMedia.php" # Make sure the log file exists and has correct permissions LOG_FILE="/var/log/${APPLICATION_NAME}.log" SLEEP=60 SLEEP_ON_ERROR=300 THREADS=4 # Thread models: DEPENDENT, INDEPENDENT, FIXED THREAD_MODEL=DEPENDENT # Zero means disables warning PROC_RUN_TIME_WARN=3600 # Zero means disables max execution duration PROC_RUN_TIME_MAX=0 PROC_TERM_TIMEOUT=30 # Only used in FIXED thread model (-1 means will wait indefinitely) FIXED_INTERVAL_WAIT=-1 # If using this and running php and your script doesn't take any arguments itself, make sure the ARGUMENTS fields ends with -- APPEND_THREAD_ID=0 # --------------- # System settings # --------------- # Make sure the pid file exists and has correct permissions PID_FILE="/tmp/${APPLICATION_NAME}.pid" APPLICATION="/usr/local/bin/fatcontroller"
CRON every 20 seconds
Let's imagine you have a chat room and you want to automatically logout idle users. You have a script which will log out idle users but you need to run it every 20 seconds. Unfortunately there aren't many options; the best you can achieve with CRON is once every minute and you don't fancy the rather daunting task of writing your own daemon. Luckily, this is exactly what the fixed interval thread model is used for in The Fat Controller. As opposed to other thread models which wait an interval after an instance of a script has finished before starting another, the fixed interval thread model starts scripts at regular intervals, regardless of how long the scripts take to run. This can of course introduce quite a lot of other problems as discussed here in the manual. In the example below, if a script takes longer than 20 seconds then The Fat Controller will wait until it has finshed and them immediately start another instance of the script.
# --------------------------- # FatController user settings # --------------------------- APPLICATION_NAME="fatcontroller" WORKING_DIRECTORY="/var/www/mysite/" COMMAND="/usr/bin/php" ARGUMENTS="-f chatroomLogout.php" # Make sure the log file exists and has correct permissions LOG_FILE="/var/log/${APPLICATION_NAME}.log" SLEEP=20 SLEEP_ON_ERROR=300 THREADS=1 # Thread models: DEPENDENT, INDEPENDENT, FIXED THREAD_MODEL=DEPENDENT # Zero means disables warning PROC_RUN_TIME_WARN=3600 # Zero means disables max execution duration PROC_RUN_TIME_MAX=0 PROC_TERM_TIMEOUT=30 # Only used in FIXED thread model (-1 means will wait indefinitely) FIXED_INTERVAL_WAIT=-1 # If using this and running php and your script doesn't take any arguments itself, make sure the ARGUMENTS fields ends with -- APPEND_THREAD_ID=0 # --------------- # System settings # --------------- # Make sure the pid file exists and has correct permissions PID_FILE="/tmp/${APPLICATION_NAME}.pid" APPLICATION="/usr/local/bin/fatcontroller"