Exemple #1
0
 public function send($data)
 {
     $msg = new Zmsg($this->socket);
     $msg->push($data);
     $msg->wrap(sprintf("%.0f", microtime(1) * 1000));
     $msg->send(true);
 }
Exemple #2
0
function worker_thread($self)
{
    $context = new ZMQContext();
    $worker = $context->getSocket(ZMQ::SOCKET_REQ);
    $endpoint = sprintf("ipc://%s-localbe.ipc", $self);
    $worker->connect($endpoint);
    //  Tell broker we're ready for work
    $worker->send("READY");
    while (true) {
        $zmsg = new Zmsg($worker);
        $zmsg->recv();
        sleep(mt_rand(0, 2));
        $zmsg->send();
    }
}
Exemple #3
0
function broker_task()
{
    //  Prepare our context and sockets
    $context = new ZMQContext();
    $frontend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER);
    $backend = new ZMQSocket($context, ZMQ::SOCKET_ROUTER);
    $frontend->bind("tcp://*:5555");
    $backend->bind("tcp://*:5556");
    //  Initialize poll set
    $poll = new ZMQPoll();
    $poll->add($frontend, ZMQ::POLL_IN);
    $poll->add($backend, ZMQ::POLL_IN);
    $read = $write = array();
    while (true) {
        $events = $poll->poll($read, $write);
        foreach ($read as $socket) {
            $zmsg = new Zmsg($socket);
            $zmsg->recv();
            if ($socket === $frontend) {
                $zmsg->push("W");
                $zmsg->set_socket($backend)->send();
            } elseif ($socket === $backend) {
                $zmsg->pop();
                $zmsg->push("C");
                $zmsg->set_socket($frontend)->send();
            }
        }
    }
}
Exemple #4
0
 protected function onPoll($events, $read, $write)
 {
     parent::onPoll($events, $read, $write);
     if ($events > 0) {
         foreach ($read as $socket) {
             //handle publisher
             if ($socket === $this->frontedSocket) {
                 $zmsg = new Zmsg($this->frontedSocket);
                 $zmsg->recv();
                 if ($this->verbose) {
                     echo "I: received message from publisher size: ";
                     echo strlen($zmsg->__toString()), PHP_EOL;
                 }
                 $zmsg->unwrap();
                 //time
                 if ($this->queueLimit > sizeof($this->queue)) {
                     array_unshift($this->queue, $zmsg->pop());
                 }
             }
         }
     }
 }
Exemple #5
0
 /**
  * Send request to broker and get reply by hook or crook
  * Takes ownership of request message and destroys it when sent.
  * Returns the reply message or NULL if there was no reply.
  *
  * @param  string $service
  * @param  Zmsg   $request
  * @param  string $client
  * @return Zmsg
  */
 public function send($service, Zmsg $request)
 {
     //  Prefix request with protocol frames
     //  Frame 1: "MDPCxy" (six bytes, MDP/Client
     //  Frame 2: Service name (printable string)
     $request->push($service);
     $request->push(MDPC_CLIENT);
     if ($this->verbose) {
         printf("I: send request to '%s' service:", $service);
         echo $request->__toString();
     }
     $retries_left = $this->retries;
     $read = $write = array();
     while ($retries_left) {
         $request->set_socket($this->client)->send();
         //  Poll socket for a reply, with timeout
         $poll = new ZMQPoll();
         $poll->add($this->client, ZMQ::POLL_IN);
         $events = $poll->poll($read, $write, $this->timeout);
         //  If we got a reply, process it
         if ($events) {
             $request->recv();
             if ($this->verbose) {
                 echo "I: received reply:", $request->__toString(), PHP_EOL;
             }
             //  Don't try to handle errors, just assert noisily
             assert($request->parts() >= 3);
             $header = $request->pop();
             assert($header == MDPC_CLIENT);
             $reply_service = $request->pop();
             assert($reply_service == $service);
             return $request;
             //  Success
         } elseif ($retries_left--) {
             if ($this->verbose) {
                 echo "W: no reply, reconnecting...", PHP_EOL;
             }
             //  Reconnect, and resend message
             $this->connect_to_broker();
             $request->send();
         } else {
             echo "W: permanent error, abandoning request", PHP_EOL;
             break;
             //  Give up
         }
     }
 }
