Skip to content

Instantly share code, notes, and snippets.

@niisan-tokyo
Last active February 26, 2022 09:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niisan-tokyo/dd61d54d670e0702d955 to your computer and use it in GitHub Desktop.
Save niisan-tokyo/dd61d54d670e0702d955 to your computer and use it in GitHub Desktop.
Asynchronous MySQL code
<?php
namespace NiisanTokyo\As2sm;
use Evenement\EventEmitter;
use React\EventLoop\LoopInterface;
/**
* The asynchronous wrapper for MySQL
*/
class MysqlWrapper extends EventEmitter
{
const INTERVAL = 0.001;// The periodic timer cycle
private static $_loop = null;
/**
* Setting the default loop.
*
* if you want to use this class without regard to loop.
*
* @param LoopInterface $loop loop
*/
public static function setDefaultLoop(LoopInterface $loop)
{
self::$_loop = $loop;
}
private $connection = null;
private $loop = null;
private $timer = null;
public function __construct($config, LoopInterface $loop = null)
{
$this->connection = new \mysqli(
$config['host'],
$config['user'],
$config['pass'],
$config['db']
);
$this->loop = ($loop === null) ? self::$_loop : $loop;
}
/**
* Create asynchronous query.
*
* @param type $sql
* @param type $callback
* @return type
*/
public function query($sql, $callback = null)
{
$this->connection->query($sql, MYSQLI_ASYNC);
$that = $this;
$this->timer = $this->loop->addPeriodicTimer(self::INTERVAL, function () use ($that) {
$that->checkPolling();
});
if ($callback === null) {
return;
}
$this->on('success', $callback);
}
/**
* Disconect from the mysql stream
*/
public function disconnect()
{
$this->connection->kill($this->connection->thread_id);
}
/**
* Checking the connection status;
*
* @return type
*/
private function checkPolling()
{
$read = $error = $reject = [$this->connection];
if (! \mysqli::poll($read, $error, $reject, 0, 1)) {
return;
}
if ($res = $this->connection->reap_async_query()) {
$this->emit('success', [$res]);
} else {
$this->emit('error');
}
$this->loop->cancelTimer($this->timer);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment