We report below the code of the AIOCJ choreography where a rule introduces a new role (logger
) in the adapted scope.
preamble { starter: client } aioc { product@client = getInput( "Insert product name" ); request: client( product ) -> seller ( order ); scope @seller{ // process the order and compute result, here XXX result@seller = "XXX"; response: seller( result ) -> client( result ) } }
rule { include log from "socket://localhost:8002" with "jsonrpc" include getTime from "socket://localhost:8003" with "jsonrpc" newRoles: logger on { N.apply != false } // applicability conditions, irrelevant in this example do{ log: seller( order ) -> logger( entry ); { time@logger = getTime(); _@logger = log( time + ": " + entry ) } | { result@seller = "XXX"; response: seller( result ) -> client ( result ) } } }
// scope adaptation synchronisation procedure var5.sid = "3dd7e775-7006-4a96-b07f-cfa920183575"; var5.rolesNum = 2; var5.hasAck = true; Leader.location = "socket://localhost:10501/"; initStartProcedure@Leader( var5 ); undef( var5.rolesNum ); undef( var5.hasAck ); startSR.name = "execute"; acquire@SemaphoreUtils( startSR )( ); joinStart@Leader( var5 )( ); aReq.client = "socket://localhost:10501/"; aReq.ports.seller.address = "socket://localhost:10501/"; aReq.ports.client.address = "socket://localhost:10500/"; // adaptation request checkForUpdate@AdaptationManager( aReq )( aRes ); // if adaptation is required if ( is_defined( aRes ) ) { for ( c = 0, c < #aRes.roles.seller.code, c++ ){ embed_scope@ActivityManager( aRes.roles.seller.code[ c ] )( ) }; var4.sid = adaptRequest.main_key = aRes.main_key; foreach ( r : aRes.roles ){ var4.rolesNum++ }; var4.hasAck = true; initStartProcedure@Leader( var4 ); var4.sid = "3dd7e775-7006-4a96-b07f-cfa920183575_adapt"; undef( var4.hasAck ); initStartProcedure@Leader( var4 ); undef( var4.rolesNum ); undef( aRes.roles.seller ); // distribute the adaptation code to all participants (roles) ... foreach ( roleName : aRes.roles ){ if ( is_defined( aRes.roles.( roleName ).cookie ) ) { adaptRequest.cookie = aRes.roles.( roleName ).cookie; LedRole.location = aRes.roles.( roleName ).location; op0.msgID = adaptRequest.cookie; op0.content.sid = "3dd7e775-7006-4a96-b07f-cfa920183575_adapt"; op0.content.leader = Leader.location; coord@LedRole( op0 )( ) } else { adaptRequest.cookie = "3dd7e775-7006-4a96-b07f-cfa920183575"; LedRole.location = aRes.roles.( roleName ).location + "!/Activity/3dd7e775-7006-4a96-b07f-cfa920183575" }; adaptRequest.code << aRes.roles.( roleName ).code; adapt@LedRole( adaptRequest )( ); undef( adaptRequest.code ) }; joinStart@Leader( var4 )( ); // ... and execute your own run@ActivityManager( aRes.main_key )( ) } else { // no adaptation, execute original code eReq.cookie = "3dd7e775-7006-4a96-b07f-cfa920183575"; noAdapt@client( eReq ); var0 = "XXX"; var1.value = var0; var1 = "result"; set@State( var1 )( ); get@State( "result" )( var3 ); _tmp = var3; var2.content = _tmp; var2.msgID = "973caa7c-0bc9-4f5e-8455-eb3047ced1bd"; response@client( var2 )( ) }; // scope execution terminated, returning to the parent choreography var6.sid = "3dd7e775-7006-4a96-b07f-cfa920183575"; joinAck@Leader( var6 )( ); startActivity@ActivityManager( "3dd7e775-7006-4a96-b07f-cfa920183575" ); startSR.name = "done"; release@SemaphoreUtils( startSR )( )
// gets the entry log from the seller var0.msgID = "9751af6e-277a-47ad-b272-f6b6f904ed2e"; get_log@MH( var0 )( var0 ); var1 = var0.content; var2.value = var1; var2 = "entry"; set@State( var2 )( ); { // contacts the getTime service getTime@Port1( var3 )( var4 ); var5.value = var4; var5 = "time"; set@State( var5 )( ); // prepare the message to the logger service get@State( "entry" )( var6 ); get@State( "time" )( var7 ); var8.p[0] = var7 + ": " + var6; // send the message to the logger service log@Port0( var8 )( var9 ); var10.value = var9; var10 = "_"; set@State( var10 )( ) }