Thread : connexion base de donnée

Un thread est une unité d’exécution. Cette unité fonctionne de façon autonome et parallèlement à d’autres threads. Le principal avantage des threads est de pouvoir répartir différents traitements d’un même programme en plusieurs unités distinctes pour permettre leurs exécutions « simultanées ».

Pour créer un thread rien de plus simple il suffit de faire :

Il existe une méthode status qui permet de retourner le statut d’un thread qui peut être utilisé de la manière suivante :

Cette méthode peut retourner les valeurs suivante :

sleep => le thread est en attente

run => le thread est en cour d’exécution

aborting => le thread est en cours d’annulation

false => le thread est terminé normalement

nil => le thread est terminé avec une exception

Il existe deux autres méthodes :

List permet de lister les threads qui sont arrêter ou qui sont en cour d’exécution.

Kill quant à lui permet de stopper un thread.

Dans l’idée les threads sont bien pratiques, cependant lorsque l’on commence a faire des thread.new l’erreur suivante « could not obtain a database connection within 5.000 seconds » est souvent levée.

Dans une application rails on a ce qu’on appel un pool de connexion définit à 5 par défaut et un timeout définit à 5 secondes. Ceci étant configurable dans le database.yml.

D’où la première solution logique qui à été d’augmenter ce pool de connexion. Cependant je ne sais pas quelles sont toutes les conséquences de cette action et jusqu’à quelle point peut-on augmenter ce pool de connexion ?

Malheureusement cela ne suffit pas a vaincre l’erreur qui met juste plus de temps a survenir.

Il apparaît que lorsque Rail utilise des threads ces derniers sont gérés correctement. Mais si on créer nos propres threads il faut les gérer nous même.

En effet, lorsque un thread se lance celui-ci va utiliser une connexion selon le pool de connexion disponible. Mais lorsqu’il meurt la connexion devient « orpheline » appelé aussi « fuite de connexion » et devient inutilisable. Donc si toutes les connexions deviennent orphelines il n’y à plus de connexion disponible donc l’erreur « could not obtain a database connection within 5.000 seconds » est levée.

Pour palier ce problème il existe une méthode « clear_stale_cached_connections! » qui permet de nettoyer les connexions orphelines. Cette méthode est valable en Rails 3.x.

Pour ce qui est de Rails 4 cette méthode à été réécrite et ne fait plus du tout la même chose.

Donc une solution qui semble valable en Rails 4 est la suivante :

Il faut ajouter dans la création du thread les lignes suivantes :

La ligne ActiveRecord::Base.connection_pool.release_connection permet donc de cleaner les connexions.

Malgré tout une autre erreur peut être levée « ActiveRecord::StatementInvalid (Mysql2::Error: This connection is in use by: #<Thread:0x007f99b6aa59e0 dead> » cette erreur n’arrête pas l’exécution du processus.

Il faut donc ajouter le code suivant dans le ensure si l’on veux gérer cette erreur :

Avec ceci je n’ai pas réussi a reproduire les erreurs obtenu.

 

source : bibwild.wordpress.com

stackoverflow

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.