Building Azure Service Fabric Actors with F# – Part 1


This post is the first part of a brief overview of Service Fabric and how we can model Service Fabric Actors in F#. Part 1 will cover the details of how to get up and running in SF, whilst Part 2 will look at the challenges and solutions to modelling stateful actors in a OO-based framework within F#.

What is Service Fabric?

Service Fabric is a new service on Azure (currently in preview at the time of writing) which is designed to support reliable, scalable (at “hyper scale”) and maintainable distributed applications and services – with automatic support for things like replication of state across nodes, automatic failover & recovery and multi tenanting services on the same instances. It supports (currently) both stateful and stateless micro-services and actor model architectures (more on this shortly). The good thing about Service Fabric (SF) from a risk/reward point of view is that it’s not a new technology – it actually underpins a lot of existing Azure services themselves such as Azure SQL, DocDB and even Cortana, so when Microsoft says it’s a reliable and scalable technology, they’ve been using it for a while now with a lot of big services on Azure. The other nice thing is that whilst it’s still private preview for running in Azure, you can get access to a locally running SF here. This isn’t an emulator like with Azure Storage – it’s apparently the “full” SF, just running locally. Nice.

Actors on Service Fabric

As mentioned, SF supports an Actor model in both stateful and stateless modes. It’s actually based on the Orleans codebase, although I was pleasantly surprised to see that there’s actually no C# code-generation whatsoever in SF – the only bit that’s auto-generated are some XML configuration files which I suspect will be pretty much boilerplate for most people and rarely change.

Why would you want to try SF out? Well, simply put, it allows you to focus on the code you write, as opposed to the infrastructure side of things. You spin up an SF cluster (or run the local version), deploy your code to it, and off you go. This is right up my alley, as someone who likes to focus on creating solutions and sometimes has little patience for messing around with infrastructural challenges or difficulties that prevent me from doing what I’m best at.

Getting up and running with Service Fabric

I’ve been using Service Fabric for a little while now, and spent a couple of hours getting it up and running in F#. As it turns out, it’s not too much hassle to do aside from a few oddities, which I’ll outline here: –

  • Download and install VS2015. Community edition should be fine here. You’ll also need WIndows 8 or above.
  • Download and install the SDK.
  • Create a new Service Fabric solution and an Stateful Actor service. This will give you four projects: –
    • A SF hosting project. This has no code in it, but essentially just the manifest for what services get deployed and how to host them.
    • An Actors project. This holds your actor classes and any associated code; it also serves as a bootstrapper that deploys the appropriate services into SF; as such, it’s actually an executable program which does this during Main(). It also holds a couple XML configuration files that describe the name of the package and each of the services that will be hosted.
    • An Interfaces project. This holds your actor interfaces. I suspect that this project could just as easily be collapsed into the actors one, although I suppose for binary compatibility you might want to keep the two separate so you can update the implementations without redeploying the interfaces to clients.
    • A console test project. This just illustrates how to connect to the Service Fabric and create actors. In the F# world these projects serve zero purpose since we can just create a script file to interact with our code, so I deleted this immediately.
  • Convert to Paket (optional). If you use Paket rather than Nuget for dependency management, change over now. The convert-from-nuget works first time; you’ll end up with a simplified packages file of just a single dependency (Microsoft.ServiceFabric.Actors), plus you’ll get all the other benefits over Nuget.
  • Create F# project equivalents. The two core projects, the Actors and Interfaces projects, can simply be recreated as an F# Console App and Class Library respectively. The only trick is to copy across the PackageRoot configuration folder from the C# Actors project to the equivalent F# one. Once you’ve done this, you can essentially disregard the C# projects.
  • Configure the F# projects. I set both projects to 4.5.1 (as this is what the C# ones default to) – I briefly tried (and failed) to get them up and running in 4.5.2 or 4.6. Also, make sure that both projects target x64 rather than AnyCPU. This is more than just changing the target in the project settings – you must create a Configuration (via Configuration Manager) called x64!
  • Create an interface. This is pretty simple – each actor is represented by an interface that inherits from IActor (a marker interface). Make sure that all arguments in all methods all have explicit names! If you don’t do this, your actors will crash on initialisation.
  • Create the implementation. Here’s an example of a Cat actor interface and implementation.


open System
open System.Threading.Tasks
open Microsoft.ServiceFabric.Actors
/// Cat actor
type ICat =
inherit IActor
abstract member Jump : destination : string -> Task
abstract member FavouriteFood : unit -> string Task
abstract member Colour : unit -> string Task
// other members elided…
/// Implementation of ICat
type Cat() =
inherit Actor<CatState>()
let emptyTask() = Task.FromResult() :> Task // simple helper for returning Task (rather than Task<unit>)
interface ICat with
// Side-effect-free actions
member __.Colour() = Task.FromResult "Black"
member __.FavouriteFood() = Task.FromResult favouriteFood
// Side-effect-full actions
member this.Jump(destination) =
this.State.HungerLevel <- this.State.HungerLevel + 1
this.State.CatHappiness <- this.State.CatHappiness + 1
this.State.Weight <- this.State.Weight – 0.1
match destination with
| "Table" -> this.State.OwnerHappiness <- this.State.OwnerHappiness – 2
| "Bed" -> this.State.OwnerHappiness <- this.State.OwnerHappiness – 1
| _ -> ()
emptyTask()

view raw

ICat.fsx

hosted with ❤ by GitHub

  • Update the Hosting project. Reference the implementation from the Hosting project and update the configuration appropriately.

Luckily, I’ve done all of this in a sample project available here.

Running your project

Once you’ve done all this, you can simply hit F5 (or Publish from the Host project) and watch as your code is launched into the Fabric via the UI.

SFEYou can then also call into your actors via e.g. an F# script:-


#load "load-references.fsx"
#r @"..\bin\debug\Interfaces.dll"
open Microsoft.ServiceFabric.Actors
open ServiceFabricDemo
open System
let cat = ActorProxy.Create<ICat>(ActorId "Blackie", "fabric:/CatActors")
async {
do! cat.Eat "Whiskers" |> Async.AwaitTask
do! cat.Eat "Sheba" |> Async.AwaitTask
do! cat.Meow 3 (TimeSpan.FromHours 6.) |> Async.AwaitTask
do! cat.Purr() |> Async.AwaitTask
let! color = cat.Colour() |> Async.AwaitTask
let! food = cat.FavouriteFood() |> Async.AwaitTask
return sprintf "%s is %s and likes %s." (cat.GetActorId().GetStringId()) color food
} |> Async.RunSynchronously
(*
val it : string = "Blackie is Black and likes Sheba."
*)

I’m looking forward to talking more about the coding side of this in my next post, where we can see how code that is inherently mutable doesn’t always fit idiomatically into F#, and how we can take advantage of F#’s ability to mix and match OO and FP styles to improve readability and understanding of our code without too much effort.

7 thoughts on “Building Azure Service Fabric Actors with F# – Part 1

  1. I don’t expect you to be give me a definitive answer, but do you think there is any fundamental issue which would prevent me doing the same with VB.net ?

  2. It all seemed easy enough to port over, but it fell apart when I tried to build. My VB “Service” would not import into the “Hosting Project”. I think I followed all your steps including copying over the PackageRoot folder into my VB Service, but the hosting project just would not recognise it.

    It seems to be running some sort of powershell/command prompt build step but it fails

    I don’t have VS2015 on my dev machine yet, so I was running this on an Azure IaaS VM running Visual Studio 2015. I have since forgotten the exact error message I was getting 😦

    I will have to repeat the process and and report back the exact error I am having.

Leave a comment