Execution Engine

From Gcube Wiki
Revision as of 10:46, 12 February 2010 by Giorgos.papanikos (Talk | contribs) (Java Object)

Jump to: navigation, search

Execution Plan

For a client of the ExecutionEngine to be able to formally describe the plan that he wants to execute, the constructs offered by the Execution Plan are used. These constructs have the following main pillars.

  • Configuration
    Every plan is potentially one execution unit for the execution engine. Each plan while executing can request different parametrization.
  • Variables
    Tha variables defined in a plan are the common data placeholders through which the elements of the plan exchange data.
    • Data Types
      Each variable is typed and this type describes the different characteristics of the data exchanged.
    • Parameters
      Each variable is accessed through defined parameters. Parameters are distinguished by their direction and processing.
      • Filters
        Each parameter can provide either direct access to its underlying data or perform a number of elaborate filtering tasks before retrieving or storing data to its underlying Parameter and Data Type
  • Execution Tree
    The plan hierarchy is composed of a number of elements that control the flow and the actions of the plan

Execution Events

Every plan created and executed, follows a life cycle which in every point is updated and reported to the client through the use of events. These events follow the Observer / Observable pattern and the defined events that are emitted during the execution life cycle are:

  • Execution Started
    Event emitted when the execution is initiated
  • Execution Completed
    Event emitted when the execution is completed either successfully or not
  • Execution Paused
    Event emitted when the execution is paused by the client
  • Execution Resumed
    Event emitted when the execution is resumed after being paused by the client
  • Execution Canceled
    Event emitted when the execution is canceled by the client
  • Progress Report
    Event emitted from internal Plan Elements reporting on the progress of their execution
  • External Progress Report
    Event emitted from external invokable which has been invoked by one of Java Object and Web Service reporting on the progress of their execution. This is only feasible if the invoked Java object or Web Service is declared and implemented to use an Execution Context.
  • Performance Report
    Event emitted from internal Plan Elements reporting timing andf performance statistics on their operation

The Progress Report and Performance Report events can be requested to be omitted if the client requests using the Plan Configuration

Execution Context

The Execution Engine from the time it receives an Execution Plan and starts execution it, it creates a context within which the whole execution takes place. This context enables monitoring of the execution tree, event propagation and management. Since the execution may have to be moved to multiple execution containers through Boundary Elements this context remains synchronized across multiple hosts through control Channels. Every partial execution instance initialized in every execution container acts as the original context for the specific container, and through the control Channel synchronizes its state with the ones it is paired with.

This scheme works well for the Plan Elements that operate in the context of the engine. But since the context is an internal to the engine structure, it cannot be used by external components such as Java Objects and Web Services invoked through Java Object and Web Service elements respectively. To cover this gap and to allow for external component to offer a more integrated with the engine service, Java Objects and Web Services may also ,with the trade off of being coupled with the execution engine at compile time, receive an execution context construct. Through this they can emit progress events, be notified for execution life cycle, as well as receive parametrized values that they may need during their operation and can be better initialized externally.

For Java objects, which are initialized in the same address space as the one the engine that invokes it, the context kept by the engine is wrapped and passed to it. For Web Services, a new control Channel is initialized in the caller side, an identifier to it is created and passed with the SOAP envelop header with the call made. In the Web Service side, the execution engine provides utilities to retrieve the SOAP envelop piggy bagged information, instantiate en execution context construct, which from then one takes care of synchronizing it self with the caller side.

Contingency Triggers

Given the distributed nature of the environment the execution engine operates on, as well as the level of expressiveness the execution plan was designed to provide, another construct offered by the engine is the ability to define reactions in cases of specific errors. Different Plan Elements support different levels of contingency reactions, while others do not support them at all. To define a contingency reaction one must first define the trigger that will enable the reaction. This trigger is an exception that may be raised by the invoked component. Once the exception is caught, if a reaction is defined that can be triggered by the caught event, it takes over and handles the error. A number of reactions can be defined to be set by different triggers. The currently available reactions to such a trigger are listed below:

