Saturday, April 28, 2018

Functional Adventures in F# - The MailboxProcessor


In this post we will look at MailboxProcessor in F#.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

MailboxProcessor

This continues with the code from Application State post.
Mainly the GameState type
and GameState =
 {
  PlayerStore:PlayerStore
  UnitStore:UnitStore
 }
 member this.HandleAction (action:obj) (state:GameState) =
  {
   PlayerStore = state.PlayerStore.HandleAction action state.UserStore
   UnitStore = state.UnitStore.HandleAction action state.AmmunitionStore 
  }


My goal is to incorporate F# with C# in a nice way. And as described in the Application State post, the core application model and all actions that can be made in the application will be modeled in F#. But to prevent a multithreaded C# application to corrupt the state we need to serialize the commands that are processed.
In C# I would have used a background Thread and a Queue<T> and written a locks to synchronize the reads and writes. Luckily in F#, we have all that nicely packaged in the built in MailboxProcessor.

The first line redefines the MailboxProcessor to the term Agent instead, this seems to be something that a lot of people are doing, so lets stick to that for the time being.
After that we define a F# static class, i.e. an abstract and sealed class with only static members. (this is what C# does under the hood).

type Agent<'T> = MailboxProcessor<'T>     
[<AbstractClass; Sealed>]
type GameHolder private () =
 static let mutable state : GameState = 
  {
   PlayerStore = { Players = Map.empty }
   UnitStore = { Units = Map.empty }
  }
 static member State : GameState = state
 static member private Processor = Agent.Start(fun inbox ->
  let rec loop =
   async {
    let! action = inbox.Receive()
    state <- state.HandleAction action state
    return! loop
    }
  loop)
 static member HandleAction (action:obj) =
  GameHolder.Processor.Post action

In addition we will be allowing for mutation here, something that the business logic in the F# module should be unaware of, but here, we are exposing the current state to the rest of the application so that it is easily accessible.
I.e. C# we can call GameHolder.State and always get the latest state. It is exposed as immutable so there is no risk that other threads will write to it.

After that we define the MailboxProcessor<'T> or in this case the redefined Agent<'T> as a private static member of the class.
What happens in the recursive part is a little iffy for me still. To my understanding the let! (with the exclamation mark) makes the inbox.Receive (that is also an async call) an synchronous call and stores its result in the action value.
If anyone has detailed explanation of what is going on here, please feel free to comment as I was unable to find details of this seems just to be the way things are done.

The HandleAction method calls the Post method on the MailboxProcessor and thus posts the action to the MailboxProcessor that in turn calls the HandleAction method of the State and mutates the exposed State value.

Update 2018-05-02, forcing serial access

Turns out the MailboxProcessor above does not work the way I thought... In my mind it serialized the processing but it did not. I.e. when multiple actions were sent to it in parallel, it corrupted the state variable.
After looking at this for some time now, I finally had to post the question on stackoverflow.
https://stackoverflow.com/questions/50135825/f-mailboxprocessor-limit-parallelism

Turns out the bad wolf in the drama was the static member. Changing the code to a module instead got the solution to work as expected.

The end result is:
module GameHolder =
    type Agent<'T> = MailboxProcessor<'T>     

    let mutable private state = AppliationState.Default
    let mutable private counter : int = 0
    let GetCurrentState() =  state
    let GetProcessedActionsCounter() = counter
    let private Processor = Agent.Start(fun inbox ->
        let rec loop (s : AppliationState) =
            async {
                let! action = inbox.Receive()
                let s' = s.HandleAction action
                state <- s'
                counter <- counter + 1
                return! loop s'
                }
        loop AppliationState.Default)

    let HandleAction (action:obj) =
        Processor.Post action

I can still get the current application state by calling a 'static' method from C#, in this case GameHolder.GetCurrentState().
So a small change thanks to stackoverflow and we still have a small but neat interface between our C# game/application and it model/business logic that is written in F#.

Finally

In the end. We have a GameHolder class that exposes State and HandleAction to the outside world. Whoever can query the state at anytime, but they are not allowed to change it other then through the HandleAction method.

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment or share a link, not required but appreciated! :)

Hope this helps someone out there!

Thursday, March 22, 2018

Functional Adventures in F# - Getting rid of temp variables


This time we will look at how to get rid of temporary variables when updating an object in multiple steps.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

In my game that I am trying to write with F# (at least the core model) I have some functions that look like the following
static member HandleTick (state:UnitStore) (action:Tick) =     
 let queueUpdatedState = UnitStore.handleTickBuildQueues state action
 let unitsUpdatedState = UnitStore.handleTickUnitUpdates queueUpdatedState action
 unitsUpdatedState
A function that takes a state and an action and in turn it uses other functions to update that state with the help of the action.
I don't know, but I grew tired of naming temporary variables after a while and started googling for a better solution. Turns out there is one. By using the forward-pipe operator '|>' we can take the output of one function and send it as input to the next function.

