Showing posts with label Design. Show all posts
Showing posts with label Design. Show all posts

Monday, July 19, 2010

Executing work from a "VeroServe Workflow"

While the interaction of an enterprise user application with its back-end services is orchestrated in a “VeroServe Workflow”, execution of intensive or performance sensitive “VeroServe Workflow” work can in turn be delegated to one or more instances of ExecuteServe for load balancing across servers. “VeroServe Workflow” hides the details of delegating work to ExecuteServe through its ExecuteActivity.




To use ExecuteActivity, first add it to VS by hovering over the toolbar when displaying a work flow, right clicking, selecting the “System.Activities.Components” tab, then browsing for ExecutionActivity.dll (built from svn://[repositoryAddress]/[company]/WorkflowServices/WorkflowServices.sln). Then, drag it to the appropriate location in your work flow. 

ExecuteActivity requires configuration of the following in and out parameters:

ExecuteActivity.DLL Activity Control:

In Parameters:
   callbackAddress          String
   workflowInstanceId       String
   executeActivityNumber    String
   worker                   Worker
   executionServiceAddress  String


Out Parameters:
   executeReturnParameter   ExecuteReturnParameter


    public class ExecuteReturnParameter
    {
        public string Status { ... }
        public string Message { ... }
        public string AssemblyName { ... }
        public string ClassName { get; set; }
        public string SerializedWorker { ... }
        public ExecuteParameter ExecutionParameter { ... }
    }


Work flows containing the ExecuteActivity must also have a client endpoint element in its web.config named "IExecutionServiceEndpointConfigurationName". The following web.config entry can be directly cut/pasted into a "VeroServe Workflow" web.config without any modification to satisfy this requirement:

Web.config Settings:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IExecutionService" .... >
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint binding="basicHttpBinding" 
        bindingConfiguration="BasicHttpBinding_IExecutionService" contract="IExecutionService" address="http://localhost/ExecutionService.svc"
        name="IExecutionServiceEndpointConfigurationName" />
    </client>
  </system.serviceModel>
</configuration>

The following figure is an example of settings for ExecuteActivity parameters:



ExecuteActivity's in parameters include:
  • callbackAddress, the execution URL of the “VeroServe Workflow” containing the ExecuteActivity. In this figure, this "VeroServe Workflow" is configured to execute at "http://localhost:1392/PayoutWorkflowService.xamlx".
  • workflowInstanceId, a unique number that identifies the instance of the "VeroServe Workflow" executing. In this example, the variable workflowId was set in "VeroServe Workflow" prior to this ExecuteActivity with a unique Guid generated for the executing instance.
  • executeActivityNumber, a unique constant that identifies the ExecuteActivity within the "VeroServe Workflow". In this example, the variable invocationNumber was set to a constant that uniquely identifies this ExecuteActivity within the "VeroServe Workflow".
  • worker, an instance of a derivative of Worker, with its DataMember-decorated properties set to their values in preparation for execution within ExecutionServe.
  • executionServiceAddress, the URL of an ExecutionServe service.

ExecuteActivity also requres an ExecuteReturnParameter out parameter defined in Entities.dll (built from svn://[repositoryAddress]/[company]/WorkflowServices/WorkflowServices.sln), which will include a Worker-defined status and an ExecutionParameter that can be used by Worker's desearalize() static method to re-instantiate the Worker within the work flow after ExecuteActivity completes. Modifications made to any Worker property decorated with the [DataMember] attribute during execution directed by ExecuteActivity will be subsequently reflected in these deserialized values.


    public abstract class Worker
    {
        public static Worker deserialize(ExecuteParameter executeParameter)
        { ... }
        }

        public ExecuteParameter serialize()
        { ... }

    }

Saturday, July 17, 2010

Persistence of Worker data in "VeroServe Workflow"

When an ExecutionServe Worker is used as a variable within a "VeroServe Workflow", its properties decorated with the [DataMember] attribute will be persisted with the rest of the work flow when it persists.

What makes this possible is the persistence services of SqlWorkflowInstanceStore, which "VeroServe Workflow" uses to persist work flows. SqlWorkflowInstanceStore in turn uses  the NetDataContractSerializer to serialize and deserialize complex types, including those decorated with the [DataContract] attribute like ExecutionServe Workers.

Sunday, July 11, 2010

Implementing work for ExecutionServe

While the design goal of "VeroRight" is to accomplish as much application development through configuration as possible, some operations are complex and simply require coding. For those that are also execution intensive or performance sensitive, ExecutionServe provides a remote service-based execution environment within which submitted work can be executed asynchronously for load balancing across servers.

Units of work are implemented for execution within ExecutionServe by simply extending a base class that hides all underlying details of ExecutionServe's execution environment:
  1. Derive your worker class from the Worker class within Entities.dll (built from svn://[repositoryAddress]/[company]/WorkflowServices/WorkflowServices.sln)
  2. Decorate it with the DataContract attribute
  3. Add properties decorated with the DataMember attribute
  4. Override the doWork() method with your long running implementation.

The following example code snippet is from svn:// [repositoryAddress]/[company]/WorkflowServices/SampleCalculator:

  
    [DataContract]
    public class LongerRunningCalculator : Worker
    {
        [DataMember]
        public string Param1 { get; set; }

        [DataMember]
        public string Param2 { get; set; }

        protected override DoWorkReturnParameter doWork()
        {
            System.Threading.Thread.Sleep(14400000); //4 hours

            DoWorkReturnParameter returnParam = new DoWorkReturnParameter();
            returnParam.Message = "return value";
            returnParam.Status = "status value;

            return returnParam;
        }
    }

This example class can now be instantiated, its DataMember properties set, and then serialized so it can be supplied to a remote ExecutionServe's IExecutionService.executeAsync() operation for execution of its doWork() method. It will also be automatically serialized again and asynchronously returned to the caller  after its doWork() method completes so that any changes to its DataMember properties are available after completion. 

"VeroServe Workflow" use of ExecutionServe will be discussed in a subsequent post.