Exemple #6
0
 /**
  * This is the main listen and process loop
  */
 public function listen()
 {
     $read = $write = array();
     //  Get and process messages forever or until interrupted
     while (true) {
         $poll = new ZMQPoll();
         $poll->add($this->socket, ZMQ::POLL_IN);
         $events = $poll->poll($read, $write, HEARTBEAT_INTERVAL * ZMQ_POLL_MSEC);
         //  Process next input message, if any
         if ($events) {
             $zmsg = new Zmsg($this->socket);
             $zmsg->recv();
             if ($this->verbose) {
                 echo "I: received message:", PHP_EOL, $zmsg->__toString();
             }
             $sender = $zmsg->pop();
             $empty = $zmsg->pop();
             $header = $zmsg->pop();
             if ($header == MDPC_CLIENT) {
                 $this->client_process($sender, $zmsg);
             } else {
                 if ($header = MDPW_WORKER) {
                     $this->worker_process($sender, $zmsg);
                 } else {
                     echo "E: invalid message", PHP_EOL, $zmsg->__toString();
                 }
             }
         }
         //  Disconnect and delete any expired workers
         //  Send heartbeats to idle workers if needed
         if (microtime(true) > $this->heartbeat_at) {
             $this->purge_workers();
             foreach ($this->workers as $worker) {
                 $this->worker_send($worker, MDPW_HEARTBEAT, NULL, NULL);
             }
             $this->heartbeat_at = microtime(true) + HEARTBEAT_INTERVAL / 1000;
         }
     }
 }
Exemple #7
0
 /**
  * Start listen for messages in loop
  * @throws \Exception
  */
 public function listen()
 {
     if (!$this->listener) {
         throw new \Exception("Empty listener");
     }
     $this->isListen = true;
     while ($this->isListen) {
         $zmsg = new Zmsg($this->socket);
         $zmsg->recv();
         if ($this->verbose) {
             echo "I: received message from broker:", PHP_EOL;
             echo $zmsg->__toString(), PHP_EOL;
         }
         $time = $zmsg->unwrap();
         if (!$this->normalDelay) {
             $this->normalDelay = microtime(true) * 1000 - (double) $time;
         }
         $delayTime = microtime(true) * 1000 - (double) $time;
         if ($this->misser && $delayTime > $this->normalDelay + $this->maxAllowedDelay) {
             call_user_func($this->misser, $zmsg->pop(), $time, $delayTime);
         }
         call_user_func($this->listener, $zmsg->pop(), $time);
     }
 }
Exemple #8
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;
 }
