From 540d84c115e1ce51c53289f1eb8e36fd31687ba0 Mon Sep 17 00:00:00 2001 From: Xavier Leune Date: Mon, 26 Jan 2026 15:31:19 +0100 Subject: [PATCH 1/2] Worker mode: implement reset interface --- composer.json | 3 ++- src/Ting/ConnectionPool.php | 8 +++++++- src/Ting/Driver/Mysqli/Driver.php | 30 +++++++++++++++++++++++++++++- src/Ting/Driver/Pgsql/Driver.php | 24 +++++++++++++++++++++++- src/Ting/UnitOfWork.php | 12 +++++++++++- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 07aa4142..614010f0 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "php": ">=7.1", "pimple/pimple": "^3.0", "aura/sqlquery": "^2.6", - "doctrine/cache": "^1.6" + "doctrine/cache": "^1.6", + "symfony/contracts": "^2.5 || ^3.0" }, "require-dev": { "ext-pgsql": "*", diff --git a/src/Ting/ConnectionPool.php b/src/Ting/ConnectionPool.php index 9b0deb63..9e9e1d34 100644 --- a/src/Ting/ConnectionPool.php +++ b/src/Ting/ConnectionPool.php @@ -27,8 +27,9 @@ use CCMBenchmark\Ting\Driver\DriverInterface; use CCMBenchmark\Ting\Exceptions\ConnectionException; use CCMBenchmark\Ting\Logger\DriverLoggerInterface; +use Symfony\Contracts\Service\ResetInterface; -class ConnectionPool implements ConnectionPoolInterface +class ConnectionPool implements ConnectionPoolInterface, ResetInterface { /** @@ -226,4 +227,9 @@ public function getDriverClass($name) return $this->connectionConfig[$name]['namespace'] . '\\Driver'; } + + public function reset(): void + { + $this->closeAll(); + } } diff --git a/src/Ting/Driver/Mysqli/Driver.php b/src/Ting/Driver/Mysqli/Driver.php index 32464824..e3886477 100755 --- a/src/Ting/Driver/Mysqli/Driver.php +++ b/src/Ting/Driver/Mysqli/Driver.php @@ -35,9 +35,10 @@ use CCMBenchmark\Ting\Logger\DriverLoggerInterface; use CCMBenchmark\Ting\Repository\CollectionInterface; +use Symfony\Contracts\Service\ResetInterface; use function is_null; -class Driver implements DriverInterface +class Driver implements DriverInterface, ResetInterface { /** @@ -560,4 +561,31 @@ public function setTimezone($timezone) $this->connection->query(sprintf($query, $value)); $this->currentTimezone = $timezone; } + + /** + * Reset state between requests (worker mode: FrankenPHP, Swoole, RoadRunner, etc.) + */ + public function reset(): void + { + // Rollback any open transaction to prevent state leaks + if ($this->transactionOpened === true && $this->connected === true) { + @$this->connection->rollback(); + $this->transactionOpened = false; + } + + // Close the connection to avoid server-side timeouts + $this->close(); + + // Reinitialize connection object for next request + $this->connection = \mysqli_init(); + $this->connection->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1); + + // Clear prepared queries as they are connection-scoped + $this->preparedQueries = []; + + // Reset connection state + $this->currentDatabase = null; + $this->currentCharset = null; + $this->currentTimezone = null; + } } diff --git a/src/Ting/Driver/Pgsql/Driver.php b/src/Ting/Driver/Pgsql/Driver.php index 9d84093b..e623d891 100755 --- a/src/Ting/Driver/Pgsql/Driver.php +++ b/src/Ting/Driver/Pgsql/Driver.php @@ -33,8 +33,9 @@ use CCMBenchmark\Ting\Exceptions\TransactionException; use CCMBenchmark\Ting\Logger\DriverLoggerInterface; use CCMBenchmark\Ting\Repository\CollectionInterface; +use Symfony\Contracts\Service\ResetInterface; -class Driver implements DriverInterface +class Driver implements DriverInterface, ResetInterface { /** @@ -525,4 +526,25 @@ public function setTimezone($timezone) pg_query($this->connection, sprintf($query, $value)); $this->currentTimezone = $timezone; } + + /** + * Reset state between requests (worker mode: FrankenPHP, Swoole, RoadRunner, etc.) + */ + public function reset(): void + { + // Rollback any open transaction to prevent state leaks + if ($this->transactionOpened === true && $this->connection !== null) { + @pg_query($this->connection, 'ROLLBACK'); + $this->transactionOpened = false; + } + + // Clear last result reference + $this->result = null; + + // Close the connection to avoid server-side timeouts + $this->close(); + + // Clear prepared queries as they are connection-scoped + $this->preparedQueries = []; + } } diff --git a/src/Ting/UnitOfWork.php b/src/Ting/UnitOfWork.php index ca35c21b..2accce4b 100644 --- a/src/Ting/UnitOfWork.php +++ b/src/Ting/UnitOfWork.php @@ -30,8 +30,9 @@ use CCMBenchmark\Ting\Entity\PropertyListenerInterface; use CCMBenchmark\Ting\Query\QueryFactoryInterface; use CCMBenchmark\Ting\Repository\Metadata; +use Symfony\Contracts\Service\ResetInterface; -class UnitOfWork implements PropertyListenerInterface +class UnitOfWork implements PropertyListenerInterface, ResetInterface { const STATE_NEW = 1; const STATE_MANAGED = 2; @@ -229,6 +230,15 @@ public function detachAll() $this->entities = []; } + /** + * Reset state between requests (worker mode: FrankenPHP, Swoole, RoadRunner, etc.) + */ + public function reset(): void + { + $this->detachAll(); + $this->statements = []; + } + /** * Flag the entity to be deleted on next process * From c3256593da749a66d054c3803f4b0aa4fa00f9ed Mon Sep 17 00:00:00 2001 From: Xavier Leune Date: Tue, 27 Jan 2026 09:04:51 +0100 Subject: [PATCH 2/2] Remove `ResetInterface` from drivers and refactor its implementation in repositories. --- composer.json | 3 +-- src/Ting/ConnectionPool.php | 1 - src/Ting/Driver/Mysqli/Driver.php | 32 +----------------------------- src/Ting/Driver/Pgsql/Driver.php | 24 +--------------------- src/Ting/Repository/Repository.php | 9 ++++++++- src/Ting/ResetInterface.php | 8 ++++++++ src/Ting/UnitOfWork.php | 1 - 7 files changed, 19 insertions(+), 59 deletions(-) create mode 100644 src/Ting/ResetInterface.php diff --git a/composer.json b/composer.json index 614010f0..07aa4142 100644 --- a/composer.json +++ b/composer.json @@ -24,8 +24,7 @@ "php": ">=7.1", "pimple/pimple": "^3.0", "aura/sqlquery": "^2.6", - "doctrine/cache": "^1.6", - "symfony/contracts": "^2.5 || ^3.0" + "doctrine/cache": "^1.6" }, "require-dev": { "ext-pgsql": "*", diff --git a/src/Ting/ConnectionPool.php b/src/Ting/ConnectionPool.php index 9e9e1d34..d328ab3d 100644 --- a/src/Ting/ConnectionPool.php +++ b/src/Ting/ConnectionPool.php @@ -27,7 +27,6 @@ use CCMBenchmark\Ting\Driver\DriverInterface; use CCMBenchmark\Ting\Exceptions\ConnectionException; use CCMBenchmark\Ting\Logger\DriverLoggerInterface; -use Symfony\Contracts\Service\ResetInterface; class ConnectionPool implements ConnectionPoolInterface, ResetInterface { diff --git a/src/Ting/Driver/Mysqli/Driver.php b/src/Ting/Driver/Mysqli/Driver.php index e3886477..ac74a1f7 100755 --- a/src/Ting/Driver/Mysqli/Driver.php +++ b/src/Ting/Driver/Mysqli/Driver.php @@ -35,10 +35,7 @@ use CCMBenchmark\Ting\Logger\DriverLoggerInterface; use CCMBenchmark\Ting\Repository\CollectionInterface; -use Symfony\Contracts\Service\ResetInterface; -use function is_null; - -class Driver implements DriverInterface, ResetInterface +class Driver implements DriverInterface { /** @@ -561,31 +558,4 @@ public function setTimezone($timezone) $this->connection->query(sprintf($query, $value)); $this->currentTimezone = $timezone; } - - /** - * Reset state between requests (worker mode: FrankenPHP, Swoole, RoadRunner, etc.) - */ - public function reset(): void - { - // Rollback any open transaction to prevent state leaks - if ($this->transactionOpened === true && $this->connected === true) { - @$this->connection->rollback(); - $this->transactionOpened = false; - } - - // Close the connection to avoid server-side timeouts - $this->close(); - - // Reinitialize connection object for next request - $this->connection = \mysqli_init(); - $this->connection->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1); - - // Clear prepared queries as they are connection-scoped - $this->preparedQueries = []; - - // Reset connection state - $this->currentDatabase = null; - $this->currentCharset = null; - $this->currentTimezone = null; - } } diff --git a/src/Ting/Driver/Pgsql/Driver.php b/src/Ting/Driver/Pgsql/Driver.php index e623d891..9d84093b 100755 --- a/src/Ting/Driver/Pgsql/Driver.php +++ b/src/Ting/Driver/Pgsql/Driver.php @@ -33,9 +33,8 @@ use CCMBenchmark\Ting\Exceptions\TransactionException; use CCMBenchmark\Ting\Logger\DriverLoggerInterface; use CCMBenchmark\Ting\Repository\CollectionInterface; -use Symfony\Contracts\Service\ResetInterface; -class Driver implements DriverInterface, ResetInterface +class Driver implements DriverInterface { /** @@ -526,25 +525,4 @@ public function setTimezone($timezone) pg_query($this->connection, sprintf($query, $value)); $this->currentTimezone = $timezone; } - - /** - * Reset state between requests (worker mode: FrankenPHP, Swoole, RoadRunner, etc.) - */ - public function reset(): void - { - // Rollback any open transaction to prevent state leaks - if ($this->transactionOpened === true && $this->connection !== null) { - @pg_query($this->connection, 'ROLLBACK'); - $this->transactionOpened = false; - } - - // Clear last result reference - $this->result = null; - - // Close the connection to avoid server-side timeouts - $this->close(); - - // Clear prepared queries as they are connection-scoped - $this->preparedQueries = []; - } } diff --git a/src/Ting/Repository/Repository.php b/src/Ting/Repository/Repository.php index 1d31936e..e2391a7f 100644 --- a/src/Ting/Repository/Repository.php +++ b/src/Ting/Repository/Repository.php @@ -37,6 +37,7 @@ use CCMBenchmark\Ting\Exceptions\RepositoryException; use CCMBenchmark\Ting\MetadataRepository; use CCMBenchmark\Ting\Query\QueryFactory; +use CCMBenchmark\Ting\ResetInterface; use CCMBenchmark\Ting\Serializer\SerializerFactoryInterface; use CCMBenchmark\Ting\UnitOfWork; use Doctrine\Common\Cache\Cache; @@ -44,7 +45,7 @@ /** * @template T */ -abstract class Repository +abstract class Repository implements ResetInterface { const QUERY_SELECT = 'select'; @@ -412,4 +413,10 @@ public function getMetadata() { return $this->metadata; } + + public function reset(): void + { + $this->unitOfWork->reset(); + $this->connection = $this->metadata->getConnection($this->connectionPool); + } } diff --git a/src/Ting/ResetInterface.php b/src/Ting/ResetInterface.php new file mode 100644 index 00000000..f9777421 --- /dev/null +++ b/src/Ting/ResetInterface.php @@ -0,0 +1,8 @@ +