Thursday, January 2, 2014

Programming Service Oriented Recursion

Recursion in service oriented architectures is something unusual because it seems to be useless. So, why a post about recursion in SOA? I think the big result we can obtain from service oriented recursion is understanding service oriented programming paradigm nature and technologies. Recursion indeed, is a well known programming pattern hugely adopted by all the programmers in the world and its usage could reveal us some interesting features about a programming language. So, I want to use recursion in a SOA because I want to know more about SOA. Let's do it.

In the following example you can find the implementation of Fibonacci with Jolie.
[ You can copy it into a file and save it with name fibonacci.ol. Then run it typing the command
jolie fibonacci.ol ]


include "console.iol"
include "runtime.iol"

execution{ concurrent }

interface FibonacciInterface {
  RequestResponse:
    fibonacci( int )( int )
}

outputPort MySelf {
  Location: "socket://localhost:8000"
  Protocol: sodep
  Interfaces: FibonacciInterface
}


inputPort FibonacciService {
  Location: "socket://localhost:8000"
  Protocol: sodep
  Interfaces: FibonacciInterface
}

main
{
  fibonacci( n )( response ) {
    if ( n < 2 ) {
      response = n
    } else {
      {
fibonacci@MySelf( n - 1 )( resp1 )
|
fibonacci@MySelf( n - 2 )( resp2 )
      };
      response = resp1 + resp2
    }
  }
}




The code is very intuitive and simple. The outputPort MySelf defines the external endpoint to be invoked which corresponds to the input endpoint FibonacciService where the operation fibonacci is deployed. The invocations are performed in parallel (operator |) and they are blocking activities which wait until they receive a response from the invoked service
. You can invoke it by simply exploiting the following client which sends 10 as input parameter:

include "console.iol"

interface me {
  RequestResponse:
    fibonacci( int )( int )
}

outputPort Service {
  Location: "socket://localhost:8000"
  Protocol: sodep
  Interfaces: me
}

main
{
  fibonacci@Service( 10 )( result );
  println@Console( result )()
}

Starting from this simple example we can understand some interesting features:

server sessions represent recursive call stack layers: each invocation opens a new session on the server which represents a new layer in the recursive call stack.

loosely coupling: each invocation is separated from the others which guarantees that the value of n is not overwritten by different calls.

runtime outputPort binding: the binding of the output endpoint (MySelf)  must be achieved at runtime and not at deploy time in order to avoid frustrating programming issues like those reported here:  http://blogs.bpel-people.com/2007/02/writing-recursive-bpel-process.html.

the invocation stack could be distributed: you can imagine to deploy more than one fibonacci service and switch the invocations from one to another depending on some inner parameter such as, for example, the number of the open sessions. As an example consider the code modified as it follows:

init {
  getLocalLocation@Runtime()( global.location );
  MySelf.location = global.location;
  println@Console( MySelf.location )();
  global.count = 0
}

main
{
  fibonacci( n )( response ) {
    synchronized( lock ) {
      global.count ++;
      println@Console( "begin n="+n )();
      if ( global.count >= 100 ) {
MySelf.location  = "socket://localhost:8001"
      }
    };
    if ( n < 2 ) {
      response = n
    } else {
      {
fibonacci@MySelf( n - 1 )( resp1 ) 

fibonacci@MySelf( n - 2 )( resp2 )
      };
      response = resp1 + resp2;
      synchronized( lock ) {
global.count --;
println@Console( "end n="+n )();
if ( global.count < 100 ) {
 MySelf.location  = global.location
}
      }
    }
  }
}

Here the location of the outputPort MySelf can be changed dynamically during the execution. global.count stored the number of the current open sessions, if it is greater than 100 the location is changed into socket://localhost:8001 where the second fibonacci service is deployed. In this way you can easily create a chain of Fibonacci services whose sessions participate to a unique Fibonacci number recursive calculation.


Conclusions
Here I used service oriented recursion for programming a Fibonacci service with Jolie which can be invoked by external clients. This service could be also chained with other copies of it in order to obtain a distributed SOA for calulating the Fibonacci number recursively. Such an example could be an interesting reference point for understanding how service creation and invocations work in a SOA.


No comments:

Post a Comment

Please, enter here your feedback: