Rash thoughts about .NET, C#, F# and Dynamics NAV.

"Every solution will only lead to new problems."

Monday, 21. December 2015

FsAdvent: Automatic re-build and background tasks for suave.io websites

Filed under: .NET,F#,FAKE - F# Make,Visual Studio — Steffen Forkmann at 14:12 Uhr

[This post my second entry of the F# advent calendar 2015 series. You can also read the first post about “Using Async.Choice in Paket“]

Recently I was asked to help with a website that was based on suave.io. The task was to transform the existing F# script based suave.io website to something that can be run in the enterprise infrastructure and also performs some background tasks like creating Excel reports recurringly.

Suave as a (windows) service

A lot of the suave.io samples work with simple .fsx script files. This approach is indeed simple and allows fast prototyping with the use of the REPL. Even more complex websites like fssnip.net are using this approach with great success (code here). One of the benefits of script based suave solutions is that they are often equipped with a FAKE build script that rebuilds the website automatically if someone changes a file. One prominent example is FsReveal:

But sometimes you want to have a “real Visual Studio project” with debugging support and your enterprise might want to install your website as a Windows service. So the first step was to convert the F# script based approach into a project and adding TopShelf layer to make it runnable as Windows service. Thanks to a short blog post by Tomas Jansson this was super easy. It’s basically just installing TopShelf.FSharp via Paket and adding a single file with the config. Look into Tomas’s blog post to see the details.

After moving to the TopShelf model we still wanted to have automatic website rebuild whenever someone touched the source code. This little FAKE script makes this possible:

Running background jobs

The website already allowed to generate Excel reports by clicking somewhere in the UI. In addition to that we wanted to create the Excel reports recurringly in background jobs. Scott Hanselman has a blog post about “How to run Background Tasks in ASP.NET” and shows a couple of solutions that while optimized for ASP.NET would probably work with suave.io as well. But in this case we wanted to have something that syncronizes with the IO of the website so we decided to use F#’s MailboxProcessor feature a.k.a. “agents”. (As always: Scott Wlaschin has a nice introduction to agents.)

As a small intro into background jobs we start with F# counter agent sample by Tomas Petricek:

This little snippet shows an agent that calculates averages of the messages that it receives. Now let’s add a background job that recurringly sends messages to the counter agent:

In order to use this we need a bit of ugly infrastructure code that we will hide in a library:

So let’s try this out in the F# interactive:

Since this works as expected we can use it in our website:

Since all the user triggered reporting will also go through this taskAgent we ensure that IO is synchronized.

Sample project

In https://github.com/forki/backgroundjobs you can find a sample project which does exactly the two points from above.

As you can see the website performs background jobs and is rebuilding/restarting automatically when a source code file is saved.

Tags: , ,