LAgent : an agent framework in F# – Part II – Agents and control messages
Luca Bolognese -Download framework here.
All posts are here:
- Part I - Workers and ParallelWorkers
- Part II - Agents and control messages
- Part III - Default error management
- Part IV - Custom error management
- Part V - Timeout management
- Part VI - Hot swapping of code
- Part VII - An auction framework
- Part VIII – Implementing MapReduce (user model)
- Part IX – Counting words …
Agents
Agents are entities that process messages and keep state between one message and the next. As such they need to be initialized with a lambda that takes a message and a state and returns a new state. In F# pseudo code: msg –> state –> newState. For example the following:
let counter = spawnAgent (fun msg state -> state + msg) 0
This is a counter that starts from 0 and gets incremented by the value of the received message. Let’s make it print something when it receives a message:
let counter1 = spawnAgent
(fun msg state -> printfn "From %i to %i" state (state + msg); state + msg) 0 counter1 <-- 3 counter1 <-- 4
Which produces:
**From 0 to 3
From 3 to 7**
There is no spawnParallelAgent, because I couldn’t figure out its usage patterns. Maybe I don’t have enough creativity. Obviously msg and state could be of whatever type (in real application they end up being tuples more often than not).
Control messages
You can do things to agents. I’m always adding to them but at this stage they are:
type Command = | Restart | Stop | SetManager of AsyncAgent | SetName of string
Plus some others. I’ll describe most of them later on, right now I want to talk about Restart and Stop. You use the former like this:
counter1 <-- Restart counter1 <-- 3
Which produces:
From 0 to 3
This should be somehow surprising to you. You would have thought that you could just post integers to a counter. This is not the case. You can post whatever object. This is useful because it allows to have a common model for passing all sort of messages, it allows for the agent not to be parameterized by the type of the message (and of state) so that you can store them in data structures and allows advanced scenarios (i.e. hot swapping of code).
This is a debatable decision. I tried to get the best of strongly typing and dynamic typing, while keeping simplicity of usage. The implementation of this is kind of a mess though. We’ll get there.
BTW: you use Stop just by posting Stop, which stops the agent (forever).
Tags
- FSHARP
3 Comments
Comments
DotNetShoutout
2009-06-07T02:36:05ZThank you for submitting this cool story - Trackback from DotNetShoutout
Nick Gunn
2009-06-12T18:21:34ZGood mini-series. I have a some code and binaries at http://fspread.codeplex.com that shows f# agents operating in a distributed environment using the Spread Toolkit. The server models are similar to yours and also show load-balancing, fault-tolerance and leader-election.
Andrey
2009-06-29T07:33:36ZWhere can I download your library?