XML definition

<contingency error="error name" isFullName="true/false">
  <reaction type="None"/>
</contingency>
...
<contingency error="error name" isFullName="true/false">
  <reaction type="Retry" retries="..." interval="..." />
</contingency>
...
<contingency error="error name" isFullName="true/false">
  <reaction type="Pick" exchaust="true/false">
    <pick>...</pick>
    <pick>...</pick>
    ...
    <retrieve>...</retrieve>
  </reaction>
</contingency>

Invokable Profile

Every external to the Execution Engine callable object that can take part in an Execution Plan and invoked during execution needs to be describes so that the Execution Engine's clients can find all the information needed to construct the respective Plan Elements that will describe this callables, namely Shell scripts, Java objects and Web Services.

This information is detailed in an XML document that each of these callables expose and has the following form for each of these items

Java Object

As a concrete example, lets assume we want to profile the following class

public class Calculator implements IExecutionContextEnabled {
	private int salt = 0;
	private IExecutionContext Context = null;
 
	public Calculator(){}
	public Calculator(int salt) {this.salt = salt;}
	public static int GetProposedSalt(){return 10;}
	public int add(int []parts) {
		int count=0;
		for(int i=0;i<parts.length;i+=1) {count+=parts[i];}
		return count;
	}
	public int add(int [][][]parts) {
		int count=0;
		for(int i=0;i<parts.length;i+=1) { for(int q=0;q<parts[i].length;q+=1) { count+=this.add(parts[i][q]); } }
		return count;
	}
	public int[] add(int [][]parts) {
		int []res=new int[parts.length];
		for(int i=0;i<parts.length;i+=1) {
			int count=0;
			for(int q=0;q<parts[i].length;q+=1) { count+=parts[i][q]; }
			res[i]=count;
		}
		return res;
	}
	public int add(CalculatorHolder []holders) {
		int count=0;
		for(int i=0;i<holders.length;i+=1) { count+=(holders[i].X+holders[i].Y); }
		return count;
	}
	public CalculatorHolder[] add(CalculatorHolder [][]holders) {
		CalculatorHolder []res=new CalculatorHolder[holders.length];
		for(int i=0;i<holders.length;i+=1)
		{
			int count=0;
			for(int q=0;q<holders[i].length;q+=1){ count+=(holders[i][q].X+holders[i][q].Y); }
			res[i]=new CalculatorHolder();
			res[i].Result=count;
		}
		return res;
	}
	public CalculatorHolder[][] random() {
		CalculatorHolder[][] ret=new CalculatorHolder[3][3];
		ret[0][0]=new CalculatorHolder(1);
		ret[0][1]=new CalculatorHolder(2);
		ret[0][2]=new CalculatorHolder(3);
		ret[1][0]=new CalculatorHolder(4);
		ret[1][1]=new CalculatorHolder(5);
		ret[1][2]=new CalculatorHolder(6);
		ret[2][0]=new CalculatorHolder(7);
		ret[2][1]=new CalculatorHolder(8);
		ret[2][2]=new CalculatorHolder(9);
		return ret;
	}
	public int add(int x, Integer y) {
		if (this.Context != null) this.Context.Report("in the process of adding");
		return x + y;
	}
	public int minus(int x, Integer y){
		if (this.Context != null) this.Context.Report("in the process of subtracting");
		return x - y;
	}
	public int multiply(int x, Integer y) {
		if (this.Context != null) this.Context.Report("in the process of multiplying");
		return x * y;
	}
	public int multiplySalted(int x, Integer y) {
		if (this.Context != null) this.Context.Report("in the process of multiplying with salt");
		return x * y * this.salt;
	}
	public CalculatorHolder multiplySaltedHolder(CalculatorHolder Holder) {
		if (this.Context != null) this.Context.Report("in the process of multiplying with salt with holder info");
		Holder.Result = Holder.X * Holder.Y * Holder.Salt;
		return Holder;
	}
	public IExecutionContext GetExecutionContext() { return this.Context; }
	public void SetExecutionContext(IExecutionContext Context) { this.Context = Context; }
}

