(fourni
par )
Cache avec fichiers
Notre deuxième partie est consacrée aux caches en fichiers.
Même si cela simple un mécanisme enfantin à mettre en place
le cache de fichiers est traître, tout comme le cache mémoire,
et pour la même raison : les accès simultanés.
Comme
vous le savez, PHP dispose de mécanismes de cache basés sur
la fonction flock(). Aussi
tentante que soit cette fonction, elle a ses limitations.
Tout d'abord, c'est un verrouillage collaboratif, ce qui signifie
que les processus qui veulent utiliser un verrou doivent utiliser
flock(). De plus, flock()
ne fonctionne qu'après avoir ouvert le fichier en lecture
ou écriture : ce n'est pas utile si vous avez déjà décidé
de vider le fichier en utilisant l'option "w"
de fopen().
Par conséquent, nous nous retrouvons encore une fois à la
recherche d'une solution. Pour pallier ce problème, nous devons
trouver une solution qui implique l'utilisation d'une fonction
atomique : une fonction qui ne peut être utilisée simultanément
à deux endroits dans le même serveur. Sans les sémaphores,
qui ne sont pas utilisables hors d'Unix, c'est une gageure.
Pourtant, la solution est toute simple : créer un dossier.
Les dossiers se créent avec la commande mkdir(),
et cette opération est atomique, hormis peut-être sur les
volumes NFS, où le verrouillage est un problème récurrent.
Encore une fois, pourquoi placer un cache sur un volume NFS
?
Comme vous le voyez au listing
3, j'ai ajouté deux fonctions à cache_file_get_cached_version()
et cache_file_cache(). Il
s'agit de cache_file_lock(),
qui attend qu'un fichier soit déverrouillé et le verrouille
pour son usage, puis cache_file_unlock(),
qui débloque le fichier précédent. Le fonctionnement est très
simple : cache_file_lock()
crée un dossier dans le même dossier que le fichier de cache,
et ajoute l'extension '.lock'
à son nom, puis appelle mkdir().
Si mkdir() échoue, la fonction
suppose qu'un autre processus a déjà posé un verrou, et elle
va retenter de créer ce dossier jusqu'à ce qu'elle réussisse.
A ce moment, elle considère que le fichier est verrouillé,
et se termine. Son complémentaire, cache_file_unlock(),
efface simplement le dossier, pour que le prochain processus
puisse prendre la suite.
Ce mécanisme est simple et élégant, tout en étant très fonctionnel.
Ce seul problème potentiel réside dans les droits d'accès
: mkdir() ne fait pas la distinction
entre un problème de droits d'accès (droits en écriture du
processus en court), et la présence du dossier. Il faut donc
être prudent et s'assurer que le processus utilisé pourra
écrire dans ce dossier temporaire. Cela ne devrait pas être
un problème.
Hormis cette peccadille, le mécanisme de cache sur le disque
est très clair. En fait, si vous comparez les fonctions cache_disk_*
avec leurs alter ego cache_shm_*,
vous remarquerez que leur structure est identique, mais que
quelques fonctions différents PHP sont utilisées.
Utilisation du cache
Maintenant que toutes les pièces sont en place, voyons enfin
comment implanter notre bibliothèque dans une application.
C'est un scénario d'utilisation que vous rencontrerez facilement,
et pour lequel vous voudrez faire le moins d'efforts.
C'est le cas. Si vous observez le listing
4, vous remarquerez une partie du code qui doit être ajoutée
à la fin de la bibliothèque pour effectuer la mise en cache
automatique. Cela fonctionne en vérifiant si la constante
CACHE_THIS_PAGE a été définie,
et si c'est le cas, la version en cache de la page est émise,
si elle existe, ou bien créée si elle n'existe pas.
Pour s'assurer que vous n'avez absolument rien d'autre à faire
que de définir la constante CACHE_THIS_PAGE
et inclure la bibliothèque de cache, le code du listing
4 utilise ob_start(),
pour s'assurer que le résultat de la page soit envoyé à la
fonction cache_ob_handler().
|
Forum |
|
Réagissez
dans les forums
de JDN Développeurs
|
Et maintenant
L'intérêt de notre bibliothèque de cache est que, malgré le
fait qu'elle n'utilise aucune technique de POO avancée, elle
est très facile à étendre, pour y ajouter d'autres techniques
de cache, comme une base de données. Même dans son état actuel,
elle peut être utilisée pour accélérer un site Web sous forte
charge, et vous donner le temps de traiter les problèmes d'optimisations.
|