Skip to content

feat: add flushAll() method to Pool and PoolFactory#7698

Merged
limingxinleo merged 4 commits intohyperf:masterfrom
binaryfire:feature/pool-close-all
Jan 25, 2026
Merged

feat: add flushAll() method to Pool and PoolFactory#7698
limingxinleo merged 4 commits intohyperf:masterfrom
binaryfire:feature/pool-close-all

Conversation

@binaryfire
Copy link
Contributor

@binaryfire binaryfire commented Jan 15, 2026

Summary

This PR adds a flushAll() method to:

  • Hyperf\Pool\Pool - closes all connections in the pool
  • Hyperf\Redis\Pool\PoolFactory - closes all connections in all Redis pools
  • Hyperf\DbConnection\Pool\PoolFactory - closes all connections in all database pools

Why is this needed?

Problem: File descriptor exhaustion in test suites

When running large PHPUnit test suites with RunTestsInCoroutine (2000+ tests), each test creates a new application container with new pool instances. The old pools are not explicitly closed - they wait for garbage collection.

PHP's garbage collector does not run immediately. This causes file descriptors (socket connections) to accumulate until the process hits the OS limit (ulimit -n), resulting in errors like:

RedisException: Too many open files

This is a known PHPUnit issue (sebastianbergmann/phpunit#182) where file handles accumulate across tests. With coroutines, the problem is more severe because connection pools hold multiple socket file descriptors.

Solution

With flushAll(), test frameworks can explicitly close all pool connections between tests:

// In test tearDown
$container->get(RedisPoolFactory::class)->flushAll();
$container->get(DbPoolFactory::class)->flushAll();

Other use cases

  1. Graceful shutdown - Close all connections when worker exits
  2. Resource cleanup - Release connections in long-running processes
  3. Connection refresh - Force new connections after configuration change

Implementation

Pool::flushAll() reuses the existing flushOne(true) method:

public function flushAll(): void
{
    while ($this->getConnectionsInChannel() > 0) {
        $this->flushOne(true);
    }
}

PoolFactory::flushAll() calls flushAll() on all managed pools:

public function flushAll(): void
{
    foreach ($this->pools as $pool) {
        $pool->flushAll();
    }
}

Note

The RedisPoolStub test class had its own flushAll() implementation. This PR removes it since the base Pool class now provides this method.

Tests

  • Added testPoolFlushAll to PoolTest.php
  • Added PoolFactoryTest.php for Redis package
  • Added PoolFactoryTest.php for db-connection package

All tests pass with co-phpunit.

binaryfire and others added 3 commits January 15, 2026 14:34
Add Pool::flushAll() to close all connections in the channel.
Add PoolFactory::flushAll() to redis and db-connection packages
to close all connections across all managed pools.

This is useful for:
- Test suites: prevent file descriptor exhaustion when running
  many tests that each create fresh application containers
- Graceful shutdown: explicitly release all connections
- Resource cleanup in long-running processes
limingxinleo
limingxinleo previously approved these changes Jan 25, 2026
@limingxinleo limingxinleo merged commit 175cbfc into hyperf:master Jan 25, 2026
60 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants