Sûreté de fonctionnement
Dans un langage classique, la fiabilité d'un programme est directement liée à l'attention des informaticiens lors de l'écriture et du test de leur programmes. Nous pouvons affirmer qu'aucun programme conséquent n'est exempt d'erreurs qui, un jour ou l'autre, provoqueront un dysfonctionnement. En plus des erreurs propres au programme, il y a :
- Les erreurs des programmes connexes, ne serait-ce que les bases de données ou les systèmes d'exploitation.
- Les pannes matérielles comme un disque ou une mémoire défectueuse.
- Les arrêts brutaux du programme suite à une mauvaise manipulation ou suite à une coupure de courant.
Seuls quelques programmes suffisamment sophistiqués comportent des procédures visant à :
- Contrôler le bon fonctionnement du programme.
- Rattraper au mieux les dysfonctionnements dès qu'ils surviennent.
- Reprendre l'exécution du programme suite à un arrêt brutal sans que cela ait des conséquences sur les données qu'il gère.
Cependant, de nombreuses applications des entreprises sont critiques au point de devoir être disponibles prêt de 100 % du temps. Ceci est pratiquement atteint grâce aux efforts importants des informaticiens.
Afin d'alléger grandement ces efforts consentis et d'offrir à chaque application en technologie Up ! Virtual Technical Machine une sûreté de fonctionnement de prêt de 100 %, Up ! Application System comporte des mécanismes spécifiques qui ne nécessitent aucun codage particulier.
Détection des erreurs à la compilation
Up ! Compiler analyse les fichiers sources Up ! 5GL aussi finement que possible afin de détecter dès la compilation des possibilités de dysfonctionnement. Lorsqu'une erreur certaine est détectée, telle une mauvaise conversion de données, Up ! Compiler la signale et n'enchaîne pas sur la phase de compilation. Lorsqu'une erreur possible est détectée, Up ! Compiler ajoute dans le code généré du code visant à s'assurer que cette situation ne survient pas.
Si le modèle de données comporte des contraintes d'intégrité, ce qui est fortement recommandé, Up ! Compiler ajoute au code généré du code visant à s'assurer que celles-ci ne sont pas violées. Il faut toutefois générer le programme en activant l'option contrainte.
Pour plus de précisions, veuillez vous référer à la fiche La cohérence du programme.
Détection des erreurs à l'exécution
La détection des erreurs à l'exécution provient du code supplémentaire généré par Up ! Compiler pour s'assurer de la cause du programme mais surtout de la robustesse du code de Up ! Virtual Technical Machine :
- Chaque API de Up ! Virtual Technical Machine peut être à priori invoquée avec des paramètres incorrects, que ce soit dans l'identification de la session ou dans l'adressage des objets. Chaque paramètre pouvant occasionner un dysfonctionnement est vérifié avant usage.
Il est possible de renforcer les vérifications effectuées par Up ! Object Management System pour un surcoût modique en temps en activant le paramètre d'exécution verifieradresse.
- Chaque code retour des API natives du système d'exploitation est dûment interprété.
- Les dysfonctionnements non contrôlables au moment de l'exécution d'une API native du système d'exploitation sont rattrapées via le mécanisme des signaux.
Lorsqu'une erreur est détectée par Up ! Virtual Technical Machine, elle est transformée en une exception qui est envoyée à la tâche à l'origine du dysfonctionnement.
De plus, il vous est possible de créer des exceptions applicatives visant à signaler des dysfonctionnements d'ordre fonctionnel. Ceci s'effectue au moyen de l'instruction Exception.
Rattrapage des erreurs d'exécution
Une exception envoyée comporte parmi ses propriétés l'identification du traitement ayant provoqué l'erreur (nom du fichier source, numéro de la ligne, numéro de la colonne), un message d'erreur et un code retour.
Entre chaque partie d'un programme, il est fortement recommandé de rattraper les exceptions au moyen de l'instruction AttraperException et de traiter au mieux ces situations de dysfonctionnement. Dans le pire des cas, si l'exception est renvoyée ou si elle n'est jamais rattrapée par l'application, l'exception est rattrapée par Up ! Virtual Technical Machine et le programme s'arrête en douceur.
Tâche Moniteur
Quand un programme comporte une seule tâche, si un dysfonctionnement survient, le programme s'arrête. Quand un programme comporte plusieurs tâches, si un dysfonctionnement survient à une des tâches, le programme se bloque généralement rapidement pour les raisons suivantes :
- Les autres tâches sont en attente du résultat du travail que devait accomplir la tâche en erreur.
- La tâche en erreur a certainement verrouillé des ressources qui sont partagées par les autres tâches. Il y a alors des interblocages.
Cette situation est encore plus pénalisante lorsqu'elle survient à un serveur travaillant pour de nombreux programmes clients.
Afin de remédier à ces problèmes, il est possible d'activer la tâche Moniteur de Up ! Object Management System dont l'objet est de s'assurer du bon fonctionnement des autres tâches. Cela s'effectue en fixant une période de vérification non nulle au paramètre d'exécution PeriodeMoniteur. Quand une tâche subit un arrêt brutal parce que le dysfonctionnement est suffisamment grave pour qu'il n'y ait pas eu d'arrêt en douceur, la tâche moniteur se substitue à celle-ci et exécute la procédure d'urgence suivante :
- Invalidation de toutes les transactions ouvertes par la tâche en erreur.
- Lâchage des synchronisations posées par la tâche en erreur.
- Libération de toutes les ressources verrouillées par la tâche en erreur.
- Destruction de l'objet représentant la tâche en erreur s'il n'est plus référencé, sinon mis à jour de son code retour et de son état d'activité.
- Clôture de la session rattachée à la tâche en erreur et nettoyage des descripteurs associés.
Si la tâche est relançable automatiquement, alors la tâche Moniteur le fait. Ceci est notamment le cas pour les tâches Alarme, Archive, EnregistrementJournal, FichierEchange, FileDAttente, Retasser, Serveur, Scruptateur et Statistiques.
Journalisation des modifications des entrepôts persistants
Un programme est persistant quand il doit conserver les données qu'ils emploient d'une exécution à l'autre. Ceci est particulièrement le cas pour les serveurs d'objets. Les données sont alors conservées dans des fichiers de persistance correspondant soit aux segments de mémoire du processus soit aux entrepôts.
Afin d'offrir un minimum de performances, Up ! Object Management System utilise au maximum le volume de mémoire Ram qui est attribuée au programme, ceci grâce à son ramasse-miettes. De ce fait, pour les objets les plus récemment modifiés, il y a des différences entre les valeurs de leurs propriétés lues en mémoire ou relues depuis un fichier de persistance.
Sans autre précaution, si un arrêt brutal survient, le programme une fois relancé exploitera des données qui seront corrompues puisque certaines modifications d'objets auront été déposées sur disque et pas d'autres. Ceci est particulièrement dommageable pour les objets transactionnels.
Up ! Object Management System comporte alors un mécanisme optionnel de journalisation des modifications apportées aux objets. Il est activé si le paramètre d'exécution fichierjournal est renseigné. Ce dernier désigne un nom de fichier journal générique. A chaque modification d'un objet, lorsque celle-ci est effective, i.e. lorsque le verrou en écriture est levé, Up ! Object Management System écrit en asynchrone, via la tâche EnregistrementJournal, un enregistrement dans le fichier journal permettant de répercuter la modification en cas d'arrêt brutal. En cas de validation ou d'invalidation d'une transaction, l'écriture est synchrone, i.e. la tâche opération sur la transaction est suspendue tant que l'écriture n'a pas eu lieu.
Up ! Object Management System utilise autant de fichiers journaux que cela est spécifié par le paramètre d'exécution NbFichiersJournaux. Le minimum est de deux fichiers journaux. Un fichier journal est rempli dans la limite de la valeur du paramètre d'exécution maxfichierjournal, exprimée en mégaoctets. Quand un fichier journal est plein, Up ! Object Management System le ferme et passe au suivant. S'il n'y a pas de suivant, il reprend au premier fichier journal.
Périodiquement, selon la valeur du paramètre d'exécution periodesynchronisation, à l'occasion d'un changement de fichier journal ou suite à un appel à la procédure SynchroniserEntrepotsEtFichierJournal, la tâche EnregistrementJournal fait synchroniser le contenu des mémoires cache de chaque entrepôt avec leur fichier de persistance. Cela est réalisé par les tâches FichierEchange si elles existent, sinon cela est directement effectué par la tâche EnregistrementJournal. Pendant ce court moment, aucune tâche ne peut modifier ou consulter un objet.
Archivage des fichiers
Un principe de sûreté de fonctionnement connu de chacun est de réaliser périodiquement une sauvegarde de son travail en gérant des copies de secours.
Up ! Object Management System comporte un mécanisme d'archivage automatique de fichiers intègres sans qu'il soit nécessaire d'arrêter le programme. Ceci est particulièrement important pour les serveurs d'objets devant être disponibles prêt de 100 % du temps.
La tâche Archive est activée si le paramètre d'exécution archiverfichier est renseigné. Ce dernier désigne le nom d'une commande où l'argument NomFichier est un nom de fichier à archiver. A chaque synchronisation entre les mémoires cache de chaque entrepôt avec leur fichier de persistance, Up ! Object Management System utilise cette commande pour archiver dans l'ordre :
- Le fichier de persistance de l'entrepôt Système.
Cet archivage est synchrone.
- Le fichier de persistance des autres entrepôts par ordre de déclaration.
Cet archivage est synchrone.
- Le fichier journal qui vient d'être fermé si la synchronisation a lieu au cours d'un changement de fichier journal.
Cet archivage est asynchrone.
Avant le premier archivage, tous les entrepôts sont basculés dans l'état EntrepotLectureSeule. Une fois son fichier de persistance archivé, l'état de l'entrepôt redevient EntrepotLectureEcriture. Durant cette opération de maintenance, si une tâche nécessite de modifier un objet de cet entrepôt, elle est automatiquement suspendue.
L'entrepôt Système étant le plus critique puisqu'il contient notamment le dictionnaire de données. Il est important que la sauvegarde de son fichier de persistance soit rapide. Il est donc conseillé de ne pas créer un trop grand entrepôt Système.
Procédure de reprise à partir des journaux
Les fichiers journaux ne sont utiles que pour relancer un programme persistant suite à un arrêt brutal.
Si le mécanisme de journalisation des modifications n'est pas activé, il sera possible de le relancer si les fichiers de persistance du programme et des entrepôts sont intègres i.e. s'ils proviennent d'une sauvegarde réalisée suite au dernier arrêt normal du programme.
Dans le pire des cas, il est nécessaire de supprimer les fichiers de persistance, ce qui fait perdre toutes les données.
Si le mécanisme de journalisation des modifications est activé, Up ! Object Management System cherchera à mettre à jour les fichiers de persistance des entrepôts à partir des fichiers journaux en suivant la procédure suivante :
- Identification de la dernière date de synchronisation entre les fichiers de persistance des entrepôts et le journal.
- Recherche du fichier journal possédant la marque de cette synchronisation.
- Répercutions des modifications enregistrées dans le journal.
Les modifications sont répercutées dans le même ordre et dans les mêmes zones mémoires en exploitant chaque enregistrement jusqu'à celui précédant l'arrêt brutal.
- Invalidations de toutes les transactions ouvertes par toutes les tâches actives au moment de l'arrêt brutal.
- Synchronisation des fichiers de persistance du programme et des entrepôts avec le dernier fichier journal.
- Relancement de toutes les tâches relançables automatiquement.
L'exécution du programme se poursuit ensuite normalement.