static member HandleTick (state:UnitStore) (action:Tick) =     
 UnitStore.handleTickBuildQueues action state 
 |> UnitStore.handleTickUnitUpdates action
To make this work, the order of parameters need to be switched so that Action is the first argument followed by the State.
Turns out I have to refactor all the functions in my Stores to take the action first and state as second argument to get this working, but I guess that is a small price to pay for cleaner code.

Looking at the assembly in ILSpy gives us that in the background there will be temporary variables passed around, but our code is clean of them.
public static UnitStore HandleTick(Actions.Tick action, UnitStore state)
{
 UnitStore unitStore = UnitStore.handleTickBuildQueues(action, state);
 UnitStore state2 = unitStore;
 return UnitStore.handleTickUnitUpdates(action, state2);
}

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Wednesday, March 21, 2018

Functional Adventures in F# - Getting rid of loops


Solving problems without loops.....

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

This time lets look at a real issue when coming from an imperative language and trying functional programming.
The example problem (that I crashed into when rewriting some game logic in F#) is that of spawning new Ships in a space game. We do not want to spawn 2 ships on top of each other, so we generate the default spawning coordinate and then test if it is safe to use, if not we move the ship a bit and try again....

How I solved it in C#..
private Ship FindClosestFreeCoordinate(ImmutableList<Fleet> state, Ship newShip)
{
    var shipsWithinSafetyDistance = ShipsWithinSafetyDistance(state, newShip);
    while (shipsWithinSafetyDistance.Any())
    {
        var newCoordinates = newShip.Coordinates.Position.Add(Vector3.UnitXVector);
        newShip = newShip.Modify(coordinates: newShip.Coordinates.Modify(position: newCoordinates));
        shipsWithinSafetyDistance = ShipsWithinSafetyDistance(state, newShip);
    }
    return newShip;
}

private List<Ship> ShipsWithinSafetyDistance(ImmutableList<Fleet> state, Ship newShip)
{
    return (from fleet in state
        from
            ship in fleet.Ships
        where
            ship.Distance(newShip) < 5
        select ship).ToList();
}

Translating the ShipsWithinSafetyDistance function is no problem. We just use the Map.filter function...
static member private shipsWithinSafetyDistance (unit:Unit) (state:UnitStore) =
    Map.filter (fun key value -> unit.distanceToUnit value < 5.0) state.Units
Ah, yes.. I switched from a ImmutableList in C# to a Map in F#, just to keep things interesting (and to get faster Key lookups)


So, the tricky part here is the while loop. Most loops can be rewritten with Map/List functions like map, filter and fold etc... But this time I don't see how to use them as I don't have a Collection of any sort here so my brain keeps yelling "Write a loooooop", as that is the way I have solved this kind of problems for the past 20+ years... So...
How should we do it in F#??? We have some other constructs to use that fit the functional idea better.

static member private findClosestFreeCoordinate (unit:Unit) (state:UnitStore) =
 let rec findClosestFreeCoordinateRecursive (unit:Unit) (state:UnitStore) = 
  let shipsWithinSafetyDistance = shipsWithinSafetyDistance unit state
  match shipsWithinSafetyDistance with
  | a when a.IsEmpty -> unit
  | _ ->  let newUnit = { unit with Coordinates = unit.Coordinates + Vector3.UnitX }
    findClosestFreeCoordinateRecursive newUnit state
 findClosestFreeCoordinateRecursive unit state
Recursion!
At least for this problem, it seems to be a good option. Here we define a function, findClosestFreeCoordinateRecursive with the rec keyword to let the compiler know that it will be called recursively. In the function body we match the result list with IsEmpty and return the input value or else call the recursive function with a new copy of the unit with new coordinates.

Call stack.. Is there a risk for stack overflow with this?
Lets open the dll output with ILSpy to check what actually goes on behind the scenes
ILSpy of F# Recursive Function
Turns out, that the current F# compiler in the background uses a while loop. The key here is that we do not, instead we define a short and concise function where we state what it is that we want done, how it is solved behind the scene in detail is not up to us. At some point, there is always someone that needs to write the ifs and loops, but lets keep them away from the application code that we write.

So there, lets move the last shipsWithinSafetyDistance to inner scope of our function and we are set
static member private findClosestFreeCoordinate (unit:Unit) (state:UnitStore) =
 let shipsWithinSafetyDistance (unit:Unit) (state:UnitStore) =
  Map.filter (fun _ value -> unit.distanceToUnit value < 50.0) state.Units
 let rec findClosestFreeCoordinateRecursive (unit:Unit) (state:UnitStore) = 
  let shipsWithinSafetyDistance = shipsWithinSafetyDistance unit state
  match shipsWithinSafetyDistance with
  | a when a.IsEmpty -> unit
  | _ ->  let newUnit = { unit with Coordinates = unit.Coordinates + Vector3.UnitX }
    findClosestFreeCoordinateRecursive newUnit state
 findClosestFreeCoordinateRecursive unit state

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!