Hosting What Where? As a Web Service?

This comes from a forum post here.  After writing almost 4 pages in response, I figured I'd place it here as well:

 

John,

Good discussion, I’m going to be posting this to my blog to get some wider exposure and comment for this important topic!

First, let me try to clear things up.  Tom is right above, there is no "one best way" to host the workflow runtime, that's really the beauty of the model, you can host it in a windows forms app, or you can scale it up and out to a clustered setting.

That being said, let's look at some of the hosting options we have available to us in a web application, some of the reasons you'd pick one over the other, as well as some of the issues you will face in implementation.  I'll try to rank these in some order of increasing complexity of implementation.  I also try to look at the implication of having declarative (XAML-only) workflows in each scenario.

Workflows inline to ASP.NET

This is somewhat the "simplest" model, and it is what you see in many of the samples surrounding ASP.NET hosting of workflows and using the ManualWorkflowSchedulerService.  In this case, you create a workflow runtime and store it in the same appdomain (and IIS instance) of your application.  You typically start and stop the runtime in the app_start / end events, although you could expose administrative functions to reset the runtime, although I'd be interested in why you'd want to do that.  If you needed multiple runtimes you can host them in the same appdomain in basically the same way, just store them with different application variable keys.  Again, I'm not sure what scenario would neccessitate different runtimes in the asp.net process, so please let me know what you're thinking about doing here. 

Now, if you do this with the SQL persistence service, this will allow scaling out to a farmed environment, thus having multiple runtime instances correlating to each box in the farm.  I'd be careful about how much work you're doing in the workflow, I would think you would want to return relatively quickly to the web page to allow rendering.  In the declarative case, this could be tricky if you are enabling editing of your workflows because you wouldn't want to place a "getManagerApproval" activity in the middle of a workflow that only takes place between postback-to-render.

Long running workflows hosted inside ASP.NET

In this case, the lifetime of the workflow is extended beyond postback-to-render to enable the web application interacting with workflow throughout the life of a process, which may span multiple pages.  Many of the samples showing page flow are examples of this.  The implementation is very similar to the above, except instead of a page starting a workflow, you are really sending in an event to a waiting activity and either waiting for the next "pause", or sending a one-way message and continuing with rendering the page.  One issue to watch out for here is taking up a number of threads in IIS if you are not using the ManualWorkflowSchedulerService.  There are some runtime properties that allow you to set the maximum number of threads.  You'd want to look at this relative to the number of threads you are allowing IIS to make sure that your web pages still get served.  Many of these scenarios cause people to start looking outside of the ASP.NET app to host the business logic (think of the tier approach, where you really separate this into a distinct business process tier).  Which leads to the next case:

Long Running Workflows Exposed as Web Services Generated by Visual Studio

This is what happens when you click "Publish as a web service" on an existing workflow.  Due to the way this process works, the web service has to be created against a compiled workflow, which means the web service can't be executing a dynamic, declarative version on the fly.  The runtime is still hosted in IIS, but it will be within a different application than your ASP.NET application for management and portability.  If you need to provide the workflow with any services, you will need to do this via the config file, but in this way, you can plug in any of the runtime services that you need. Again, this doesn't address the scenario of XAML-only workflows, but by incorporating multiple web service input and outputs, you can create a centralized workflow runtime (or a set of them in a farmed environment) that multiple applications can interact with over the course of the lifetime of the workflow. 

This is a model to consider when you have
• Multiple applications that interact with a running workflow
• Need to separate (for management, perf, etc) the workflow from your presentation layer

This model won't work, and you'll need to consider one of the following two if:
• Need to execute declarative workflows
• Need very fine grained control over the web service exposure (incorporating WSE / WCF, specific WSDL / XSD implementations, etc)

Long running workflows exposed as a Web Service You Create

This solves two of the problems above, handling declarative workflows and fine grained control over the web service implementation, at the expense of not being able to click and generate the web service facade for you.  The way to implement this would be to take Tom's sample of XAML-only workflow being executed from an ASP.NET application, and place that into an ASMX web service project.  Instead of handling a button click on a web form, you'll expose a WebMethod that gathers whatever parameters you need, interacts with the runtime that will again be hosted the same way (within an application level variable for instance), and executes the workflow.  Your workflow would not need to have the web service activities in it, rather it could simply have a HandleExternalEvent or some other activity waiting on a message.

This gives you some flexibility in having some methods that execute an entire workflow, and others that simply inject a message.  It would be here where you could also handle the XAML activation needed for the XAML-only scenario.  This has an advantage over the previous approach in that it truly de-couples the web service (the choice of messaging implementation) from the business process (the workflow).  Again, this is going to come at the cost of having to write a little bit of web service code.  I've written a note to try to write this up as a sample in the next day or two.  This also leads into the next approach in the line of de-coupling the workflow from the messaging implementation.

Long Running Workflows Hosted in a Windows Service

You are also welcome to use a Windows service as a host for the workflow runtime and your workflows.  Some people like this because it provides additional / different flexibility in management.  The trick is to then expose the workflow communication points through the Windows service, which you can do in whatever means you see fit (MSMQ, socket-based communication, other message passing).  If you look at our expense reporting sample, you see two applications communicating with a workflow living in a third application via WCF.  in this case WF is hosted within a console app, but that could be wrapped in a Windows service.  Using the SqlPersistenceService will still give you the ability to execute in a farm, but you'll probably need some mechanism to handle load balancing and message routing (this is why IIS is a convenient hosting mechanism, you can get a lot of that "for free" in IIS).

This comes at the expense that it is one of the more complicated development scenarios, but one that definitely enables the use of long running workflows in scenarios where IIS is not appropriate or possible, such as in a long running client side workflow.  This also may fit the scenario when you want to allow maximum throughput on your web app, so all you do is drop a message in a queue (relatively inexpensive) and  go on with processing your page.

The Windows service approach is what a number of people are doing who want to expose portions of the workflow via WCF endpoints.  There was a presentation given at TechEd that talks about how this scenario is going to improve down the road with future versions of WF, so look for that when the sessions are available.

Finally, the End!

In short, you’ve got a whole lot of options available to you when you chose where to host the workflow runtime and execute your workflows.  I hope this shows some of the options you have available, why you might chose them, how to start going about implementing them, and also some things to look out for.  Let me know if I missed something or if you have any questions.

Matt