Home > Software, Software Architecture > Conceptualiser en fonction d’un échec

Conceptualiser en fonction d’un échec

Même si je dois avouer que garder la maison propre n’est pas mon point fort, lorsqu’il est question de conception la structure est de mise. Peut-être justement parce que je sais pertinemment que je vais oublier des tests unitaires et laisser traîner des stubs. Un point central de cette structure est la gestion d’exceptions. Jusqu’ici, cette bonne habitude s’avère payante, puisque les erreurs sont détectées rapidement, sont faciles à comprendre et sont supportés par de bons outils de suivi. Pourtant, une fois en production, ce même avantage peut être catastrophique lorsqu’on n’a pas un contrôle direct sur l’environnement final; le système plante simplement plus souvent! C’est pourquoi, dans certain cas, il est avantageux de conceptualiser en fonction d’un échec.

En fonction d’un échec? Ha! Pourquoi faire des efforts pour qu’un système fonctionne en cas d’échec, si on peut simplement les prévenir avant d’aller en production? Cette question n’est pas dénuée de sens. C’est d’ailleurs une raison d’être des tests unitaires et d’une bonne gestion d’exceptions. Pourtant, certains cas resteront toujours hors de votre contrôle. La connectivité peut tomber, la machine peut s’éteindre, les données peuvent être corrompues, et vos tests unitaires peuvent aussi être sujets d’erreurs. C’est la raison pour laquelle dans plusieurs cas un système devrait être en mesure de se sortir lui-même d’une situation problématique. Voici quelques exemples:

  • Une commande passée dans un système lance une exception lors de l’évaluation des règles de flux de travail. Plutôt que de notifier l’utilisateur de l’erreur, les informations requises pour passer la commande sont gracieusement redirigées à un groupe de support, et l’utilisateur n’est pas impacté.
  • Un courriel de notification ne peut pas être envoyé dans un logiciel de gestion. Le système sauvegarde simplement le courriel dans une queue pour être envoyé plus tard, tout en notifiant l’utilisateur que la réception du courriel pourrait être retardée.
  • Une requête dirigée sur un serveur dans un parc de machines est perdue lorsque ce dernier flanche. La requête est donc simplement ré-exécutée par le distributeur de charge, ne faisant que ralentir un peu la requête de l’utilisateur plutôt que lui lancer une erreur inutile.

La règle générale est que l’utilisateur ne doit pas répéter une même séquence de travail à cause d’une erreur du système. Pour éviter de créer de nouvelles faiblesses, il est conseillé de:

  • Prévoir un mécanisme évitant les boucles infinies lorsqu’une tâche erronée est ré-exécutée
  • Prévoir un outillage de suivi efficace; les erreurs cachées doivent tout de même être réglées
  • Valider les informations reçues dans tous les nœuds de communication. Quoique cette pratique soit toujours conseillée, dans ce cas elle prend une importance primordiale puisque chaque module peut modifier son comportement en cas d’erreur, et ainsi donner des informations invalides.

On doit tenter de minimiser, dans la mesure du possible, le nombre de points individuels de défaillance. Ces points sont les endroits où une erreur impliquera la défaillance complète d’un système. Dans la plupart des projets web, ces points sont plus rares; on cherchera donc surtout les points de défaillance d’une requête.

Certaines approches simples peuvent faciliter la capacité d’un système à fonctionner même si un ou plusieurs de ses éléments cessent temporairement de fonctionner. En voici quelques exemples:

  • Lorsqu’une tâche logicielle sort du contexte de l’utilisateur, conserver les informations requises pour reproduire la requête
  • Réduire la validation à la sauvegarde, et écrire des outils de recouvrement pour automatiquement corriger les erreurs
  • Offrir des solutions logicielles de rechange lorsque possible; par exemple, si la cache ne fonctionne pas, charger directement de la base de données
  • Offrir des solutions utilisateur de rechange lorsque possible; par exemple, offrir de passer la commande par courriel si le système est incapable de la sauvegarder

Le site d’eBay offre un excellent exemple de ce type d’application. Je vous conseille la lecture du document The eBay Architecture; celui-ci est simplement rédigé et reste de très haut niveau. Aussi, une courte entrevue sur le site ACM Queue, effectuée par Steve Bourne avec Bruce Lindsay, explique bien l’idée derrière ce type de conception.

Je n’ai pas eu l’occasion de voir beaucoup de systèmes résistants aux échecs. La plupart du temps, soient ils plantent aussitôt qu’une information n’est pas conforme (mon approche la plus commune), ou ils laissent passer les erreurs sans toutefois les gérer (dans ces cas j’ai les poils qui hérissent). Avec la popularité grandissante des services et de la complexité exponentielle des systèmes interconnectés, il y a de fortes chances pour qu’on trouve de plus en plus de systèmes intelligents capables de se débrouiller, même dans les situations les plus embrouillées!

  1. June 27, 2007 at 22:54

    Bravo! Tu as une capacité de synthèse remarquable. Combiné d’une générosité certaine d’en faire profiter la communauté ! Un monde fascinant.

  2. May 4, 2009 at 17:15

    Merci, j’apprécie grandement!

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: