Exemplo n.º 1
0
 public function testComplex()
 {
     $context = new \ZMQContext();
     $output = new \ZMQSocket($context, \ZMQ::SOCKET_DEALER);
     $output->bind("inproc://zmsg_selftest");
     $input = new \ZMQSocket($context, \ZMQ::SOCKET_ROUTER);
     $input->connect("inproc://zmsg_selftest");
     //  Test send and receive of single-part message
     $zmsgo = new Zmsg($output);
     $zmsgo->setLast("Hello");
     $this->assertTrue($zmsgo->getLast() == "Hello");
     $zmsgo->send();
     $zmsgi = new Zmsg($input);
     $zmsgi->recv();
     $this->assertTrue($zmsgi->parts() == 2);
     $this->assertTrue($zmsgi->getLast() == "Hello");
     //  Test send and receive of multi-part message
     $zmsgo = new Zmsg($output);
     $zmsgo->setLast("Hello");
     $zmsgo->wrap("address1", "");
     $zmsgo->wrap("address2");
     $this->assertTrue($zmsgo->parts() == 4);
     $zmsgo->send();
     $zmsgi = new Zmsg($input);
     $zmsgi->recv();
     $this->assertTrue($zmsgi->parts() == 5);
     $zmsgi->unwrap();
     $this->assertTrue($zmsgi->unwrap() == "address2");
     $zmsgi->setLast(sprintf("%s%s", 'W', "orld"));
     $this->assertTrue($zmsgi->getLast() == "World");
     //  Pull off address 1, check that empty part was dropped
     $zmsgi->unwrap();
     $this->assertTrue($zmsgi->parts() == 1);
     //  Check that message body was correctly modified
     $part = $zmsgi->pop();
     $this->assertTrue($part == "World");
     $this->assertTrue($zmsgi->parts() == 0);
     // Test load and save
     $zmsg = new Zmsg();
     $zmsg->setLast("Hello");
     $zmsg->wrap("address1", "");
     $zmsg->wrap("address2");
     $this->assertTrue($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->getLast() == $zmsg->getLast());
     fclose($fh);
     $this->assertTrue($zmsg2->parts() == 4);
 }
Exemplo n.º 2
0
        try {
            $strRequestPayload = @json_encode($payload->body);
            $payload->setBody($task->worker($payload->body));
            $payload->code = 200;
        } catch (Exception $e) {
            $task->log('ERROR', "Worker %s failed with exception:%s - %s", $task->getName(), get_class($e), $e->getMessage());
            $payload = $payload->error(500, $e->getMessage());
        }
        $executionTime = microtime(true) - $start;
        $statPath = '/var/log/scalr/worker.log';
        if (is_writable($statPath)) {
            @error_log(sprintf("%s,%d,\"%s\",%0.4f,%d,\"%s\"\n", date('M d H:i:s P'), isset($payload->code) ? $payload->code : 500, $service, $executionTime, \Scalr::getDb()->numberQueries + (\Scalr::getContainer()->analytics->enabled ? \Scalr::getContainer()->cadb->numberQueries : 0), str_replace('"', '""', $strRequestPayload)), 3, $statPath);
        }
        //Resets the number of the queries
        \Scalr::getDb()->numberQueries = 0;
        if (\Scalr::getContainer()->analytics->enabled) {
            \Scalr::getContainer()->cadb->numberQueries = 0;
        }
    }
    //It checks memory usage for demonized tasks
    if ($config->daemon && !$task->checkMemoryUsage()) {
        //Adds the pid of the process to payload to handle it on client's side
        $payload->dw = posix_getpid();
        //It does not even exit execution loop. Client should start a replacement in its time.
        //We cannot start worker from here because it won't be correctly terminated by client.
    }
    $reply = new Zmsg();
    $reply->setLast(serialize($payload));
    unset($payload);
    unset($request);
}
Exemplo n.º 3
0
 /**
  * Handle internal service according to 8/MMI specification
  *
  * @param    string                 $frame  The frame
  * @param    \Scalr\System\Zmq\Zmsg $msg    The message
  */
 protected function handleInternalService($frame, $msg)
 {
     if ($frame == "mmi.service") {
         $name = $msg->getLast();
         $service = isset($this->services[$name]) ? $this->services[$name] : null;
         $code = !empty($service->workers) ? "200" : "404";
     } else {
         $code = "501";
     }
     $client = $msg->unwrap();
     $msg->setLast($code);
     //NOTE! We changed a bit ZMQ MDP protocol here.
     //The number of registered workers for the service follows the status frame.
     $msg->append(sprintf("%s", isset($service->workers) ? intval($service->workers) : "0"));
     $msg->push($frame);
     $msg->push(Mdp::CLIENT);
     $msg->wrap($client, "");
     if ($this->verbose) {
         $this->log("ZMQDEBUG", "responding mmi.service:\n--\n%s", (string) $msg);
     }
     $msg->setSocket($this->socket)->send();
 }
