Raza Ali

Raza Ali I am Currently working as an Architect and a Consultant at a Microsoft partner company. I have broad technology interests but find myself more interested in ASP.Net and backend server techonlogies. This blog for me is a means to share whatever I come to learn. Hope you find something useful here.
E-mail me Send mail
MCTS

Recent comments

Recent posts

Files I've Posted

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Sign in

Learning WF- Part 9

by raza 5/27/2008 1:56:59 PM

In this installment we will look at the persistence functionality built into the workflow framework. But why is persistence important anyway? You have to remember that workflows represent processes and these processes can be short or long. If all process were short and completed in a few seconds life would be much easier and we would not need to persist, but processes tend to be long running and to make best use of resources in this case we need to be able to offload (persist) those workflows that are not doing anything right now.

Persistence is not just about long running processes, although that is one of the most important reason, its also about saving state during intermediate states so that a recovery can be made if a failure occurs. Other uses could simply be resource optimization or to save a workflow in one application and then load in another, sort of a travelling process between applications.

As we saw previuosly that there is a distinction between the runtime and the services a workflow can use which gives us the flexibility to easily plug-in and out these services. Persistence is also used in similar fashion. A ready-made persistance service is the SQLWorkflowPersistenceService, which uses SQL Server as the backend store. Let's now see how we can use this service.

First thing to understand is that workflows don't persist themselves, they have to be persisted by the host application which has access to the workflow instance object. To simulate the process we are going to create a workflow application along following lines:

- A workflow that counts to ten

- The workflow call the host during the counting and asks to be persisted

- The host unloads the workflow and waits for a user input to reaload it so that it can contiue its counting process from where it left off

First step create a workflow that counts to ten and calls a host function at an arbitrary value, lets say 6:

Now the function called by this workflow is just setting an event, we will use this to trigger the code in the host program.

How does the host code interact with it? Here you go.

We put a wait on the event we defined in the PersistManager class, which is then set when the workflow calls the function. This leads the host to unload it and once the user input arrives it loads it back up.

I described the whole process but did not mention the actual persistence part yet, let's look at it now. Since we are using SQL Server as our backed database we need to set it up first. For the SQLWorkflowPersistenceService it needs two tables in the database, the schema for which is provided as an sql script that you can find in C:\<WINDOWS DIR>\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\<LANGUAGE DIR>. Open the script from here, create a new database in SQL Server called let's say WFPersistence and run this script in it. You should have tables InstanceState and CompletedScope in it. The InstanceState table is used for storing the workflow instances and the CompletedScope is used for storing the activities executed during a transactional workflow. Another script needs to be executed which creates the stored procedures needed for persistence serivce, it comes with a _logic in it.

Now let's add the persistence service to the runtime so that all persistence calls can be passed to it.

This is it. Now run the workflow.

At this point go to the database and open the table InstanceState, you should see the persisted instance.

When we press the key it gets loaded back and resumes it work as planned.

and the workflow is removed from database.

Did you notice the second "Workflow persisted" message at the end? I had put a handler on the persist event of the runtime like so:

Why did it persist the second time? Actually it has to do with how the workflow runtime defines its "persistence points". These are places during the executing when the workflow would be persisted. They include:

- When workflow becomes idle (waiting for something)

- When workflow completes or terminates

- When transaction completes

- When CompensatableSequence completes

- When explicitly unloaded or when an activity marked with PersistOnClose ends.

In this post I cannot go into the details of writing your own workflow persistence service but it is not as dificult as you might think, though there are some details of the persistence mechanism. For all practical purposes the SQL service should enable you to create persistable workflows. In the next post we will look at workflow tracking, keep reading!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Learning WF - Part 8

by raza 5/22/2008 11:20:32 AM

In this installment we will be looking at consuming and exposing web services through Workflow Foundation. Needless to say that any modern framework should have the ability to easily interface with web services as more often then not it would either be hosted by a web service or using some.

Let's start with how can you use web service from WF. To consume a web service we need to first create one, use the template provided in visual studio to create a hello world web service. Change the function to accept a parameter called name and say hello to that name.

image3

Now create a sequential workflow that looks like this:

image6

In the first code activity we will get a name from the console and put it in a local property. The value of this property will be bound to the function we are calling in the InvokeWebService activity. The return value is placed in another local property which the second code activity will print.

