Ejemplo n.º 1
9
function client_thread($self)
{
    $context = new ZMQContext();
    $client = new ZMQSocket($context, ZMQ::SOCKET_REQ);
    $endpoint = sprintf("ipc://%s-localfe.ipc", $self);
    $client->connect($endpoint);
    $monitor = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
    $endpoint = sprintf("ipc://%s-monitor.ipc", $self);
    $monitor->connect($endpoint);
    $readable = $writeable = array();
    while (true) {
        sleep(mt_rand(0, 4));
        $burst = mt_rand(1, 14);
        while ($burst--) {
            //  Send request with random hex ID
            $task_id = sprintf("%04X", mt_rand(0, 10000));
            $client->send($task_id);
            //  Wait max ten seconds for a reply, then complain
            $poll = new ZMQPoll();
            $poll->add($client, ZMQ::POLL_IN);
            $events = $poll->poll($readable, $writeable, 10 * 1000000);
            if ($events > 0) {
                foreach ($readable as $socket) {
                    $zmsg = new Zmsg($socket);
                    $zmsg->recv();
                    //  Worker is supposed to answer us with our task id
                    assert($zmsg->body() == $task_id);
                }
            } else {
                $monitor->send(sprintf("E: CLIENT EXIT - lost task %s", $task_id));
                exit;
            }
        }
    }
}
Ejemplo n.º 2
0
function client_task()
{
    $context = new ZMQContext();
    $client = new ZMQSocket($context, ZMQ::SOCKET_DEALER);
    //  Generate printable identity for the client
    $identity = sprintf("%04X", rand(0, 0x10000));
    $client->setSockOpt(ZMQ::SOCKOPT_IDENTITY, $identity);
    $client->connect("tcp://localhost:5570");
    $read = $write = array();
    $poll = new ZMQPoll();
    $poll->add($client, ZMQ::POLL_IN);
    $request_nbr = 0;
    while (true) {
        //  Tick once per second, pulling in arriving messages
        for ($centitick = 0; $centitick < 100; $centitick++) {
            $events = $poll->poll($read, $write, 1000);
            $zmsg = new Zmsg($client);
            if ($events) {
                $zmsg->recv();
                printf("%s: %s%s", $identity, $zmsg->body(), PHP_EOL);
            }
        }
        $zmsg = new Zmsg($client);
        $zmsg->body_fmt("request #%d", ++$request_nbr)->send();
    }
}
Ejemplo n.º 3
0
 /**
  * Run a self test of the Zmsg class. 
  *
  * @return boolean
  * @todo See if assert returns
  */
 public static function test()
 {
     $result = true;
     $context = new ZMQContext();
     $output = new ZMQSocket($context, ZMQ::SOCKET_XREQ);
     $output->bind("inproc://zmsg_selftest");
     $input = new ZMQSocket($context, ZMQ::SOCKET_XREP);
     $input->connect("inproc://zmsg_selftest");
     //  Test send and receive of single-part message
     $zmsgo = new Zmsg($output);
     $zmsgo->body_set("Hello");
     $result &= assert($zmsgo->body() == "Hello");
     $zmsgo->send();
     $zmsgi = new Zmsg($input);
     $zmsgi->recv();
     $result &= assert($zmsgi->parts() == 2);
     $result &= assert($zmsgi->body() == "Hello");
     echo $zmsgi;
     //  Test send and receive of multi-part message
     $zmsgo = new Zmsg($output);
     $zmsgo->body_set("Hello");
     $zmsgo->wrap("address1", "");
     $zmsgo->wrap("address2");
     $result &= assert($zmsgo->parts() == 4);
     echo $zmsgo;
     $zmsgo->send();
     $zmsgi = new Zmsg($input);
     $zmsgi->recv();
     $result &= assert($zmsgi->parts() == 5);
     $zmsgi->unwrap();
     $result &= assert($zmsgi->unwrap() == "address2");
     $zmsgi->body_fmt("%s%s", 'W', "orld");
     $result &= assert($zmsgi->body() == "World");
     //  Pull off address 1, check that empty part was dropped
     $zmsgi->unwrap();
     $result &= assert($zmsgi->parts() == 1);
     //  Check that message body was correctly modified
     $part = $zmsgi->pop();
     $result &= assert($part == "World");
     $result &= assert($zmsgi->parts() == 0);
     // Test load and save
     $zmsg = new Zmsg();
     $zmsg->body_set("Hello");
     $zmsg->wrap("address1", "");
     $zmsg->wrap("address2");
     $result &= assert($zmsg->parts() == 4);
     $fh = fopen(sys_get_temp_dir() . "/zmsgtest.zmsg", 'w');
     $zmsg->save($fh);
     fclose($fh);
     $fh = fopen(sys_get_temp_dir() . "/zmsgtest.zmsg", 'r');
     $zmsg2 = new Zmsg();
     $zmsg2->load($fh);
     assert($zmsg2->last() == $zmsg->last());
     fclose($fh);
     $result &= assert($zmsg2->parts() == 4);
     echo $result ? "OK" : "FAIL", PHP_EOL;
     return $result;
 }
