Codeigniter Daemons Using the System_Daemon Package

I am trying to create a daemon using the System_Daemon package from the CodeIgniter CLI. This is a new area for me and I am struggling.

Here's what I have: A CI controller that injects messages into the AWS SQS queue (thanks to [url = http://codeigniter.com/forums/member/196201/"coccodrillo [/url ]] for excellent instructions on how to integrate the AWS SDK into CI (See Integrating AWS SDK as Libraries in Codeigniter here ).

A CI controller that takes messages in the queue and writes them to the log file, and then deletes the message in the queue.

I would like to have a CI daemon that will listen to this queue, receive messages when they are there, and do something useful with the message, and then delete the message. So I started with an example in the documentation for System_Daemon and added the CI from the receiving program to the code. See code below

Is it the right thing to do? Can you point me to this "right"? I touched various knowledgeable forums and came to my senses ... Help me, please!

Mmiz

#!/usr/bin/php -q
<?php

// Make it possible to test in source directory
// This is for PEAR developers only
ini_set('include_path', ini_get('include_path').':..');

// Include Class
error_reporting(E_ALL);
require_once "System/Daemon.php";

// Bare minimum setup
System_Daemon::setOption("appName", "receiveaws");
System_Daemon::setOption("logLocation","/tmp/log/receiveaws.log");
System_Daemon::setOption("appPidLocation","/tmp/log/receiveaws/receiveaws.pid");
System_Daemon::log(System_Daemon::LOG_INFO, "Daemon not yet started so this will be written on-screen");

// Spawn Deamon!
System_Daemon::start();
System_Daemon::log(System_Daemon::LOG_INFO, "Daemon: '".
    System_Daemon::getOption("appName").
        "' spawned! This will be written to ".
            System_Daemon::getOption("logLocation"));

System_Daemon::log(System_Daemon::LOG_WARNING, 'My php code starting');
class Receiveaws extends CI_Controller {

    public function index(){
    if ($this->input->is_cli_request()) {
        //Load the aws library
        $this->load->library('awslib');
        $sqs = new AmazonSQS();

        //Get the queue to look at
        $res=$sqs->get_queue_url('example-queue');

        //Get the queue url
        $qurl=($res->body->GetQueueUrlResult->QueueUrl);
        System_Daemon::log(System_Daemon::LOG_INFO,$qurl);

        //Get a message from the queue
        $response = $sqs->receive_message($qurl);

        //If there was a message received, then do something
            if ($res->isOK()) {
            System_Daemon::log(System_Daemon::LOG_INFO,"Receive message successful");
                            //Now delete message from queue
            $res=$sqs->delete_message($qurl,$rcpt_hand);
            if ($res->isOK()) {
                System_Daemon::log(System_Daemon::LOG_INFO,"Delete message successful");
            }
        } else {
            //go back to check for messages
            //How do you do that?
        }
    } else {
        //Access from URL - so bail out?
        //how do you not bail out of the daemon from here?
    }
    }
}
System_Daemon::stop();
?>

      

+3


source to share


1 answer


A daemon is a process that runs "forever" in the background. Here, all you do is check for one new message in the queue, then exit. Basically you need to add a loop that takes in all the code that needs to be executed. You need to hibernate in a loop to prevent your daemon from using all available resources.

Anyway, php is not good for the daemon because some memory is never freed until the end of the script. If your script never ends (like a daemon), it eats up all available memory (as per php config) and then dies with an error. You will need to code your script very carefully to avoid memory leaks!

Also note that every time you request the sqs library it will send an HTTP request to the Amazon servers. It can be very costly to do it too often.



To compensate, I recommend that you use a cronjob that runs every minute to check out the new task. This way you avoid memory leaks (php process goes down between executions) and too much network usage (request takes one minute to complete).

As a final note, unless you plan on having a lot of tasks (which means your daemon does nothing 99% of the time), use a push queue instead. With a push queue, it's not your script that polls the queue anymore, but the queue notifies your script (i.e.: the script calls you with a standard HTTP request) every time some task needs to be done. This avoids unnecessary script usage.

I don't know if amazon provides push queues, but ironmq (another free queuing service) can provide them. More information: http://dev.iron.io/mq/reference/push_queues/

0


source







All Articles