image9

 image15

image18

Calling web services is as simple as that. When you provide the url for the web service a proxy class is generated as usual and a web reference added.

Now let's come to exposing web service through WF. Yes, it is possible to expose your workflows directly as web services with some visual studio magic. WF designer provides you with three activities, one that allows you to receive the incoming request, the second lets you send a response back to the client and third one alternatively allows you to send back SOAP faults. Think of this web service that you create with WF as a single function in a usual web service implementation where you enter the function with a request and exit with a response or exception. Although it is possible to receive multiple requests and return multiple responses but it is much easier to understand it in such a unit like manner.

Start by dropping a WebServiceInput and WebServiceOutput activity in the workflow. When you get the properties of the input activity, you see the need of an interface and method which these activities will expose. As opposed to previous uses of interfaces to create external services this would just be a plain old interface.

image21

Specify this interface and method in the two activities only that they now need two properties to save the incoming name value and outgoing greeting message. Define these properties and select them here. Once that is done we put in a code activity to make the response message from the incoming name.

 image30

Let's put in a fault activity as well. But we can either return a response for a request or a exception so they have to be put in a exclusive branch. For that let's put a If-Else and put the condition in that if the name is empty it throws the exception that name should be specified. When you put the service fault activity it needs a Fault property to bind to. This needs to be a Exception type of property. Define it and assign it to this activity. We need to instantiate this property to some exception value as well, so for that modify the code activity and add the following line:

image33 

The workflow should look something like this:

image36

Till now we have defined the necessary element to define a web service not the web service itself. Let's do that now by right clicking the project and selecting Publish as Web Service. It may prompt you if the workflow is an application rather than a library. Once published, another project will be added to you solution which actually contains the proxy code for a web service that invokes your workflow and provides it with incoming name and returns the resulting output.

image39

In the web.config you will notice an http handler:

image42

This http module is basically part of the workflow runtime which allows you to do necessary session management for workflow webservices. From previous post you might remember that to send any message to a workflow it is necessary that we talk to it using its unique id. This unique id is available for session management and is stored on the client side in a cookie. So if the client sends a request back with the same id in the cookie then it is considered to be a request for an already running instance of the workflow otherwise a new one is created. All this could be done manually if required without using the built in wizards of visual studio. Select the web service as the startup project and run it.

Lets create a client for it and call this web service. I did it by creating another project in the same solution, adding a web reference to the running service and then selecting this client project as the startup one. Call the method from the service with a name:

image45

It should return the response. Now call it with an empty value:

image48

It should throw an error which says what we specified as the exception description. This ends the post on consuming and exposing web service with WF workflows. In the next post we will learn about workflow persistence, keep reading.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net | WF

Learning WF - Part 7

by raza 5/14/2008 6:26:00 PM

Till this point we have been working with sequential workflows. Sequential workflows are suitable for all processes where all the "arrows" seem to be pointing in one direction. If you have processes where you may be repeating previously completed steps then you may need what are called state machine workflows. The state machine workflows follow the state machine model which has a number of states linked by transitions. A transition represents an event that triggers the change of state. For any given state there may be N number of transitions resulting in any one of the available states.

This workflow type requires prior understanding of the state machine concept, which I cannot describe in detail here. Let's create a project called LightBulb which has two states, you guessed it right, On and Off. Naturally then we need a "toggle" event for the button which changes the state from one to another. Once the project is created you will see something like this.

This is the initial condition of a state. It allows you to drop a number of activities in it as visible from the diagram. Lets change the name of this state to BulbOff and create another state called BulbOn. Right click on the BulbOff activity and add an EventDriven activity to it. Double click and it should look something like this:

Here lets add a code activity to display a custome message and a SetState activity to change state. The EventDriven activity represents the transition and you can perform whatever actions necessary here during it. At the start you should drop a HandleExternalEvent to catch the transition event. At the end you should do a SetState to change the state to some other activity, otherwise it will stay in the same one.

Lets do the same for the other activity and its SetState should bring us back to this state. Now we need to implement the event that drives both these states. Coincidently in this case its the same event for both on and off, which is the toggle of the switch. Following the previuos post lets define an interface to generate that event.

