Architecture du PDO Pool

Cet article decrit la conception interne du PDO Pool. Si vous cherchez un guide d’utilisation, consultez PDO Pool : Pool de connexions.

Architecture a deux niveaux

Le PDO Pool est compose de deux couches :

1. Noyau PDO (pdo_pool.c) – logique de liaison des connexions aux coroutines, gestion des transactions, comptage de references des instructions.

2. Async Pool (zend_async_pool_t) – le pool de ressources universel de l’extension async. Gere la file d’attente des connexions libres, les limites et les verifications de sante. Il ne sait rien de PDO – il travaille avec des valeurs zval abstraites.

Cette separation permet d’utiliser le meme mecanisme de pool pour n’importe quelles ressources, pas seulement les bases de donnees.

Diagramme des composants

PDO Pool -- Composants

Connexion modele

Lors de la creation d’un PDO avec un pool, le noyau n’ouvre pas de connexion TCP reelle. A la place, un modele est cree – un objet pdo_dbh_t qui stocke le DSN, le nom d’utilisateur, le mot de passe et une reference au pilote. Toutes les connexions reelles sont creees plus tard, a la demande, sur la base de ce modele.

Pour le modele, db_handle_init_methods() est appele a la place de db_handle_factory(). Cette methode definit la table des methodes du pilote (dbh->methods) mais ne cree pas de connexion TCP et n’alloue pas de driver_data.

Cycle de vie d’une connexion

Cycle de vie d'une connexion dans le pool

Creation d’une connexion depuis le pool (Sequence)

Creation d'une connexion depuis le pool

API interne

pdo_pool.c – Fonctions publiques

Fonction Fonction
pdo_pool_create() Cree un pool pour pdo_dbh_t base sur les attributs du constructeur
pdo_pool_destroy() Libere toutes les connexions, ferme le pool, vide la table de hachage
pdo_pool_acquire_conn() Retourne une connexion pour la coroutine courante (reutilisation ou acquisition)
pdo_pool_peek_conn() Retourne la connexion liee sans acquisition (NULL si aucune)
pdo_pool_maybe_release() Retourne la connexion au pool si pas de transaction ou d’instructions
pdo_pool_get_wrapper() Retourne l’objet PHP Async\Pool pour la methode getPool()

pdo_pool.c – Callbacks internes

Callback Quand il est appele
pdo_pool_factory() Le pool a besoin d’une nouvelle connexion (acquire quand le pool est vide)
pdo_pool_destructor() Le pool detruit une connexion (a la fermeture ou a l’eviction)
pdo_pool_healthcheck() Verification periodique – la connexion est-elle toujours active ?
pdo_pool_before_release() Avant le retour au pool – rollback des transactions non validees
pdo_pool_free_conn() Ferme la connexion du pilote, libere la memoire

Liaison a une coroutine

Les connexions sont liees aux coroutines via une table de hachage pool_connections, ou la cle est l’identifiant de la coroutine et la valeur est un pointeur vers pdo_dbh_t.

L’identifiant de la coroutine est calcule par la fonction pdo_pool_coro_key() :

Nettoyage a la fin de la coroutine

Lorsqu’une connexion est liee a une coroutine, un pdo_pool_cleanup_callback est enregistre via coro->event.add_callback(). Lorsque la coroutine se termine (normalement ou avec une erreur), le callback retourne automatiquement la connexion au pool. Cela garantit l’absence de fuites de connexions meme en cas d’exceptions non gerees.

Verrouillage : blocage de connexion

Une connexion est verrouillee a une coroutine et ne retournera pas au pool si au moins une condition est remplie :

Le compteur de references est incremente lors de la creation d’une instruction et decremente lors de sa destruction. Lorsque les deux conditions sont levees, pdo_pool_maybe_release() retourne la connexion au pool.

Gestion des identifiants dans la fabrique

Lors de la creation d’une nouvelle connexion, pdo_pool_factory() copie les chaines DSN, nom d’utilisateur et mot de passe du modele via estrdup(). Cela est necessaire car les pilotes peuvent modifier ces champs durant db_handle_factory() :

Apres un appel reussi a db_handle_factory(), les copies sont liberees via efree(). En cas d’erreur, la liberation se fait via pdo_pool_free_conn(), qui est egalement utilise par le destructeur du pool.

Incompatibilite avec les connexions persistantes

Les connexions persistantes (PDO::ATTR_PERSISTENT) sont incompatibles avec le pool. Une connexion persistante est liee au processus et survit entre les requetes, tandis que le pool cree des connexions au niveau de la requete avec gestion automatique du cycle de vie. Tenter d’activer les deux attributs simultanement provoquera une erreur.

Et ensuite ?