Ejemplo n.º 4
0
     //  Get message
     //  - 3-part envelope + content -> request
     //  - 1-part "HEARTBEAT" -> heartbeat
     $zmsg = new Zmsg($worker);
     $zmsg->recv();
     if ($zmsg->parts() == 3) {
         //  Simulate various problems, after a few cycles
         $cycles++;
         if ($cycles > 3 && rand(0, 5) == 0) {
             printf("I: (%s) simulating a crash%s", $identity, PHP_EOL);
             break;
         } elseif ($cycles > 3 && rand(0, 5) == 0) {
             printf("I: (%s) simulating CPU overload%s", $identity, PHP_EOL);
             sleep(5);
         }
         printf("I: (%s) normal reply - %s%s", $identity, $zmsg->body(), PHP_EOL);
         $zmsg->send();
         $liveness = HEARTBEAT_LIVENESS;
         sleep(1);
         // Do some heavy work
     } elseif ($zmsg->parts() == 1 && $zmsg->body() == 'HEARTBEAT') {
         $liveness = HEARTBEAT_LIVENESS;
     } else {
         printf("E: (%s) invalid message%s%s", $identity, PHP_EOL, $zmsg->__toString());
     }
     $interval = INTERVAL_INIT;
 } elseif (--$liveness == 0) {
     printf("W: (%s) heartbeat failure, can't reach queue%s", $identity, PHP_EOL);
     printf("W: (%s) reconnecting in %d msec...%s", $identity, $interval, PHP_EOL);
     usleep($interval * 1000);
     if ($interval < INTERVAL_MAX) {
Ejemplo n.º 5
0
function main()
{
    for ($client_nbr = 0; $client_nbr < NBR_CLIENTS; $client_nbr++) {
        $pid = pcntl_fork();
        if ($pid == 0) {
            client_thread();
            return;
        }
    }
    for ($worker_nbr = 0; $worker_nbr < NBR_WORKERS; $worker_nbr++) {
        $pid = pcntl_fork();
        if ($pid == 0) {
            worker_thread();
            return;
        }
    }
    $context = new ZMQContext();
    $frontend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER);
    $backend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER);
    $frontend->bind("ipc://frontend.ipc");
    $backend->bind("ipc://backend.ipc");
    //  Logic of LRU loop
    //  - Poll backend always, frontend only if 1+ worker ready
    //  - If worker replies, queue worker as ready and forward reply
    //    to client if necessary
    //  - If client requests, pop next worker and send request to it
    //  Queue of available workers
    $available_workers = 0;
    $worker_queue = array();
    $writeable = $readable = array();
    while ($client_nbr > 0) {
        $poll = new ZMQPoll();
        //  Poll front-end only if we have available workers
        if ($available_workers > 0) {
            $poll->add($frontend, ZMQ::POLL_IN);
        }
        //  Always poll for worker activity on backend
        $poll->add($backend, ZMQ::POLL_IN);
        $events = $poll->poll($readable, $writeable);
        if ($events > 0) {
            foreach ($readable as $socket) {
                //  Handle worker activity on backend
                if ($socket === $backend) {
                    //  Queue worker address for LRU routing
                    $zmsg = new Zmsg($socket);
                    $zmsg->recv();
                    assert($available_workers < NBR_WORKERS);
                    $available_workers++;
                    array_push($worker_queue, $zmsg->unwrap());
                    if ($zmsg->body() != "READY") {
                        $zmsg->set_socket($frontend)->send();
                        // exit after all messages relayed
                        $client_nbr--;
                    }
                } else {
                    if ($socket === $frontend) {
                        $zmsg = new Zmsg($socket);
                        $zmsg->recv();
                        $zmsg->wrap(array_shift($worker_queue), "");
                        $zmsg->set_socket($backend)->send();
                        $available_workers--;
                    }
                }
            }
        }
    }
    // Clean up our worker processes
    foreach ($worker_queue as $worker) {
        $zmsg = new Zmsg($backend);
        $zmsg->body_set('END')->wrap($worker, "")->send();
    }
    sleep(1);
}
Ejemplo n.º 6
0
 *
 * @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
 */
include 'zmsg.php';
$context = new ZMQContext();
$worker = new ZMQSocket($context, ZMQ::SOCKET_REQ);
//  Set random identity to make tracing easier
$identity = sprintf("%04X-%04X", rand(0, 0x10000), rand(0, 0x10000));
$worker->setSockOpt(ZMQ::SOCKOPT_IDENTITY, $identity);
$worker->connect("tcp://localhost:5556");
//  Tell queue we're ready for work
printf("I: (%s) worker ready%s", $identity, PHP_EOL);
$worker->send("READY");
$cycles = 0;
while (true) {
    $zmsg = new Zmsg($worker);
    $zmsg->recv();
    $cycles++;
    //  Simulate various problems, after a few cycles
    if ($cycles > 3 && rand(0, 3) == 0) {
        printf("I: (%s) simulating a crash%s", $identity, PHP_EOL);
        break;
    } elseif ($cycles > 3 && rand(0, 3) == 0) {
        printf("I: (%s) simulating CPU overload%s", $identity, PHP_EOL);
        sleep(5);
    }
    printf("I: (%s) normal reply - %s%s", $identity, $zmsg->body(), PHP_EOL);
    sleep(1);
    // Do some heavy work
    $zmsg->send();
}