12,950,618 members (64,584 online)
alternative version

#### Stats

22.2K views
20 bookmarked
Posted 20 Feb 2009

# An Idea of F# Workflow Engine based on Concurrency and Coordination Runtime

, 20 Feb 2009 CPOL
 Rate this:
This article describes the basic ideas of how to build workflow engine a-la WF based on F# workflows and CCR

## Introduction

This article describes basic ideas of how to build workflow engine a-la Workflow Foundation based on F# workflows and CCR.

## Main Idea

Recently I've played a bit with F# workflows feature and one crazy idea appeared in my fevered imagination: “Would it be possible to build a workflow engine a-la Windows Workflow Foundation using F# workflows?”. In this article, you can see an attempt to build such an engine, at least a very initial version of it. First of all, I would like to provide you with some useful links for those who haven't had a chance to play with F# and F# workflows in particular:

So, if you continue reading this, then you probably already have some F# knowledge or have checked the links above… or just want to check what this crazy guy is talking about.

```let workflowHost = new WorkflowEngine()

let fibonacciWorkflow number =
workflowHost {
do printfn "Started!"
let! f1 = fib number
let! f2 = fib (number + 1)
do printfn "Finished"
do printfn "Result is %s" ((f1 + f2).ToString())
return 0 //success
}

runWorkflow(fibonacciWorkflow(22));;  ```

What do we have here: A workflow or THE workflow called `fibonacciWorkflow`. Something very trivial: we calculate two Fibonacci numbers and print out the sum of these numbers. Here `fib `function calculates Fibonacci number for a given position. Honestly, I've copy pasted this function from somewhere on the web. :)

```let fib n =
let rec fib_aux (n, a, b) =
match (n, a, b) with
| (0, a, b) -> a
| _ -> fib_aux (n - 1, a + b, a)
fun () -> fib_aux (n, 0, 1)		 ```

Looks like nothing special - a very trivial workflow. Let's have some fun now - it's time to have a closer look at the workflow engine.

Of course, each dependable workflow engine should manage threading and execute all workflows and activities in parallel (or not?) threads where possible and tries to do its best to increase performance. So our engine tries to follow the tradition and uses CCR to execute all activities (activities you can identify by “`let!`” keyword). Here we have two activities and each one is transformed behind the scene to CCR task. The output of each activity (CCR task) is taken as an input to the next activity (CCR task).

Before I show the actual implementation, I'd like to describe one more feature of our workflow engine.

The second thing each dependable workflow engine should do is to provide developers with the ability to inject aspects during activity execution. Let’s define trivial security aspect which is intended to notify someone (probably a system administrator) about a security alert (let's assume that in your company it is forbidden to calculate Fibonacci numbers :)) :)

```let securityAspect() =

This is a very, very simple aspect. I could make it more complicated (for instance, validate activity input within aspect)… maybe next time. :)

Now it’s time to have a look at the workflow engine code (by the way, please forgive me for using “engine” term here, in F# usually is used workflow builder term):
```type Activity<'a> = unit -> 'a

let runWorkflow (f:Activity<'a>) = f()

type WorkflowEngine() =
let dispatcher = new Dispatcher(8, "MyDispatcher") //from Microsoft.Ccr.Core
let queue = new DispatcherQueue("MyQueue", dispatcher) // from Microsoft.Ccr.Core

member b.Let(p, rest) =
rest p
member b.Return(x) =
fun () -> x
member b.Delay f =
fun () -> (runWorkflow f)()
member b.Bind(p, rest) =
securityAspect()
fun () ->
fun () ->
let res = p()
fun () ->
let fakeVal =
rest(res)()
()
))
()
))
new 'b()//return fake value - just to fool the F# compiler :)... sorry,
//it's ugly, but I haven't yet found a better way```

Each keyword in the workflow is transformed to a method in the workflow builder: let -> `Let`, let! -> `Bind`, return -> `Return `and `Delay `method is used to provide invocation point for the whole workflow. Actually, all workflow-engine-features-I-have-stated-above-related functionality is implemented within the `Bind `method. It is possible to define additional keywords, like for, while, use, if/then… etc. Here I've implemented only the basic set of all possible keywords.

The important point here is that with the help of F# compiler, you have reasonable level of control over each line of code within the workflow and can influence it with aspects or any other ways you want.

The other important point is that within workflow, you can keep state of workflow execution.

## Conclusion

Here I presented the basic ideas of how to build a workflow engine based on F# workflows. The engine provided above is pretty trivial and its mission is to convey a basic idea of possible implementation. There is absolutely no support for centralized exception handling (dependable workflow engine should also provide it), which could be achieved through output ports in CCR. And CCR usage is pretty superficial, I use it in a very simple and dummy way. You can find much better CCR-related articles if you want to learn it (I've used some CCR samples as a base).

## Share

 Technical Lead bwin Interactive Entertainment AG Austria
The views expressed in my articles are mine and do not necessarily reflect the views of my employer.

if(youWantToContactMe)
{
SendMessage(string.Format("{0}@{1}.com", "liptchinski_vit", "yahoo"));
}

## You may also be interested in...

 Pro

 View All Threads First Prev Next
 [My vote of 2] Errors & Questions [modified] Member 1984809-Aug-10 16:18 Member 198480 9-Aug-10 16:18
 Re: [My vote of 2] Errors & Questions Vitaliy Liptchinsky16-Aug-10 2:07 Vitaliy Liptchinsky 16-Aug-10 2:07
 Re: [My vote of 2] Errors & Questions [modified] Bourlesque17-Aug-10 12:54 Bourlesque 17-Aug-10 12:54
 Re: [My vote of 2] Errors & Questions Vitaliy Liptchinsky17-Aug-10 21:37 Vitaliy Liptchinsky 17-Aug-10 21:37
 You are concentrating on the minor details. The purpose of the article is to present general concept of CCR workflows. The purpose of article is not to reveal advantages against traditional OOP, I would say that it is incorrect to compare workflows with OOP: OOP is a computational model and workflows are just a single feature of functional programming as computational model. Again, article demonstrates workflow engine, but not the single workflow. Don't you understand the difference??? Vitaliy Liptchinsky
 Re: [My vote of 2] Errors & Questions Bourlesque18-Aug-10 4:37 Bourlesque 18-Aug-10 4:37
 Last Visit: 31-Dec-99 18:00     Last Update: 25-May-17 21:07 Refresh 1