Exemple #9
0
//  If liveness hits zero, queue is considered disconnected
$liveness = HEARTBEAT_LIVENESS;
$interval = INTERVAL_INIT;
//  Send out heartbeats at regular intervals
$heartbeat_at = microtime(true) + HEARTBEAT_INTERVAL;
$read = $write = array();
$cycles = 0;
while (true) {
    $poll = new ZMQPoll();
    $poll->add($worker, ZMQ::POLL_IN);
    $events = $poll->poll($read, $write, HEARTBEAT_INTERVAL * 1000);
    if ($events) {
        //  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);
Exemple #10
0
 /**
  * Send reply, if any, to broker and wait for next request.
  *
  * @param Zmsg $reply 
  * @return Zmsg Returns if there is a request to process
  */
 public function recv($reply = null)
 {
     //  Format and send the reply if we were provided one
     assert($reply || !$this->expect_reply);
     if ($reply) {
         $reply->wrap($this->reply_to);
         $this->send_to_broker(MDPW_REPLY, NULL, $reply);
     }
     $this->expect_reply = true;
     $read = $write = array();
     while (true) {
         $poll = new ZMQPoll();
         $poll->add($this->worker, ZMQ::POLL_IN);
         $events = $poll->poll($read, $write, $this->heartbeat);
         if ($events) {
             $zmsg = new Zmsg($this->worker);
             $zmsg->recv();
             if ($this->verbose) {
                 echo "I: received message from broker:", PHP_EOL;
                 echo $zmsg->__toString();
             }
             $this->liveness = HEARTBEAT_LIVENESS;
             //  Don't try to handle errors, just assert noisily
             assert($zmsg->parts() >= 3);
             $zmsg->pop();
             $header = $zmsg->pop();
             assert($header == MDPW_WORKER);
             $command = $zmsg->pop();
             if ($command == MDPW_REQUEST) {
                 //  We should pop and save as many addresses as there are
                 //  up to a null part, but for now, just save one...
                 $this->reply_to = $zmsg->unwrap();
                 return $zmsg;
                 //  We have a request to process
             } else {
                 if ($command == MDPW_HEARTBEAT) {
                     // Do nothing for heartbeats
                 } else {
                     if ($command == MDPW_DISCONNECT) {
                         $this->connect_to_broker();
                     } else {
                         echo "E: invalid input message", PHP_EOL;
                         echo $zmsg->__toString();
                     }
                 }
             }
         } else {
             if (--$this->liveness == 0) {
                 // poll ended on timeout, $event being false
                 if ($this->verbose) {
                     echo "W: disconnected from broker - retrying...", PHP_EOL;
                 }
                 usleep($this->reconnect * 1000);
                 $this->connect_to_broker();
             }
         }
         // Send HEARTBEAT if it's time
         if (microtime(true) > $this->heartbeat_at) {
             $this->send_to_broker(MDPW_HEARTBEAT, NULL, NULL);
             $this->heartbeat_at = microtime(true) + $this->heartbeat / 1000;
         }
     }
 }
Exemple #11
0
<?php

/*
 * MMI echo query example
 *
 * @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
 */
include 'mdcliapi.php';
$verbose = $_SERVER['argc'] > 1 && $_SERVER['argv'][1] == '-v';
$session = new MDCli("tcp://localhost:5555", $verbose);
//  This is the service we want to look up
$request = new Zmsg();
$request->body_set("echo");
//  This is the service we send our request to
$reply = $session->send("mmi.service", $request);
if ($reply) {
    $reply_code = $reply->pop();
    printf("Lookup echo service: %s %s", $reply_code, PHP_EOL);
}
Exemple #12
0
 /**
  * Process a request coming from a client
  *
  * @param string $sender
  * @param Zmsg $msg
  */
 public function client_process($sender, $msg)
 {
     $service_frame = $msg->pop();
     $service = $this->service_require($service_frame);
     //  Set reply return address to client sender
     $msg->wrap($sender, "");
     if (substr($service_frame, 0, 4) == 'mmi.') {
         $this->service_internal($service_frame, $msg);
     } else {
         $this->service_dispatch($service, $msg);
     }
 }
Exemple #13
0
<?php

/*
 *  Test zmsg class
 */
include "zmsg.php";
Zmsg::test();
Exemple #14
0
 /**
  * Returns the reply message or NULL if there was no reply. Does not
  * attempt to recover from a broker failure, this is not possible
  * without storing all unanswered requests and resending them all...
  *
  */
 public function recv()
 {
     $read = $write = array();
     //  Poll socket for a reply, with timeout
     $poll = new ZMQPoll();
     $poll->add($this->client, ZMQ::POLL_IN);
     $events = $poll->poll($read, $write, $this->timeout);
     //  If we got a reply, process it
     if ($events) {
         $msg = new Zmsg($this->client);
         $msg->recv();
         if ($this->verbose) {
             echo "I: received reply:", $msg->__toString(), PHP_EOL;
         }
         //  Don't try to handle errors, just assert noisily
         assert($msg->parts() >= 4);
         $msg->pop();
         // empty
         $header = $msg->pop();
         assert($header == MDPC_CLIENT);
         $reply_service = $msg->pop();
         return $msg;
         //  Success
     } else {
         echo "W: permanent error, abandoning request", PHP_EOL;
         return;
         //  Give up
     }
 }
Exemple #15
0
 /**
  * Initialise the master server that dispatches job to the worker processes
  *
  * @param int $port
  */
 protected function initAsMaster($port)
 {
     $ctx = new ZMQContext();
     $client = $ctx->getSocket(ZMQ::SOCKET_XREP);
     $client->bind('tcp://*:' . $port);
     $workers = $ctx->getSocket(ZMQ::SOCKET_XREQ);
     $workers->bind('ipc://' . $this->workersIpcName);
     $this->log(__CLASS__, "Master listening on port {$port}");
     $readable = $writable = array();
     while (true) {
         $poll = new ZMQPoll();
         $poll->add($client, ZMQ::POLL_IN);
         $poll->add($workers, ZMQ::POLL_IN);
         $poll->poll($readable, $writable);
         foreach ($readable as $socket) {
             $zmsg = new Zmsg($socket);
             $zmsg->recv();
             if ($socket === $client) {
                 $this->log(__CLASS__, "Master sending job to worker");
                 $zmsg->set_socket($workers)->send();
             } else {
                 if ($socket === $workers) {
                     $this->log(__CLASS__, "Master sending reply to client");
                     $zmsg->set_socket($client)->send();
                 }
             }
         }
     }
 }
Exemple #16
0
<?php

/*
 * Majordomo Protocol client example - asynchronous
 * Uses the mdcli API to hide all MDP aspects
 * 
 * @author Ian Barber <ian(dot)barber(at)gmail(dot)com>
 */
include_once "mdcliapi2.php";
$verbose = $_SERVER['argc'] > 1 && $_SERVER['argv'][1] == '-v';
$session = new MDCli("tcp://localhost:5555", $verbose);
for ($count = 0; $count < 10000; $count++) {
    $request = new Zmsg();
    $request->body_set("Hello world");
    $session->send("echo", $request);
}
for ($count = 0; $count < 10000; $count++) {
    $reply = $session->recv();
    if (!$reply) {
        break;
        // Interrupt or failure
    }
}
printf("%d replies received", $count);
echo PHP_EOL;
Exemple #17
0
/**
 * Attempt to process a single request, return 1 if successful
 *
 * @param Mdcli $client 
 * @param string $uuid 
 */
function s_service_success($client, $uuid)
{
    //  Load request message, service will be first frame
    $filename = s_request_filename($uuid);
    $fh = fopen($filename, "r");
    //  If the client already closed request, treat as successful
    if (!$fh) {
        return true;
    }
    $request = new Zmsg();
    $request->load($fh);
    fclose($fh);
    $service = $request->pop();
    //  Use MMI protocol to check if service is available
    $mmi_request = new Zmsg();
    $mmi_request->push($service);
    $mmi_reply = $client->send("mmi.service", $mmi_request);
    $service_ok = $mmi_reply && $mmi_reply->pop() == "200";
    if ($service_ok) {
        $reply = $client->send($service, $request);
        $filename = s_reply_filename($uuid);
        $fh = fopen($filename, "w");
        assert($fh);
        $reply->save($fh);
        fclose($fh);
        return true;
    }
    return false;
}
Exemple #18
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);
}
Exemple #19
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();
}
Exemple #20
0
                        $queue->s_worker_append($identity);
                    } else {
                        if ($zmsg->address() == 'HEARTBEAT') {
                            $queue->s_worker_refresh($identity);
                        } else {
                            printf("E: invalid message from %s%s%s", $identity, PHP_EOL, $zmsg->__toString());
                        }
                    }
                } else {
                    $zmsg->set_socket($frontend)->send();
                    $queue->s_worker_append($identity);
                }
            } else {
                //  Now get next client request, route to next worker
                $identity = $queue->s_worker_dequeue();
                $zmsg->wrap($identity);
                $zmsg->set_socket($backend)->send();
            }
        }
        if (microtime(true) > $heartbeat_at) {
            foreach ($queue as $id => $expiry) {
                $zmsg = new Zmsg($backend);
                $zmsg->body_set("HEARTBEAT");
                $zmsg->wrap($identity, NULL);
                $zmsg->send();
            }
            $heartbeat_at = microtime(true) + HEARTBEAT_INTERVAL;
        }
        $queue->s_queue_purge();
    }
}
Exemple #21
0
$session = new Mdcli("tcp://localhost:5555", $verbose);
//  1. Send 'echo' request to Titanic
$request = new Zmsg();
$request->push("Hello world");
$request->push("echo");
$reply = s_service_call($session, "titanic.request", $request);
$uuid = null;
if ($reply) {
    $uuid = $reply->pop();
    printf("I: request UUID %s %s", $uuid, PHP_EOL);
}
//  2. Wait until we get a reply
while (true) {
    usleep(100000);
    $request = new Zmsg();
    $request->push($uuid);
    $reply = s_service_call($session, "titanic.reply", $request);
    if ($reply) {
        $reply_string = $reply->last();
        printf("Reply: %s %s", $reply_string, PHP_EOL);
        //  3. Close request
        $request = new Zmsg();
        $request->push($uuid);
        $reply = s_service_call($session, "titanic.close", $request);
        break;
    } else {
        echo "I: no reply yet, trying again...", PHP_EOL;
        usleep(5000000);
        //  Try again in 5 seconds
    }
}
Exemple #22
0
$backend->bind("tcp://*:5556");
//  For workers
//  Queue of available workers
$available_workers = 0;
$worker_queue = array();
$read = $write = array();
while (true) {
    $poll = new ZMQPoll();
    $poll->add($backend, ZMQ::POLL_IN);
    //  Poll frontend only if we have available workers
    if ($available_workers) {
        $poll->add($frontend, ZMQ::POLL_IN);
    }
    $events = $poll->poll($read, $write);
    foreach ($read as $socket) {
        $zmsg = new Zmsg($socket);
        $zmsg->recv();
        //  Handle worker activity on backend
        if ($socket === $backend) {
            //  Use worker address for LRU routing
            assert($available_workers < MAX_WORKERS);
            array_push($worker_queue, $zmsg->unwrap());
            $available_workers++;
            //  Return reply to client if it's not a READY
            if ($zmsg->address() != "READY") {
                $zmsg->set_socket($frontend)->send();
            }
        } elseif ($socket === $frontend) {
            //  Now get next client request, route to next worker
            //  REQ socket in worker needs an envelope delimiter
            //  Dequeue and drop the next worker address
Exemple #23
0
 protected function workerSend(WorkerAddress $worker, $command, $data = null)
 {
     $zmsg = null;
     if ($data) {
         $zmsg = new Zmsg();
         $zmsg->body_set($data);
     }
     $this->send($worker->address, $command, $zmsg);
 }
Exemple #24
0
function server_worker()
{
    $context = new ZMQContext();
    $worker = new ZMQSocket($context, ZMQ::SOCKET_DEALER);
    $worker->connect("ipc://backend");
    $zmsg = new Zmsg($worker);
    while (true) {
        //  The DEALER socket gives us the address envelope and message
        $zmsg->recv();
        assert($zmsg->parts() == 2);
        // Send 0..4 replies back
        $replies = rand(0, 4);
        for ($reply = 0; $reply < $replies; $reply++) {
            //  Sleep for some fraction of a second
            usleep(rand(0, 1000) + 1);
            $zmsg->send(Zmsg::NOCLEAR);
        }
    }
}
Exemple #25
0
 protected function onPoll($events, $read, $write)
 {
     $events = $this->poll->poll($read, $write, $this->heartbeatDelay);
     $sendHeartBeat = true;
     if ($events) {
         $zmsg = new Zmsg($this->socket);
         $zmsg->recv();
         if ($this->verbose) {
             echo "I: received message from broker:", PHP_EOL;
             echo $zmsg->__toString(), PHP_EOL;
         }
         $this->heartbeatTriesLeft = $this->heartbeatMaxFails;
         $zmsg->pop();
         $header = $zmsg->pop();
         assert($header == Commands::W_WORKER);
         $command = $zmsg->pop();
         if ($command == Commands::W_HEARTBEAT) {
         } elseif ($command == Commands::W_REQUEST) {
             //@todo: get address
             $result = call_user_func($this->executor, $zmsg->pop());
             $this->send($result);
             //resp = HB
             $sendHeartBeat = false;
         } elseif ($command == Commands::W_RESPONSE) {
             $this->connect();
         } else {
             echo "I: Unsupported command `{$command}`.", PHP_EOL;
             echo $zmsg->__toString(), PHP_EOL, PHP_EOL;
         }
     } elseif (--$this->heartbeatTriesLeft == 0) {
         if ($this->verbose) {
             echo "I: disconnected from broker - retrying... ", PHP_EOL;
         }
         usleep($this->reconnectDelay * 1000);
         $this->connect();
     }
     $this->sendHeartbeat($sendHeartBeat);
 }