The respective Invokable Profile for this Java Object could be the following

<?xml version="1.0" encoding="UTF-8"?>
<execprf:InvocableProfile xmlns:execprf="http://profile.execution.madgik.di.uoa.gr" type="Pojo">
   <execprf:item>
      <execprf:className value="gr.uoa.di.madgik.callables.test.Calculator"/>
      <execprf:context supported="true">
         <execprf:type value="Simple"/>
         <execprf:keepAlive value="false"/>
         <execprf:reportsProgress value="true"/>
         <execprf:gRSProxy value="false"/>
      </execprf:context>
   </execprf:item>
   <execprf:calls>
      <execprf:call type="Simple">
         <execprf:method name="gr.uoa.di.madgik.callables.test.Calculator"/>
         <execprf:signature>public gr.uoa.di.madgik.callables.test.Calculator()</execprf:signature>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="gr.uoa.di.madgik.callables.test.Calculator"/>
         <execprf:signature>public gr.uoa.di.madgik.callables.test.Calculator(int)</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="salt"/>
            <execprf:token value="[execprfBeginToken]salt[execprfEndToken]"/>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="minus"/>
         <execprf:signature>public int gr.uoa.di.madgik.callables.test.Calculator.minus(int,java.lang.Integer)</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="x"/>
            <execprf:token value="[execprfBeginToken]x[execprfEndToken]"/>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:argument type="Simple">
            <execprf:order value="1"/>
            <execprf:name value="y"/>
            <execprf:token value="[execprfBeginToken]y[execprfEndToken]"/>
            <execprf:type value="java.lang.Integer"/>
            <execprf:engineType value="IntegerClass"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="GetProposedSalt"/>
         <execprf:signature>public static int gr.uoa.di.madgik.callables.test.Calculator.GetProposedSalt()</execprf:signature>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="multiplySalted"/>
         <execprf:signature>public int gr.uoa.di.madgik.callables.test.Calculator.multiplySalted(int,java.lang.Integer)</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="x"/>
            <execprf:token value="[execprfBeginToken]x[execprfEndToken]"/>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:argument type="Simple">
            <execprf:order value="1"/>
            <execprf:name value="y"/>
            <execprf:token value="[execprfBeginToken]y[execprfEndToken]"/>
            <execprf:type value="java.lang.Integer"/>
            <execprf:engineType value="IntegerClass"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="multiplySaltedHolder"/>
         <execprf:signature>public gr.uoa.di.madgik.callables.test.CalculatorHolder gr.uoa.di.madgik.callables.test.Calculator.multiplySaltedHolder(gr.uoa.di.madgik.callables.test.CalculatorHolder)</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="Holder"/>
            <execprf:token value="[execprfBeginToken]Holder[execprfEndToken]"/>
            <execprf:type value="gr.uoa.di.madgik.callables.test.CalculatorHolder"/>
            <execprf:engineType value="Convertable"/>
            <execprf:converter value="gr.uoa.di.madgik.execution.test.CalculatorHolderConverter"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="gr.uoa.di.madgik.callables.test.CalculatorHolder"/>
            <execprf:engineType value="Convertable"/>
            <execprf:converter value="gr.uoa.di.madgik.execution.test.CalculatorHolderConverter"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="add"/>
         <execprf:signature>public int gr.uoa.di.madgik.callables.test.Calculator.add(int[])</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="parts"/>
            <execprf:token value="[execprfBeginToken]parts[execprfEndToken]"/>
            <execprf:type value="[I"/>
            <execprf:engineType value="[IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="add"/>
         <execprf:signature>public int gr.uoa.di.madgik.callables.test.Calculator.add(int[][][])</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="parts"/>
            <execprf:token value="[execprfBeginToken]parts[execprfEndToken]"/>
            <execprf:type value="[[[I"/>
            <execprf:engineType value="[[[IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="add"/>
         <execprf:signature>public int[] gr.uoa.di.madgik.callables.test.Calculator.add(int[][])</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="parts"/>
            <execprf:token value="[execprfBeginToken]parts[execprfEndToken]"/>
            <execprf:type value="[[I"/>
            <execprf:engineType value="[[IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="[I"/>
            <execprf:engineType value="[IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="add"/>
         <execprf:signature>public int gr.uoa.di.madgik.callables.test.Calculator.add(gr.uoa.di.madgik.callables.test.CalculatorHolder[])</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="holders"/>
            <execprf:token value="[execprfBeginToken]holders[execprfEndToken]"/>
            <execprf:type value="[Lgr.uoa.di.madgik.callables.test.CalculatorHolder;"/>
            <execprf:engineType value="[Convertable"/>
            <execprf:converter value="gr.uoa.di.madgik.execution.test.CalculatorHolderConverter"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="add"/>
         <execprf:signature>public gr.uoa.di.madgik.callables.test.CalculatorHolder[] gr.uoa.di.madgik.callables.test.Calculator.add(gr.uoa.di.madgik.callables.test.CalculatorHolder[][])</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="holders"/>
            <execprf:token value="[execprfBeginToken]holders[execprfEndToken]"/>
            <execprf:type value="[[Lgr.uoa.di.madgik.callables.test.CalculatorHolder;"/>
            <execprf:engineType value="[[Convertable"/>
            <execprf:converter value="gr.uoa.di.madgik.execution.test.CalculatorHolderConverter"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="[Lgr.uoa.di.madgik.callables.test.CalculatorHolder;"/>
            <execprf:engineType value="[Convertable"/>
            <execprf:converter value="gr.uoa.di.madgik.execution.test.CalculatorHolderConverter"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="add"/>
         <execprf:signature>public int gr.uoa.di.madgik.callables.test.Calculator.add(int,java.lang.Integer)</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="x"/>
            <execprf:token value="[execprfBeginToken]x[execprfEndToken]"/>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:argument type="Simple">
            <execprf:order value="1"/>
            <execprf:name value="y"/>
            <execprf:token value="[execprfBeginToken]y[execprfEndToken]"/>
            <execprf:type value="java.lang.Integer"/>
            <execprf:engineType value="IntegerClass"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="random"/>
         <execprf:signature>public gr.uoa.di.madgik.callables.test.CalculatorHolder[][] gr.uoa.di.madgik.callables.test.Calculator.random()</execprf:signature>
         <execprf:return>
            <execprf:type value="[[Lgr.uoa.di.madgik.callables.test.CalculatorHolder;"/>
            <execprf:engineType value="[[Convertable"/>
            <execprf:converter value="gr.uoa.di.madgik.execution.test.CalculatorHolderConverter"/>
         </execprf:return>
      </execprf:call>
      <execprf:call type="Simple">
         <execprf:method name="multiply"/>
         <execprf:signature>public int gr.uoa.di.madgik.callables.test.Calculator.multiply(int,java.lang.Integer)</execprf:signature>
         <execprf:argument type="Simple">
            <execprf:order value="0"/>
            <execprf:name value="x"/>
            <execprf:token value="[execprfBeginToken]x[execprfEndToken]"/>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:argument type="Simple">
            <execprf:order value="1"/>
            <execprf:name value="y"/>
            <execprf:token value="[execprfBeginToken]y[execprfEndToken]"/>
            <execprf:type value="java.lang.Integer"/>
            <execprf:engineType value="IntegerClass"/>
            <execprf:converter value="none"/>
         </execprf:argument>
         <execprf:return>
            <execprf:type value="int"/>
            <execprf:engineType value="IntegerPrimitive"/>
            <execprf:converter value="none"/>
         </execprf:return>
      </execprf:call>
   </execprf:calls>
</execprf:InvocableProfile>