// Un client ripetutamente chiama un server ed aspetta la risposta. // VERSIONE SINCRONA DELLE COMUNICAZIONI con failures // VERSIONE SEQUENZIALE DEL CLIENT /SERVER Class Token is Class Server1 is Operations: WS_Request:Token; State top = s3 Transitions s3 -> s3 { WS_Request / return REQ_OK} s3 -> s3 { WS_Request / return REQ_FAIL } // Server Unreachable end; Class Server2 is Signals: doit Operations: WS_Request:Token; Vars: calling: Client; State top = s3, s4 Defers WS_Request Transitions s3 -> s3 { WS_Request / return REQ_FAIL } // Server Unreachable s3 -> s4 { WS_Request / calling := _caller; self.doit; } // elab request s4 -> s3 { doit / calling.return(REQ_OK); calling :=null} // return result s4 -> s3 { doit / calling.return(REQ_FAIL); calling:=null} // Client unreachable -- doit needed in UML because completion transitions cannot be nondeterministic end; // In entrambi i casi le call dei clients vengono servite sequenzialmente, // nel secondo caso l'attivita' puo' non essere atomica e richiedere // altre interazioni con altri server con altri server Class Client is Vars: myserver: obj; State top = s1 , s2 Transitions s1 -> s1 { - /result: Token; result = myserver.WS_Request } // synchr. call end; Object C1 : Client (myserver -> S1); Object S1: Server1; Object S2: Server2; Object REQ_OK : Token; Object REQ_FAIL : Token; // Le failures delle comunicazioni (Server Unreachable) viene // modellato come un risultato esplicito di "FAIL" di una request // Cioe' come se il server rispondesse con un errore, anche quando // in realta' non risponde proprio (causando un timeout sul client). //Dal punto di vista del client la cosa e' equivalente (errore da timeout o //errore da fail esplicito). Analogamente dal punto di vista dal server (non ricevere una //call == ricevere una call e rispondere con un fail explicita). // SEMMAI puo' essere causa di problemi il caso in cui la communication failure // avvenga durante la risposta sincrona del server. // In questo caso COSA DOVREBBE SUCCEDERE????? // Sul client scade il timeout ... OK e sul server??' dovrebbe poter restituire // REQ_FAIL anche dopp aver servito la richiesta per modellare la fail del return. // In questo modellino banale in cui la attivita' del server non esiste, il problema // non e' osservabile. // COME alternativa e' possibile modellare una call sincrona come una coppia si // di segnali request/response asincroni /REQ_OK uniti al modello esplicito // dei timeout e di un mezzo di comunicazione che puo' perdere messaggi. Abstractions { Action $1 -> $1 }