Exemplo n.º 4
0
 /**
  * Runs ZMQ MDP Asynchronous Client
  *
  * @throws Exception
  */
 protected function launchClient()
 {
     $this->launchWorkers();
     //We don't even need to start client if queue is empty
     if ($this->queue->count() == 0) {
         $this->log('DEBUG', "It does not need to start major-domo client as queue is empty.");
         return;
     }
     $this->log('DEBUG', "Launching %s 0mq mdp client", $this->name);
     $session = (new AsynClient(\Scalr::config('scalr.crontab.sockets.broker'), true))->setLogger(\Scalr::getContainer()->logger('Mdp\\AsynClient')->setLevel(\Scalr::config('scalr.crontab.log_level')))->setTimeout(\Scalr::config('scalr.crontab.heartbeat.delay') * \Scalr::config('scalr.crontab.heartbeat.liveness') * 2)->connect();
     $this->log('DEBUG', 'Sending request messages to broker');
     $payloadClass = $this->payloadClass;
     //The number of the requests sent
     $count = 0;
     //Array of the messages which are sent
     $sentMessages = [];
     //Gets queue iterator in order to gracefully iterate over an ArrayObject removing each offset
     $it = $this->queue->getIterator();
     //Sending messages loop
     while ($it->valid()) {
         $key = $it->key();
         //Creates standard payload for zmq messaging
         $payload = (new $payloadClass($it->current()))->setId();
         $sentMessages[$payload->getId()] = $payload;
         $request = new Zmsg();
         $request->setLast(serialize($payload));
         //Sends the message to worker
         if ($payload instanceof PayloadRouterInterface) {
             $session->send($payload->getAddress($this), $request);
         } else {
             $session->send($this->name, $request);
         }
         $count++;
         $it->next();
         //Removing the message from the queue
         $it->offsetUnset($key);
     }
     //Cleanup queue
     unset($this->queue);
     $this->log('DEBUG', 'Polling results');
     //Receiving loop
     for ($i = 0; $i < $count; $i++) {
         $msg = $session->recv();
         if (!$msg) {
             // Interrupt or failure
             $this->getLogger()->fatal("Some worker failed!");
             break;
         }
         //We are having deal with serialized data
         $payload = @unserialize($msg->getLast());
         if (!$payload instanceof AbstractPayload) {
             throw new TaskException(sprintf("Unexpected reply from worker: '%s'.", $msg->getLast()));
         }
         //Checks if worker reaches a memory limit
         if (!empty($payload->dw)) {
             $this->toDisconnect[$payload->dw] = $payload instanceof PayloadRouterInterface ? $payload->getAddress($this) : $this->name;
             $this->log("DEBUG", "Client got PID:%d from the worker %s to disconnect", $payload->dw, $this->toDisconnect[$payload->dw]);
         }
         if (!isset($sentMessages[$payload->getId()])) {
             //Message comes from previous session?
             $this->getLogger()->warn("Strange message came from another session. Payload:%s", var_export($payload, true));
             $count++;
         } else {
             //We get response so remove record
             unset($sentMessages[$payload->getId()]);
             //Triggers onResponse callback
             $this->onResponse($payload);
         }
     }
     if (!empty($this->toDisconnect) && $this->config()->daemon) {
         foreach ($this->toDisconnect as $pid => $address) {
             //Terminates worker
             $this->terminateWorker($pid);
             //We need to get up a replacement for that one
             $pid = $this->addWorker($address);
             //It is important to save a PID of the process to be able terminate all workers along with client
             $this->pids[$pid] = $pid;
         }
         //Resets event
         $this->toDisconnect = [];
         usleep(100000);
     }
     $this->onCompleted();
 }