Example #1
0
 public function testIdenticalConnections()
 {
     $pool = new ConnectionPool();
     $connection = null;
     $pool->withConnection(function ($conn) use($pool, &$connection) {
         $connection = $conn;
         $pool->releaseConnection($conn);
     });
     $pool->withConnection(function ($conn) use($pool, $connection) {
         $this->assertSame($connection, $conn);
         $pool->releaseConnection($conn);
     });
 }
Example #2
0
 public function loopTick(TimerInterface $timer)
 {
     if (count($this->conns) == 0) {
         // If we are shutting down, and have nothing to check, kill the timer.
         if ($this->shuttingDown) {
             // TODO: Possible race condition if shutdown also queues queries, such as a final save.
             // This could be prematurely cancelled.
             $timer->cancel();
         }
         // Nothing in the queue.
         return;
     }
     $reads = $errors = $rejects = [];
     foreach ($this->conns as $conn) {
         $reads[] = $conn['mysqli'];
     }
     // Returns immediately, the non-blocking magic!
     if (mysqli_poll($reads, $errors, $rejects, 0) < 1) {
         return;
     }
     /** @var Connection $read */
     foreach ($reads as $read) {
         /** @var Deferred $deferred */
         $deferred = $this->conns[$read->id]['deferred'];
         $result = $read->reap_async_query();
         if ($result !== false) {
             $deferred->resolve($result);
             // $result is true for non-select queries.
             if ($result instanceof \mysqli_result) {
                 // If userland code has already freed the result, this will throw a warning.
                 // No need to throw a warning here...
                 // If you know how to check if the result has already been freed, please PR!
                 @$result->free();
             }
         } else {
             $deferred->reject($read->error);
         }
         // Release the connection
         $this->pool->releaseConnection($read);
         unset($this->conns[$read->id]);
     }
     // Check error pile.
     // Current understanding is that this would only happen if the connection
     // was closed, or not opened correctly.
     foreach ($errors as $error) {
         $this->pool->releaseConnection($error);
         unset($this->conns[$error->id]);
         throw new \Exception('Unexpected mysqli_poll $error.');
     }
     // Check rejection pile.
     // Current understanding is that this would only happen if we passed a
     // connection that was already reaped. But... maybe not.
     foreach ($rejects as $reject) {
         $this->pool->releaseConnection($reject);
         unset($this->conns[$reject->id]);
         throw new \Exception('Unexpected mysqli_poll $reject.');
     }
     // Duplicated check to avoid one extra tick!
     // If we are shutting down, cancel timer once connections finish.
     if ($this->shuttingDown && count($this->conns) == 0) {
         $timer->cancel();
     }
 }