Skip to content

Instantly share code, notes, and snippets.

@raol
Created August 1, 2016 14:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raol/fe2a7e0ff0f05d90fd485d96f38182f3 to your computer and use it in GitHub Desktop.
Save raol/fe2a7e0ff0f05d90fd485d96f38182f3 to your computer and use it in GitHub Desktop.
Actor configuration example
module Actors
open System
open System.Threading.Tasks
let inline response(data:obj) = Task.FromResult(data)
let inline taskDone() = Task.FromResult(null) :> Task
type BodyConfiguration<'TMessage> = {
OnReceive: 'TMessage -> Task<obj>
OnReminder: string -> Task
OnActivate: unit -> Task
OnDeactivate: unit -> Task
}
let emptyBody(): BodyConfiguration<'a> = {
OnReceive = fun m -> response(null)
OnReminder = fun m -> taskDone()
OnActivate = fun m -> taskDone()
OnDeactivate = fun m -> taskDone()
}
type ActorConfiguration<'TMessage> = {
Id: string
KeepAlive: System.TimeSpan
Body: BodyConfiguration<'TMessage>
}
let emptyConfig() : ActorConfiguration<'a> = { Id = ""; KeepAlive = TimeSpan.Zero; Body = emptyBody() }
type ActorBuilder<'TMessage>() =
member __.Yield(item: 'a) : ActorConfiguration<'TMessage> = emptyConfig()
[<CustomOperation("id")>]
member __.Id(actor, id) = { actor with Id = id }
[<CustomOperation("keepAlive")>]
member __.KeepAlive(actor, timeSpan) = { actor with KeepAlive = timeSpan }
[<CustomOperation("body")>]
member __.Body(actor, body) = { actor with Body = body }
type BodyBulder<'TMessage>() =
member __.Yield(item: 'a) : BodyConfiguration<'TMessage> = emptyBody()
[<CustomOperation("onReceive")>]
member __.OnReceive(body, receive) : BodyConfiguration<'TMessage> = { body with OnReceive = receive }
[<CustomOperation("onReminder")>]
member __.OnReminder(body, reminder) : BodyConfiguration<'TMessage> = { body with OnReminder = reminder }
[<CustomOperation("onActivate")>]
member __.OnActivate(body, activate) : BodyConfiguration<'TMessage> = { body with OnActivate = activate }
[<CustomOperation("onDeactivate")>]
member __.OnDeactivate(body, deactivate) : BodyConfiguration<'TMessage> = { body with OnDeactivate = deactivate }
let handlers<'a> = BodyBulder<'a>()
let actor<'a> = ActorBuilder<'a>()
module Main
open System.Threading.Tasks
open Actors
type Message = Hello of string | Bye
[<EntryPoint>]
let main argv =
let config = actor {
id "HelloActor"
body (
let mutable state = 1
handlers {
onReceive (function
| Hello s ->
state <- state + 1
response()
| Bye ->
printfn "Current state is %A" state
response())
onReminder (fun r ->
printfn "Reminded on %A" r
taskDone())
onActivate taskDone
onDeactivate taskDone
})
}
Task.WaitAll((config.Body.OnReceive (Hello "Oleg")), (config.Body.OnReceive Bye))
0 // return an integer exit code
Current state is 2
Press any key to continue . . .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment