Example #1
0
 /**
  * Constucts object.
  *
  * @param callable             $callback   Callable to call for each consumed event.
  * @param AMQPStreamConnection $connection AMQP connection object.
  * @param string               $queue      Queue to bind.
  * @param string               $exchange   An events exchange.
  * @param string               $bindingKey A binding key.
  *
  * @throws ErrorException On network\transport errors.
  */
 public function __construct(callable $callback, AMQPStreamConnection $connection, $queue, $exchange, $bindingKey)
 {
     // TODO: consumer shoud has own connection with heartbeat.
     // The heartbeat is checked only during IO operations, so when AMQP connection
     // not used for a long time, RabbitMQ terminates connection
     $this->queue = $queue;
     $this->bindingKey = $bindingKey;
     $this->channel = $connection->channel();
     Util::declareQueue($connection, $queue, ['durable' => true, 'exclusive' => false]);
     Util::declareExchange($connection, $exchange, 'direct', ['auto_delete' => false]);
     $ch->queue_bind($queue, $exchange, $bindingKey);
     $wrapper = function ($msg) use($callback) {
         $event = new Event($msg);
         return $callback($event);
     };
     $ch->basic_consume($this->queue, '', false, false, false, false, $wrapper);
 }
Example #2
0
 /**
  * Initializes result objects: creates AMQP objects and binds result queue.
  *
  * @return void
  */
 public function initialize()
 {
     $this->channel = $this->connection->channel();
     // `auto-delete` argument makes sure that queue will be deleted after last queue
     // consumer disconnected. (Won't be deleted if there weren't any consumers)
     // `x-expires` queue option means that queue will be deleted if it's unused for the
     // specified time in milliseconds. Unused means that queue has no consumers,
     // the queue has not been redeclared, and basic.get has not been invoked.
     Util::declareQueue($this->connection, $this->taskId, ['exclusive' => false, 'durable' => true, 'auto_delete' => true, 'arguments' => ['x-expires' => self::EXPIRE_TIME]]);
     Util::declareExchange($this->connection, 'celeryresults', 'direct', ['exclusive' => false]);
     $this->channel->queue_bind($this->taskId, 'celeryresults', $this->taskId);
 }
Example #3
0
 /**
  * Generic method to synchronously call Fatmouse Agent tasks.
  * 
  * Create result queue for the task and bind it to results exchange.
  * Scalr uses agent tasks directly in synchronous manner (mostly for
  * retrieving server stats), and due to very high request rate we need
  * to clean up per-task result queues ASAP.
  *
  * `auto-delete` argument makes sure that queue will be deleted after last queue
  * consumer disconnected. (Won't be deleted if there weren't any consumers)
  *
  * `x-expires` queue option means that queue will be deleted if it's unused for the
  * specified time in milliseconds. Unused means that queue has no consumers,
  * the queue has not been redeclared, and basic.get has not been invoked.
  * 
  * Example: Call Fatmouse Agent task
  * <code>
  * <?php
  * $serverId = "cf3a320b-7ac6-4b88-810a-c760a94e1875";
  * $taskName = "sys.set_hostname";
  * $params = ["hostname" => "myexample.com"];
  * $timeout = 5; 
  * $result = $fatmouse->callAgentSync($serverId, $taskName, $params, $timeout);
  * ?>
  * </code>
  * 
  * @param string $serverId Scalr server-id to call task at
  * @param string $taskName Agent task name
  * @param array $kwargs optional Task parameters
  * @param integer $timeout optional Result timeout in seconds
  * @return \stdClass|mixed Task result 
  */
 public function callAgentSync($serverId, $taskName, $kwargs = null, $timeout = null)
 {
     list($taskId, $serializedTask) = $this->prepareCeleryTask($taskName, $kwargs);
     $serverExchange = 'server.' . $serverId . '.celery';
     $connection = $this->getConnection();
     $channel = $connection->channel();
     $timeout = $timeout === null ? $this->defaultCallAgentTimeout : $timeout;
     try {
         Util::declareQueue($connection, $taskId, ['durable' => false, 'auto_delete' => true, 'arguments' => $timeout ? ['x-expires' => $timeout * 1000] : null]);
         Util::declareExchange($connection, 'celeryresults', 'direct');
         $channel->queue_bind($taskId, 'celeryresults', $taskId);
         // Sending task to server's queue
         $msg = new AMQPMessage($serializedTask, $this->publishParams);
         $channel->basic_publish($msg, $serverExchange);
         $result = null;
         $setResult = function ($msg) use(&$result) {
             $result = Util::jsonDecode($msg->body);
         };
         // Setting callback for message
         $channel->basic_consume($taskId, '', false, true, false, false, $setResult);
         try {
             $channel->wait(null, false, $timeout);
         } catch (AMQPTimeoutException $e) {
             throw new Errors\ClientException(sprintf("Timeout %d seconds exceeded while waiting for task '%s' to complete on server '%s'", $timeout, $taskName, $server_id));
         }
         return $result;
     } finally {
         $channel->close();
     }
 }