/** * Constructor. * * @param AMQPMessage $message Message with serialized event. */ public function __construct(AMQPMessage $message) { $this->message = $message; $body = Util::jsonDecode($message->body); $this->firedAt = Util::datetimeFromString($body->fired_at); $this->name = $body->name; $this->eventId = $body->event_id; $ref = new \ReflectionClass(EventName::payloadClassForName($body->name)); $this->payload = $ref->getMethod('newFromResponse')->invoke(null, $body->payload); }
/** * Translate result message value into Task object. * * @return void * @throws Errors\ClientException When result message has not yet been received. */ private function translate() { if ($this->task) { return; } if (!isset($this->message)) { throw Errors\ClientException('Result has not yet been received'); } $celeryMsg = Util::jsonDecode($this->message->body); $this->task = Fatmouse::newTaskFromCeleryMessage($celeryMsg, $this->taskName); }
/** * 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(); } }