“Dynamic fault handling mechanisms for service-oriented applications” Fabrizio Montesi, Claudio Guidi, Ivan Lanese and Gianluigi Zavattaro Department of Computer Science, University of Bologna
“Dynamic fault handling mechanisms for service-oriented applications” Fabrizio Montesi, Claudio Guidi, Ivan Lanese and Gianluigi Zavattaro
Department of Computer Science,University of Bologna
Introduction
• Service oriented applications are usually distributed
• Orchestrators rely upon a workflow programming approach (e.g. WS-BPEL)
• Faults can be propagated within a system by involving several services
• Basic mechanisms: fault, termination and compensation handling.
• Static approach used so far, but some difficulties exists in some scenarios
Key Concepts (1)
• A scope is a process container able to manage faults
• A fault is a signal raised by a process towards the enclosing scope
• Termination is automatically triggered when a running scope must be smootlhy stopped because of a fault thrown by a parallel process
• Compensation is invoked to undo the effects of a scope whose execution has already successfully completed.
• Recovering mechanisms are implemented by exploiting handlers
Key concepts (2)
Scope A
Scope B Scope C
FH
TH
CH
P
A process P is in parallel with scope B and C
Fault handlersTermination handlersCompensation handlers
f
Process P raises fault f
Q R
Scope C finishes with success
C
Compensation handler of scope C ispromoted to the parent scope
Scope B, which is still running, terminates its activities
When all the child scopes have been termintated,
the fault handler of scope A is executed
Fault f
Compensation handlers can be invoked within
a fault handler
The static approach
• Usually error recovery is managed by statically associating handlers to scopes
scopeq( P , FH , TH , CH )
• Example: parallel composition between R and scope q where the compensation policy for q requires to compensate the activities executed so far in a reversed order.
scopeq( i=0;while( i<100 ){
i=i+1;if (i%2=0) then P else Q
}, FH, TH, CH)
R |
i=50i=51f
In this paper…
• We present a new approach for dealing with fault mechanisms: the dynamic approach
• The formal model has been presented in a previous paper. It is an extension of SOCK calculus
• We have implemented such a formal model within JOLIE. JOLIE is the actual implementation of SOCK
The formal model: SOCK• SOCK is formal calculus for modelling Service Oriented Computing systems developed at the University of Bologna
• Three layers:
• service behaviour layer
• service engine layer
• services system layer
• It supports the RequestResponse communication pattern
• In a previous work, we have modelled fault handling mechanisms by exploiting a dynamic approach.
"On the Interplay Between Fault Handling and Request-Response“ Claudio Guidi, Ivan Lanese, Fabrizio Montesi and Gianluigi Zavattaro
ACSD 2008. pages 190-199, IEEE Computer Society,
2008.
• Jolie is the implementation of SOCK
• It is an open-source project http://jolie.sourceforge.net/
• It is developed in Java
• It is a complete programming language
• It supplies a new programming paradigm which is the service oriented one
• In Jolie everything is a service
• It supports programming primitives for managing XML data
• Service embedding and redirection
The dynamic approach
• The basic idea of the dynamic approach is that handlers can be updated while computation progresses
scopeq( P , H )
where H is a function which associates fault names to fault handlers and scope names to termination and compensation handlers
• Dynamic handling installation is addressed by two specific primitives:
• inst(H’):updates the current handler function with H’
• cH : refers to the previous installed handlers
Updating handlers
The install primitive updates the current handler for the specified fault or scope name
main{ scope( myScope ) { install( f => println@Console("Fault Handler for f")); println@Console("--Executed line 1"); install( f => println@Console("Fault Handler updated for f")); println@Console("--Executed line 2"); install( f => cH; println@Console("Added handler")); println@Console("--Executed line 3"); throw( f ) }}
f => println@Console("Fault Handler for f")f =>f => println@Console("Fault Handler updated for f")f => println@Console("Fault Handler updated for f"); println@Console(“Added handler")
Execution priority for install primitive
The install primitive is executed with priority w.r.t.
fault processingmain{ install( myFault => HANDLER FOR myFault );
scope( myScope ) { install( this => println@Console("Fault Handler for f")); println@Console("--Executed line 1"); install( this => println@Console("Fault Handler updated for f")); println@Console("--Executed line 2"); install( this => cH; println@Console("Added handler")); println@Console("--Executed line 3") } | scope( faultScope ) { throw( myFault ) }}
f
Termination
Termination is always propagated to sibling and child scopes, and it is always completed before
the enclosing scope processes the fault handler
main{ install( f => FAULT HANDLER FOR f ); scope( myScope ) { install( this => HANDLER FOR myScope ); println@Console(...); ... scope( childScope ) { install( this => HANDLER FOR childScope ); ... } } | throw( f )}
f
CompensationA compensation handler is a termination
handler promoted to the parent scope when the child scope finishes successfully.
A compensation handler can be activated by means of a specific primitive which can only be
used within a handler.main{ install( f => FAULT HANDLER FOR f; comp( myScope ) ); scope( myScope ) { install( this => HANDLER FOR myScope; comp( chScope ); println@Console(...); ... scope( chScope ) { install( this => HANDLER FOR childScope ); ... } } ; throw( f )}
chScope
myScope
From static to dynamic
• Static approach can be trivially simulated with the dynamic one:
scopeq( P , FH , TH , CH )
scopeq(inst(f=>FH);inst(this=>TH);P;inst(this=>CH),H)
• We can rewrite the previous example as it follows:
scopeq( i=0;while( i<100 ){
i=i+1;if (i%2=0) then
{P;inst(this=>P’;cH)} else
{Q;inst(this=>Q’;cH)}}
)
R |
scopeq( i=0;while( i<100 ){
i=i+1;if (i%2=0) then P else Q
}, FH, TH, CH)
Request-Response communication pattern
• Jolie supports the RequestResponse communication pattern which is inspired by the Request-Response and Solicit-Response operations of WSDL 1.1
• In a RequestResponse operation a message is received and, after a body process is executed a response is sent to the invoker.
• Jolie supplies two specific primitives for receiving and sending messages on a RR
• op_name( request )( response ){ body_process }
• op_name@TargetService( request )( response )
Faults in the Request-Response pattern
• Fault management within a RequestResponse pattern is an interesting issue:
• What happen when a fault is raised within the RR?
• What happen when a fault is raised by a process on the SR side?
SR RR
P
Behaviour without faults
Faults in the Request-Response pattern (2)
• What happen when a fault is raised within the RR?
• In this case, a fault message is automatically sent to the sending primitive of the invoker
SR RR
P
Behaviour without faults
Faults in the Request-Response pattern (3)
• What happen when a fault is raised by a process on the SR side?
• In this case, the sending primitive (SR) always waits for the incoming response before the fault is handled by the service
SR RR
P
Behaviour without faults
Demo: the automotive example
• It describes the scenario where a car failure occurs. The car requests for an orchestrator to the assistance service in order to search for garage, car rental and truck services.
• In case the failure is about a tyre replacement, the orchestrator will look for a garage service which can send someone to the car for replacing the tyre.
• In case the failure is about the engine, the orchestrator will look for a garage and for a truck for carrying the car to the garage. Concurrently, it will look for a rental car service in order to find another car to use. The rent car will be sent to the garage coordinates if found, to the faulted car coordinates otherwise.
Demo: the automotive example (2)
• The engine failure:
Assistance
Car
RegisterGarages
21
3
Rental
21
3
Truck
21
3Banks
AE Visa
12
3
4
5
6
7
8
mySQL
9
Something to know about Jolie…
• In Jolie everything is a service
• Services can be embedded, both statically and dynamically, within another service
• Services can be passed from a service to another through message exchange and then embedded at run-time: service mobility
• Jolie exploits the programming power of Java. It is possible to create services developed in Java which can be easily embedded within a Jolie service: JavaServices
Conclusions
• In Jolie we have implemented the dynamic fault mechanisms formally developed in our previous work
• the dynamic approach is based upon the install primitive for updating handlers
• the install primitive must be executed with priority w.r.t. fault mamagement
• RequestResponse communication pattern has been enhanced with automatic fault communication
• As a future work we intend to formalize fault mechanisms in our choreography calculus and then implement it
Thank you!
Questions?