Scalr\System\Zmq\Cron\Task\ScalarizrMessaging::enqueue PHP Method

enqueue() public method

See also: Scalr\System\Zmq\Cron\TaskInterface::enqueue()
public enqueue ( )
    public function enqueue()
    {
        $queue = new ArrayObject([]);
        $config = $this->config();
        try {
            //Removing pending messages for terminated farms
            $this->db->Execute("\n                DELETE m FROM `messages` m, `servers` s, `farms` f\n                WHERE s.`server_id` = m.`server_id` AND f.`id` = s.`farm_id`\n                AND m.`type`= ? AND m.`status` = ? AND f.`status` = ?\n            ", ["in", MESSAGE_STATUS::PENDING, FARM_STATUS::TERMINATED]);
            //Removing pending messages for disappeared/terminated servers
            $this->db->Execute("\n                DELETE m FROM `messages` m\n                WHERE m.`type`= ? AND m.`status` = ?\n                AND NOT EXISTS (SELECT 1 FROM `servers` s WHERE s.`server_id` = m.`server_id`)\n            ", ["in", MESSAGE_STATUS::PENDING]);
        } catch (ADODB_Exception $e) {
            if ($e->getCode() == ConnectionPool::ER_LOCK_DEADLOCK) {
                $this->getLogger()->warn("DEADLOCK happened while removing messages of terminated farms");
            } else {
                throw $e;
            }
        }
        $replicaMessages = $this->getReplicaTypes('type', '[\\w-]+');
        $replicaAccounts = $this->getReplicaAccounts();
        if (!empty($replicaMessages)) {
            //m_priority column will be non empty if there is at least one message of this type for current unuque server
            $stmt = ", MAX(FIND_IN_SET(m.`message_name`, '" . join(',', $replicaMessages) . "')) `m_priority` ";
        } else {
            $stmt = ", 0 `m_priority` ";
        }
        //Worker must handle messages for an each server sequentially and synchronously in the same order as they come
        $rows = $this->db->Execute("\n            SELECT m.`server_id`, s.`client_id` AS `account_id`\n            " . $stmt . "\n            FROM `messages` m\n            INNER JOIN `servers` s ON s.`server_id` = m.`server_id`\n            WHERE m.type = ?\n            AND m.status = ?\n            GROUP BY m.`server_id`\n            ORDER BY `m_priority`\n        ", ["in", MESSAGE_STATUS::PENDING]);
        while ($row = $rows->FetchRow()) {
            $t = new stdClass();
            $t->serverId = $row['server_id'];
            //Adjusts object with custom routing address.
            //It determines which of the workers pool should handle the task.
            //Handles priority of message names in the same order as it is provided in the config
            $t->address = $this->name . '.' . ($row['m_priority'] > 0 ? $replicaMessages[$row['m_priority'] - 1] : 'all') . '.' . (!empty($replicaAccounts) ? in_array($row['account_id'], $replicaAccounts) ? $row['account_id'] : 'all' : 'all');
            $queue->append($t);
        }
        if ($cnt = count($queue)) {
            $this->getLogger()->info("%d server%s %s waiting for processing", $cnt, $cnt > 1 ? 's' : '', $cnt > 1 ? 'are' : 'is');
        }
        return $queue;
    }