Пакет · cpool

Справочник API

Шесть типов, все в неймспейсе Flytachi\Winter\CPool. Сигнатуры соответствуют исходному коду; для каждого элемента указаны аргументы, возвращаемые значения и неочевидная семантика.

Обзор

Тип Вид Роль
ConnectionFactory интерфейс адаптер драйвера — единственная точка расширения
ConnectionPool класс пул: выдать, вернуть, выселить
SingleConnection класс тот же смысл для рантайма без конкуренции
PoolEntry DTO выданное соединение и его метки времени
PoolPolicy значение настройки
PoolException исключение единственное исключение пакета

ConnectionFactory (interface)

php
public function create(): object;
public function validate(object $connection): bool;
public function close(object $connection): void;
Метод Описание
create() Открыть соединение. Может бросать — пул завернёт в PoolException::connectFailed()
validate($c) Дешёвая проверка живости. false → пул выселяет и открывает новое. Брошенное исключение тоже считается смертью
close($c) Закрыть. Ошибки пул игнорирует

Подробно — в Своём адаптере.


ConnectionPool (final class)

php
new ConnectionPool(
  ConnectionFactory $factory,
  PoolPolicy        $policy = new PoolPolicy(),
  ?Closure          $clock = null,
)

$clock — подмена источника времени, для тестов; в рабочем коде не нужен.

Метод Возвращает Описание
borrow() PoolEntry Взять соединение. Ниже потолка — создаёт новое; на потолке — ждёт до connectionTimeout. Бросает exhausted() по таймауту, unusable() если соединения подряд не проходят проверку
release($entry) void Вернуть в пул. Метка времени обновляется, проверка не выполняется
evict($entry) void Выселить и закрыть — для случая, когда вызывающий знает, что соединение сломано
stats() array ['total', 'idle', 'active', 'maximum']
close() void Закрыть все соединения и снять таймер уборки
abandon() void Забыть все соединения не закрывая и снять таймер — форк-безопасный аналог close()

Возврат обязателен

Пул не отслеживает невозвращённые соединения: каждая утечка навсегда уменьшает его на единицу. Оборачивайте borrow() в try/finally либо стройте фасад, возвращающий соединение в конце единицы работы.

evict() против release()

release() возвращает соединение в оборот как есть. Если вы знаете, что оно сломано — драйвер сообщил об обрыве, — возвращать его значит подсунуть заведомо мёртвое следующему заёмщику. Для этого evict().


SingleConnection (final class)

php
new SingleConnection(
  ConnectionFactory $factory,
  PoolPolicy        $policy = new PoolPolicy(),
  ?Closure          $clock = null,
)
Метод Возвращает Описание
get() object Соединение. Открывает при первом вызове; проверяет, если простояло дольше aliveBypassWindow; переоткрывает по истечении maxLifetime
peek() ?object Текущее соединение без создания и проверки — для диагностики без побочных эффектов
evict() void Сбросить; следующий get() откроет новое
close() void Закрыть

Для рантаймов, где процесс обслуживает одну единицу работы за раз. Соблюдает те же сроки жизни и проверки, поэтому долгоживущий CLI-воркер не просыпается с сокетом, который сервер закрыл часы назад.


PoolEntry (final class)

php
new PoolEntry(
  object  $resource,
  float   $createdAt,
  float   $lastUsedAt,
  ?float  $expiresAt,
)

То, что возвращает borrow(). Само соединение — в $entry->resource; остальное пул использует для решений о проверке и выселении. Создавать вручную не нужно.


PoolPolicy (final readonly class)

php
new PoolPolicy(
  int   $maximumPoolSize = 10,
  float $connectionTimeout = 15.0,
  float $maxLifetime = 1800.0,
  float $aliveBypassWindow = 0.5,
  float $maxLifetimeJitter = 0.1,
  float $housekeepingInterval = 30.0,
  float $keepaliveTime = 0.0,
  float $idleTimeout = 0.0,
  int   $minimumIdle = 0,
)

PoolPolicy::default(): PoolPolicy
$policy->housekeepingEnabled(): bool

Разбор каждого параметра — на странице Политика.


PoolException (final class)

Единственное исключение пакета, три именованных конструктора:

Конструктор Когда
exhausted(float $timeout) Свободного соединения не появилось за таймаут — все заняты
connectFailed(Throwable $previous) create() адаптера бросил; оригинал в getPrevious()
unusable(int $attempts) Соединения подряд не проходят проверку — база не отвечает

exhausted и unusable — разные диагнозы: первый говорит «ваш код держит всё», второй — «соединения плохи сами по себе».

Дальше