With this event we set the parameters for both the HandleExternalEvent activities in each state. We can set the same event for both of them because at any given time the workflow will be in one state, hence we can give them difference behaviour. The worflow now looks like the following:

The event properties of the HandleExternalEvent like:

Once this has been taken care of lets write the code to trigger the event and set our workflow rolling. First we need to add this as a service and the write the code to deliver the message to the workflow instance.

The the event delivery code with a bit of twist.

Now when we run it, we see the workflow changing state and executing the code activity. Press escape and it exits.

 Before we end this post lets just look at one more thing, initialization and finalization code. These activities you can add to each state and they will be executed once you enter or leave the state. Lets add both and it should look like this:

 

Add a code activity to each and put a relevant message in there.

In the next post we will look at how to call external web services and expose workflows as web services.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net | WF

Learning WF - Part 6

by raza 5/10/2008 9:32:00 PM

Let's continue from where we left off, in the current installment we will learn about communicating between host and the workflow instance. Why is this communication important when we can execute any code we want in the workflow? Well, we cannot act on workflow itself to begin with. That's not just it, there are many other scenarios where it is important that we are able to pass information between the hosting program and workflow, for example if the workflow were hosted in a web service. Create a new sequential workflow project called TalkToMe.

 image

Once it is created add new item of the type Interface and call it ICalculator. Communication can take place in two directions, from workflow to host where workflow calls a host function and from host to workflow where host sends the workflow "instance" an event. The key to understanding how communication between host and the workflow works is to understand how workflow communication is designed in general. The services that workflows use from the runtime have actually been separated from the runtime and implemented as independent services which can be added to the runtime and to communicate with these services we need to base these services on interfaces and then use those interfaces to call their functions. Our calculator service will be one such service and we shall now define its interface.

image

Notice the attribute ExternalDataExchange over the interface. This marks the interface usable as runtime service. Next create the implementation for this service right here without adding another file.

 image

Now drop the activity CallExternalMethod and Code to the designer.

image

select the first activity and specify the following details.

 image

The method details are quite obvious except the parameters that we are passing. The IDE has correctly recognized the input values from the selected method and that it has a return value. The input values specified here are static right now but these could be dynamic if we link these values to some value from another activity or link them to properties in the workflow. For the input we used static values but for the return value we must specify some receiving variable. To do that I have defined a property in my workflow and linked it to the return value.

image

This value can now be selected in the return value parameter in properties.

image

We will now use this property in the code activity to print the results.

 image

We can now execute and see the results for it. This covers the scenario where the workflow is communicating with the outside services. How about the outside services talking back to the workflow? To do that we have to define an event and then use a HandleExternalEventActivity to receive the call from outside. Drop this activity from the toolbar to the designer and lets add code to support the callback.

image

Now we have to create the event infrastructure. For that modify the ICalculator interface and add the following event.

 image

I have added an event and a function to raise that event. Notice that I am passing CalcArgs argument to the event handler. To pass any data to the event we need to derive our own class from the ExternalDataEventArgs class.

image

The definition of the event arguments only contains one variable called CalcResult. The constructor points to an important fact about this event handling, which is that the "callback" is bound to a specific instance of the workflow and we need to pass it to the base class here. To acquire this instance ID we need to get it either from within the workflow or where the workflow instance was created. For this example I will get it from the point of creation. In the Program class I have added the following code beside the workflow instance code.

image

After creation of the workflow instance I simply wait for the user to press the enter key and then raise the event to pass information to the workflow instance. Let's look at the implementation code for our event.

image

This goes in the implementation class of the ICalculator interface. Let's go back to our designer to see what have we specified in the properties for the event handler activity.

image

So the activity is receiving an event called CalculationComplete from an ICalculator type class. Notice the "e" parameter, two arguments are passed to any event handler, the sender and the arguments. For the moment we are only interested in receiving the arguments, so for that we create a property in our workflow class for it.

image

And assign this to the "e" parameter.  once the event is called we can get the CalcResult value, which if you look back is 10, and use it other activities.

This concludes the post on host to workflow communication. In the next post we will look at creating state machine workflow and the things that we have learnt here is necessary background for it.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net | WF

Powered by BlogEngine.NET 1.4.0.0
Theme by Mads Kristensen