diff --git a/src/EventQueue.php b/src/EventQueue.php index c155767..88a5466 100644 --- a/src/EventQueue.php +++ b/src/EventQueue.php @@ -35,6 +35,13 @@ class EventQueue extends \SplPriorityQueue implements EventQueueInterface */ protected $priorities; + /** + * Track the last timestamp used for priority so we can avoid duplicate values + * + * @var int + */ + protected $lastTimestamp = 0; + /** * Initializes the list of event priorities. */ @@ -129,7 +136,11 @@ protected function getPriority($command, array $params) { $priority = new EventQueuePriority; $priority->value = $this->priorities[$command]; - $priority->timestamp = microtime(true) * 10000; + $priority->timestamp = (int) (microtime(true) * 10000); + if ($priority->timestamp <= $this->lastTimestamp) { + $priority->timestamp = $this->lastTimestamp + 1; + } + $this->lastTimestamp = $priority->timestamp; return $priority; } @@ -158,7 +169,7 @@ protected function queueIrcRequest($command, array $params = array()) */ public function compare($priority1, $priority2) { - $priority = $priority2->value - $priority1->value; + $priority = $priority1->value - $priority2->value; if (!$priority) { $priority = $priority2->timestamp - $priority1->timestamp; } diff --git a/src/EventQueuePriority.php b/src/EventQueuePriority.php index 335e581..7ca2d7f 100644 --- a/src/EventQueuePriority.php +++ b/src/EventQueuePriority.php @@ -28,7 +28,7 @@ class EventQueuePriority * same command in order to assign higher priority to events inserted * earlier * - * @var float + * @var int */ public $timestamp; } diff --git a/tests/EventQueueTest.php b/tests/EventQueueTest.php index c212312..501175c 100644 --- a/tests/EventQueueTest.php +++ b/tests/EventQueueTest.php @@ -183,4 +183,42 @@ public function testExtract() $this->assertInstanceOf('\Phergie\Irc\Event\EventInterface', $this->queue->extract()); $this->assertNull($this->queue->extract()); } + + /** + * Tests ordering by command priority then FIFO. + */ + public function testPriorities() + { + // start with empty queue + $this->assertNull($this->queue->extract()); + + // queue a bunch of stuff + $this->queue->ircQuit('Bye!'); + $this->queue->ircPrivmsg('#channel', 'text1'); + $this->queue->ircPrivmsg('#channel', 'text2'); + $this->queue->ircPrivmsg('#channel', 'text3'); + + // verify order of output + $event = $this->queue->extract(); + $this->assertInstanceOf('\Phergie\Irc\Event\EventInterface', $event); + $this->assertEquals('PRIVMSG', $event->getCommand()); + $this->assertEquals(['#channel', 'text1'], $event->getParams()); + + $event = $this->queue->extract(); + $this->assertInstanceOf('\Phergie\Irc\Event\EventInterface', $event); + $this->assertEquals('PRIVMSG', $event->getCommand()); + $this->assertEquals(['#channel', 'text2'], $event->getParams()); + + $event = $this->queue->extract(); + $this->assertInstanceOf('\Phergie\Irc\Event\EventInterface', $event); + $this->assertEquals('PRIVMSG', $event->getCommand()); + $this->assertEquals(['#channel', 'text3'], $event->getParams()); + + $event = $this->queue->extract(); + $this->assertInstanceOf('\Phergie\Irc\Event\EventInterface', $event); + $this->assertEquals('QUIT', $event->getCommand()); + $this->assertEquals(['Bye!'], $event->getParams()); + + $this->assertNull($this->queue->extract()); + } }