diff --git a/src/Illuminate/Database/ConnectionException.php b/src/Illuminate/Database/ConnectionException.php deleted file mode 100644 index c67b87c5fd14c0d1748ce642782a72c011f1ae7e..0000000000000000000000000000000000000000 --- a/src/Illuminate/Database/ConnectionException.php +++ /dev/null @@ -1,8 +0,0 @@ -container->bound($key = "db.connector.{$config['driver']}")) { - return $this->container->make($key); - } - - switch ($config['driver']) { - case 'sw-co-mysql': - return new CoroutineMySQLConnector(); - } - return parent::createConnector($config); - } - - protected function createSingleConnection(array $config) - { - if (method_exists($this, 'createPdoResolver')) { - $pdo = $this->createPdoResolver($config); - } else { - $pdo = $this->createConnector($config)->connect($config); - } - return $this->createSwooleConnection($config['driver'], $pdo, $config['database'], $config['prefix'], $config); - } - - protected function createSwooleConnection($driver, $connection, $database, $prefix = '', array $config = []) - { - if (method_exists(Connection::class, 'getResolver')) { - if ($resolver = Connection::getResolver($driver)) { - return $resolver($connection, $database, $prefix, $config); - } - } else { - if ($this->container->bound($key = "db.connection.{$driver}")) { - return $this->container->make($key, [$connection, $database, $prefix, $config]); - } - } - - switch ($driver) { - case 'sw-co-mysql': - return new SwooleMySQLConnection($connection, $database, $prefix, $config); - } - return parent::createConnection($driver, $connection, $database, $prefix, $config); - } -} \ No newline at end of file diff --git a/src/Illuminate/Database/ConnectionPool/ConnectionPools.php b/src/Illuminate/Database/ConnectionPool/ConnectionPools.php new file mode 100644 index 0000000000000000000000000000000000000000..202f788dc5059f309af478e786e23bd7d770cd5d --- /dev/null +++ b/src/Illuminate/Database/ConnectionPool/ConnectionPools.php @@ -0,0 +1,49 @@ +min = $min; + $this->max = $max; + $this->resolver = $resolver; + } + + public function getPool($name) + { + if (isset($this->pools[$name])) { + return $this->pools[$name]; + } + $pool = new Pool($name, $this->min, $this->max, function () use ($name) { + return call_user_func($this->resolver, $name); + }); + return $this->pools[$name] = $pool; + } + +} \ No newline at end of file diff --git a/src/Illuminate/Database/Connectors/CoroutineMySQLConnector.php b/src/Illuminate/Database/Connectors/CoroutineMySQLConnector.php deleted file mode 100644 index 96699fc6591c701fb81032ad85e8f61c4f1914c7..0000000000000000000000000000000000000000 --- a/src/Illuminate/Database/Connectors/CoroutineMySQLConnector.php +++ /dev/null @@ -1,74 +0,0 @@ -connect($config); - } catch (\Exception $e) { - $mysql = $this->tryAgainIfCausedByLostConnectionForCoroutineMySQL($e, $config); - } - - return $mysql; - } - - /** - * @param \Throwable $e - * @param array $config - * @return SwoolePDO - * @throws \Throwable - */ - protected function tryAgainIfCausedByLostConnectionForCoroutineMySQL($e, array $config) - { - if (parent::causedByLostConnection($e) || Str::contains($e->getMessage(), ['is closed', 'is not established'])) { - return $this->connect($config); - } - throw $e; - } - - /** - * @param array $config - * @return SwoolePDO - */ - public function connect(array $config) - { - $connection = new SwoolePDO(); - $connection->connect([ - 'host' => Arr::get($config, 'host', '127.0.0.1'), - 'port' => Arr::get($config, 'port', 3306), - 'user' => Arr::get($config, 'username', 'hhxsv5'), - 'password' => Arr::get($config, 'password', '52100'), - 'database' => Arr::get($config, 'database', 'test'), - 'timeout' => Arr::get($config, 'timeout', 5), - 'charset' => Arr::get($config, 'charset', 'utf8mb4'), - 'strict_type' => Arr::get($config, 'strict', false), - ]); - if (isset($config['timezone'])) { - $connection->query('set time_zone="' . $config['timezone'] . '"'); - } - if (isset($config['strict'])) { - if ($config['strict']) { - $connection->query("set session sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES'"); - } else { - $connection->query("set session sql_mode='ANSI_QUOTES'"); - } - } - return $connection; - } -} \ No newline at end of file diff --git a/src/Illuminate/Database/DatabaseManager.php b/src/Illuminate/Database/DatabaseManager.php index cb131819847f306ad787c852dfce7b7b0b589135..d97745838e5819d25277b7dc515a4ac0fc508181 100644 --- a/src/Illuminate/Database/DatabaseManager.php +++ b/src/Illuminate/Database/DatabaseManager.php @@ -6,14 +6,23 @@ use Illuminate\Database\DatabaseManager as IlluminateDatabaseManager; class DatabaseManager extends IlluminateDatabaseManager { - public function __construct($app, ConnectionFactory $factory) + public function connection($name = null) { - parent::__construct($app, $factory); + $pool = $this->app['db.pool']->getPool($name); + $connection = $pool->get(); + \Log::info(__METHOD__, [$name, get_class($connection)]); + return $connection; } -// public function connection($name = null) -// { -// $this->connections = []; -// return parent::connection($name); -// } + public function parentConnection($name = null) + { + return parent::connection($name); + } + + public function disconnect($name = null) + { + \Log::info(__METHOD__, [$name]); + $pool = $this->app['db.pool']->getPool($name); + $pool->put($name, parent::connection($name)); + } } \ No newline at end of file diff --git a/src/Illuminate/Database/DatabaseServiceProvider.php b/src/Illuminate/Database/DatabaseServiceProvider.php index 4014a0d9585b5ad7bcd11f2d2633e5ac89334723..a0f982519659bde861ddd7c4717da50f91a71d21 100644 --- a/src/Illuminate/Database/DatabaseServiceProvider.php +++ b/src/Illuminate/Database/DatabaseServiceProvider.php @@ -2,30 +2,36 @@ namespace Hhxsv5\LaravelS\Illuminate\Database; -use Illuminate\Database\Eloquent\Model; +use Hhxsv5\LaravelS\Illuminate\Database\ConnectionPool\ConnectionPools; +use Illuminate\Database\Connection; use Illuminate\Database\DatabaseServiceProvider as IlluminateDatabaseServiceProvider; class DatabaseServiceProvider extends IlluminateDatabaseServiceProvider { public function register() { - Model::clearBootedModels(); - - $this->registerEloquentFactory(); - - $this->registerQueueableEntityResolver(); - - - $this->app->singleton('db.factory', function ($app) { - return new ConnectionFactory($app); - }); + parent::register(); $this->app->singleton('db', function ($app) { - return new DatabaseManager($app, $app['db.factory']); + $db = new DatabaseManager($app, $app['db.factory']); + $version = $app->version(); + if (!version_compare($version, '5.2', '>=')) { + throw new \Exception('Connection pool needs the version of Laravel/Lumen >= 5.2'); + } + return $db; }); - $this->app->bind('db.connection', function ($app) { - return $app['db']->connection(); + $this->app->singleton('db.pool', function ($app) { + $min = 2; // TODO + $max = 4; + $pools = new ConnectionPools($min, $max, function ($name) use ($app) { + /** + * @var Connection $connection + */ + $connection = $app['db']->parentConnection($name); + return $connection; + }); + return $pools; }); } } \ No newline at end of file diff --git a/src/Illuminate/Database/RecycleConnectionServiceProvider.php b/src/Illuminate/Database/RecycleConnectionServiceProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..b4efa0f3b22eabc30760a66fa7347bc78d63fa6e --- /dev/null +++ b/src/Illuminate/Database/RecycleConnectionServiceProvider.php @@ -0,0 +1,35 @@ +app->bound('swoole')) { + DB::listen(function (QueryExecuted $query) { + Log::info(__METHOD__, [$query->sql]); + }); + } + } + + /** + * Register any application services. + * + * @return void + */ + public function register() + { + + } +} diff --git a/src/Illuminate/Database/StatementException.php b/src/Illuminate/Database/StatementException.php deleted file mode 100644 index 3b82c9f7794cd7f236292fcd9e55556f76a957ad..0000000000000000000000000000000000000000 --- a/src/Illuminate/Database/StatementException.php +++ /dev/null @@ -1,8 +0,0 @@ -causedByLostConnection($e->getPrevious()) || Str::contains($e->getMessage(), ['is closed', 'is not established'])) { - $this->reconnect(); - - return $this->runQueryCallback($query, $bindings, $callback); - } - - throw $e; - } -} \ No newline at end of file diff --git a/src/Illuminate/Database/SwoolePDO.php b/src/Illuminate/Database/SwoolePDO.php deleted file mode 100644 index 29838521010739d32314b58050bb42f069d1c723..0000000000000000000000000000000000000000 --- a/src/Illuminate/Database/SwoolePDO.php +++ /dev/null @@ -1,132 +0,0 @@ -sm = new SwooleMySQL(); - } - - /** - * @param array $serverInfo - * @throws ConnectionException - */ - public function connect(array $serverInfo) - { - $this->sm->connect($serverInfo); - - if ($this->sm->connected === false) { - $msg = sprintf('Cannot connect to the database: %s', - $this->sm->connect_errno ? $this->sm->connect_error : $this->sm->error - ); - $code = $this->sm->connect_errno ?: $this->sm->errno; - throw new ConnectionException($msg, $code); - } - - } - - public function prepare($statement, $options = null) - { - $swStatement = $this->sm->prepare($statement); - if ($swStatement === false) { - throw new QueryException($statement, [], new StatementException($this->sm->error, $this->sm->errno)); - } - return new SwoolePDOStatement($swStatement); - } - - public function beginTransaction() - { - $this->isInTransaction = true; - $this->sm->begin(); - } - - public function commit() - { - $this->sm->commit(); - $this->isInTransaction = false; - } - - public function rollBack() - { - $this->sm->rollback(); - $this->isInTransaction = false; - } - - public function query($statement, $mode = \PDO::ATTR_DEFAULT_FETCH_MODE, $arg3 = null, array $ctorargs = []) - { - $result = $this->sm->query($statement, array_get($ctorargs, 'timeout', 0.0)); - if ($result === false) { - throw new QueryException($statement, [], new \Exception($this->sm->error, $this->sm->errno)); - } - return $result; - } - - public function exec($statement) - { - return $this->query($statement); - } - - public function lastInsertId($name = null) - { - return $this->sm->insert_id; - } - - public function rowCount() - { - return $this->sm->affected_rows; - } - - public function quote($string, $parameter_type = \PDO::PARAM_STR) - { - //TODO - return $string; - } - - public function errorCode() - { - return $this->sm->errno; - } - - public function errorInfo() - { - return [ - $this->sm->errno, - $this->sm->errno, - $this->sm->error, - ]; - } - - public function inTransaction() - { - return $this->isInTransaction; - } - - public function getAttribute($attribute) - { - return isset($this->sm->serverInfo[$attribute]) ? $this->sm->serverInfo[$attribute] : null; - } - - public function setAttribute($attribute, $value) - { - // TODO - return false; - } - - public static function getAvailableDrivers() - { - return ['mysql']; - } - - public function __destruct() - { - $this->sm->close(); - } -} diff --git a/src/Illuminate/Database/SwoolePDOStatement.php b/src/Illuminate/Database/SwoolePDOStatement.php deleted file mode 100644 index 00e140eecbac25f5a9a2f0500af5fd8ee418626f..0000000000000000000000000000000000000000 --- a/src/Illuminate/Database/SwoolePDOStatement.php +++ /dev/null @@ -1,50 +0,0 @@ -statement = $statement; - } - - public function rowCount() - { - return $this->statement->affected_rows; - } - - public function bindValue($parameter, $value, $data_type = \PDO::PARAM_STR) - { - $this->bindParams[$parameter] = $value; - } - - /** - * @param array $input_parameters - * @return bool - * @throws StatementException - */ - public function execute($input_parameters = null) - { - if (empty($input_parameters) && !empty($this->bindParams)) { - $input_parameters = $this->bindParams; - } - $input_parameters = (array)$input_parameters; - $this->result = $this->statement->execute($input_parameters, array_get($input_parameters, '__timeout__', -1)); - if ($this->statement->errno != 0) { - throw new StatementException($this->statement->error, $this->statement->errno); - } - return true; - } - - public function fetchAll($how = null, $class_name = null, $ctor_args = null) - { - return $this->result; - } -} \ No newline at end of file diff --git a/src/Swoole/Pool/Pool.php b/src/Swoole/Pool/Pool.php new file mode 100644 index 0000000000000000000000000000000000000000..88798dc2afec8de80c8edd42a234a6fa3a46e042 --- /dev/null +++ b/src/Swoole/Pool/Pool.php @@ -0,0 +1,83 @@ += 1'); + } + if ($max < $min) { + throw new \InvalidArgumentException('The max must be >= min'); + } + + $this->name = $name; + $this->min = $min; + $this->max = $max; + $this->pool = new Channel($this->max); + $this->resolver = $resolver; + $this->fill(); + } + + protected function fill() + { + go(function () { + $count = $this->min - $this->size(); + for ($i = 0; $i < $count; $i++) { + $resource = call_user_func($this->resolver, $this->name); + $this->put($resource); + } + }); + } + + public function size() + { + return $this->pool->length(); + } + + public function get() + { + if ($this->size() == 0) { + $this->fill(); + } + return $this->pool->pop(); + } + + public function put($resource) + { + if ($this->pool->length() > $this->max) { + return false; + } + return $this->pool->push($resource); + } + +} \ No newline at end of file diff --git a/src/Swoole/Pool/PoolInterface.php b/src/Swoole/Pool/PoolInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..5cdb1eadbc1ed16acaa772d571507ccfeef314c6 --- /dev/null +++ b/src/Swoole/Pool/PoolInterface.php @@ -0,0 +1,34 @@ +