/** * Calculate the node priority from its job count, stick to the current node * * As the priority is based on the number of jobs, higher is better. * * @param Node $node * @param string $currentNodeId * * @return float Node priority */ private function calculateNodePriority(Node $node, $currentNodeId) { $priority = $node->getJobCount(); if ($node->getId() === $currentNodeId) { $margin = 1 + $this->marginToSwitch; $priority = $priority * $margin; } // Apply a weight determined by the node priority as assigned by Disque. // Priority 1 means the node is healthy. // Priority 10 to 100 means the node is probably failing, or has failed $disquePriority = $node->getPriority(); // Disque node priority should never be lower than 1, but let's be sure if ($disquePriority < Node::PRIORITY_OK) { $disquePriorityWeight = 1; } elseif (Node::PRIORITY_OK <= $disquePriority && $disquePriority < Node::PRIORITY_POSSIBLE_FAILURE) { // Node is OK, but Disque may have assigned a lower priority to it // We use the base-10 logarithm in the formula, so priorities // 1 to 10 transform into a weight of 1 to 0.5. When Disque starts // using more priority steps, priority 9 will discount about a half // of the job count. $disquePriorityWeight = 1 / (1 + log10($disquePriority)); } else { // Node is failing, or it has failed $disquePriorityWeight = 0; } $priority = $priority * $disquePriorityWeight; return (double) $priority; }
/** * Copy node stats from the old to the new node * * @param Node $oldNode * @param Node $newNode */ private function copyNodeStats(Node $oldNode, Node $newNode) { $oldNodeJobCount = $oldNode->getTotalJobCount(); $newNode->addJobCount($oldNodeJobCount); }
/** * Reveal the whole Disque cluster from a node HELLO response * * The HELLO response from a Disque node contains addresses of all other * nodes in the cluster. We want to learn about them and save them, so that * we can switch to them later, if needed. * * @param Node $node The current node */ private function revealClusterFromHello(Node $node) { $hello = $node->getHello(); $revealedNodes = []; foreach ($hello[HelloResponse::NODES] as $node) { $id = $node[HelloResponse::NODE_ID]; $revealedNode = $this->revealNodeFromHello($id, $node); // Update or set the node's priority as determined by Disque $priority = $node[HelloResponse::NODE_PRIORITY]; $revealedNode->setPriority($priority); $revealedNodes[$id] = $revealedNode; } $this->nodes = $revealedNodes; }