Langage P
Les systèmes distribués présentent des défis majeurs lors de leur mise en place en raison de
la complexité de la programmation et de la nécessité de garantir l'exactitude malgré divers
scénarios d'interactions et de défaillances. Les équipes de service découvrent souvent des
erreurs après le déploiement. Pour relever ce défi, le langage de programmation P a été
développé, basé sur une approche de machine à états pour modéliser formellement des
systèmes distribués. P permet aux programmeurs de représenter la conception de leur
système comme un ensemble de machines à états communicantes. Il offre divers moteurs
d'analyse pour vérifier que le système distribué satisfait aux spécifications d'exactitude. La
modélisation formelle avec P vise à détecter les bugs critiques à un stade précoce,
améliorant ainsi la fiabilité des systèmes distribués.
Exemple serveur-client
3dossier :
1)spec=>1seule fichier :2specification
2) src=>client
=>serveur
=>cleintserveur
=>AbstractBackServer
3)test
Système bancaire
Contenu de p-spec =>
Résumé de la spécification BankBalanceIsAlwaysCorrect :
Objectif : Cette spécification vise à garantir que le solde du compte communiqué au client
par la banque est toujours correct, et qu'il n'y a aucune erreur du côté de la banque dans la
logique de retrait.
Fonctionnement :
Initialisation : L'état initial (Init) prend en charge l'événement d'initialisation et initialise les
soldes des comptes.
Attente des demandes et des réponses de retrait : L'état WaitForWithDrawReqAndResp gère
les événements de demande de retrait (eWithDrawReq) et de réponse de retrait
(eWithDrawResp).
Suivi des soldes et des demandes en attente : Lorsqu'une demande de retrait est reçue, elle
est ajoutée à une liste de demandes en attente. Lorsqu'une réponse de retrait est reçue, la
spécification vérifie que le nouveau solde du compte est correct. Si le retrait échoue, il
s'assure que cela est dû à une politique de la banque empêchant les soldes inférieurs à 10.
Résumé de la spécification GuaranteedWithDrawProgress :
Objectif : Cette spécification s'assure que toutes les demandes de retrait soumises par le
client obtiennent une réponse de la banque à un moment donné.
Fonctionnement :
Aucune demande en attente : L'état initial (NopendingRequests) gère l'événement de
demande de retrait (eWithDrawReq) en ajoutant la demande à une liste de demandes en
attente.
Demandes en attente : L'état actif (PendingReqs) gère les événements de réponse de retrait
(eWithDrawResp) en s'assurant que les réponses correspondent aux demandes en attente. Si
toutes les demandes ont reçu une réponse, le système retourne à l'état initial.
Conclusion : En combinant les deux spécifications, on garantit que le solde du compte est
toujours correct, que les demandes de retrait réussiront si elles sont autorisées, et que
toutes les demandes de retrait obtiendront une réponse. Cela assure un comportement sûr
et dynamique du système bancaire.
L'interaction entre le client et le serveur dans ces codes se déroule comme suit :
1)Initialisation du système :
La machine BankServer est initiée avec un solde initial de tous les comptes. Elle crée
également une instance de la machine Database pour stocker les soldes des comptes.
La machine Database est initiée avec la référence vers la machine BankServer et les soldes
initiaux des comptes.
2)Demande de retrait du client (Client) :
Lorsque le client souhaite effectuer un retrait, il envoie un événement eWithDrawReq au
serveur bancaire avec les détails de la demande (compte, montant, etc.).
3)Réception de la demande de retrait par le serveur (BankServer) :
Le serveur, dans l'état WaitForWithdrawRequests, reçoit l'événement eWithDrawReq.
Il lit le solde actuel du compte depuis la base de données en utilisant la fonction
ReadBankBalance.
S'il y a suffisamment d'argent sur le compte après le retrait, il met à jour le solde dans la base
de données avec la nouvelle valeur après le retrait, et envoie une réponse positive
(WITHDRAW_SUCCESS) au client avec le nouveau solde.
Si le solde n'est pas suffisant, il envoie une réponse négative (WITHDRAW_ERROR) au client
avec le solde actuel.
4)Traitement de la réponse par le client (Client) :
Le client reçoit l'événement eWithDrawResp du serveur avec la réponse à sa demande de
retrait.
Il vérifie si le retrait a réussi ou échoué en examinant le statut de la réponse
(WITHDRAW_SUCCESS ou WITHDRAW_ERROR).
En cas de succès, il met à jour son solde local avec le nouveau solde reçu dans la réponse.
En cas d'échec, il vérifie que son solde local n'a pas changé.
5)Fonctions auxiliaires (ReadBankBalance et UpdateBankBalance) :
La fonction ReadBankBalance permet au serveur de demander à la base de données le solde
actuel associé à un compte donné.
La fonction UpdateBankBalance permet au serveur de mettre à jour le solde d'un compte
dans la base de données avec une nouvelle valeur.
En résumé, le client envoie des demandes de retrait au serveur, le serveur vérifie la validité
de la demande en interrogeant la base de données, met à jour la base de données en cas de
retrait réussi, et envoie une réponse au client. Les fonctions de la base de donnée
permettent au serveur d'interagir avec la base de données pour lire et mettre à jour les
soldes des comptes.
Contenu de fichier serveurclient
Ce code définit trois modules : Client, Bank, et AbstractBank. Voici une vue d'ensemble de
l'interaction entre ces modules :
Client (Client) :
La machine Client représente le comportement d'un client dans le système bancaire.
Le client interagit avec le serveur en envoyant des demandes de retrait (eWithDrawReq) et
en recevant des réponses de retrait (eWithDrawResp).
Le client utilise les fonctionnalités de la machine BankServer pour traiter les demandes de
retrait.
Banque (Bank) :
La machine BankServer représente le serveur bancaire qui gère les demandes de retrait des
clients.
Il communique avec la base de données (Database) pour lire et mettre à jour les soldes des
comptes.
Lorsqu'il reçoit une demande de retrait (eWithDrawReq), il utilise la base de données pour
vérifier la validité de la demande et envoie une réponse appropriée au client.
Base de données (Database) :
La machine Database agit comme un service auxiliaire pour le serveur bancaire.
Elle stocke les soldes des comptes et offre des fonctions (ReadBankBalance et
UpdateBankBalance) permettant au serveur de lire et mettre à jour les soldes des comptes.
Module Banque Abstraite (AbstractBank) :
Le module AbstractBank définit une interface abstraite (AbstractBankServer) pour le serveur
bancaire.
Il propose une transition de l'abstraction (AbstractBankServer) vers la réalité (BankServer),
représentant la concrétisation de cette abstraction.
Interaction entre les modules :
Le client interagit avec le serveur bancaire en envoyant des demandes de retrait
(eWithDrawReq) et en recevant des réponses de retrait (eWithDrawResp).
Le serveur bancaire utilise les fonctionnalités de la base de données pour lire et mettre à jour
les soldes des comptes.
Le module AbstractBank offre une abstraction du serveur bancaire, permettant une
transition vers une implémentation concrète (BankServer).
L'ensemble des modules forme un système où le client communique avec le serveur
bancaire, et ce dernier utilise la base de données pour gérer les opérations bancaires. La
notion d'abstraction (AbstractBank) suggère une flexibilité dans le choix de l'implémentation
concrète du serveur bancaire.
Résumé global du code :
1. Module Client :
Représente le comportement du client dans le système bancaire.
Envoie des demandes de retrait (eWithDrawReq) au serveur bancaire et
reçoit des réponses (eWithDrawResp).
2. Module Bank :
Comprend la machine BankServer qui gère les demandes de retrait des clients
en interagissant avec la base de données.
Comprend la machine Database qui agit comme un service auxiliaire pour
stocker les soldes des comptes.
3. Module AbstractBank :
Définit l'interface abstraite (AbstractBankServer) pour le serveur bancaire.
Propose une transition de l'abstraction (AbstractBankServer) vers la réalité
(BankServer).
4. Module AbstractBankServer :
Fournit une implémentation abstraite du serveur bancaire.
Masque l'interaction avec la base de données en stockant les informations
localement.
Traite les demandes de retrait et envoie des réponses au client.
« Normalement, dans un contexte plus complexe, un serveur bancaire pourrait
interagir avec une base de données externe pour stocker et récupérer des
informations de compte.
Cependant, dans cet exemple, l'implémentation est simplifiée. Au lieu de réellement
interagir avec une base de données externe, le serveur bancaire stocke les soldes
localement dans la variable balance.
En résumé, l'abstraction ici permet de représenter le comportement d'un serveur
bancaire de manière simplifiée, masquant les détails spécifiques de l'interaction avec
la base de données. Cela offre une flexibilité dans le choix d'une implémentation
concrète tout en maintenant une interface cohérente pour le client. »