SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
In this talk we discussed a number of real world use cases of F# at Gamesys for domain modelling, async programming, writing game logic & genetic algorithms, and creating DSLs to tame complexities with AWS APIs.
In this talk we discussed a number of real world use cases of F# at Gamesys for domain modelling, async programming, writing game logic & genetic algorithms, and creating DSLs to tame complexities with AWS APIs.
15.
Collectables
Wager Size
Special Symbol
Avg Wager Size
Web Server call
16.
• Line Win
– X number of matching symbols on adjacent columns
– Positions have to be a ‘line’
– Wild symbols substitute for other symbols
• Scatter Win
– X number of matching symbols anywhere
– Triggers bonus game
17.
What symbols should land?
Any special symbol wins?
Did the player win anything?
33.
type Wager = int64<Pence>
type Multiplier = int
type Payout = Coins of Wager
| MultipliedCoins of Multiplier * Wager
| Multi of Payout list
| BonusGame
34.
type Wager = int64<Pence>
type Multiplier = int
type Payout = Coins of Wager
| MultipliedCoins of Multiplier * Wager
| Multi of Payout list
| BonusGame
35.
type Wager = int64<Pence>
type Multiplier = int
type Payout = Coins of Wager
| MultipliedCoins of Multiplier * Wager
| Multi of Payout list
| BonusGame
36.
type State =
{
AvgWager : Wager
SpecialSymbol : Symbol
Collectables : Map<Collectable, Count>
}
49.
Elastic Load Balancer
S3
Auto scaling Group
Server A Server B
...
EC2
CloudFront
Stateful Server
50.
Stateful Server
Game Logic
Stateless Middle-tier
Infrastructure
logging
circuit
breaker
perf
tracking
retry …
51.
Stateful Server
Game Logic
Stateless Middle-tier
Infrastructure
logging
circuit
breaker
perf
tracking
retry …
52.
Stateful Server
Game Logic
Stateful Middle-tier
Infrastructure
logging
circuit
breaker
perf
tracking
retry …
53.
The Actor Model
An actor is the fundamental unit of computation
which embodies the 3 things
• Processing
• Storage
• Communication
that are essential to computation.
-Carl Hewitt*
* http://bit.ly/HoNHbG
54.
The Actor Model
• Everything is an actor
• An actor has a mailbox
• When an actor receives a message it can:
– Create new actors
– Send messages to actors
– Designate how to handle the next message
55.
Stateful Server
• Gatekeeper
– Manages the local list of active workers
– Spawns new workers
• Worker
– Manages the states for a player
– Optimistic locking
– Persist state after period of inactivity
56.
Stateful Server
Game Server
Player A
Player B
S3
Worker C
Worker B
Gatekeeper
RequestHandlers
Asynchronous
57.
Stateful Server
Game Server
Worker C
Worker B
Gatekeeper
Worker A
ok
RequestHandlers
Player A
Player B
Asynchronous
S3
58.
Stateful Server
Game Server
S3
Worker C
Worker B
Gatekeeper
Worker A
RequestHandlers
Player A
Player B
Asynchronous
59.
Stateful Server
Game Server
S3
Worker C
Gatekeeper
Worker A
RequestHandlers
Player A
Player B
Asynchronous
60.
Stateful Server
Game Server
Worker C
Worker A
Gatekeeper
error
RequestHandlers
Player A
Player B
S3
Asynchronous
77.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None ->
do! persist state
return! closedState()
…
}
78.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None ->
do! persist state
return! closedState()
…
}
79.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
…
}
80.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
…
}
type Message =
| Get of AsyncReplyChannel<GetResult>
| Put of State * Version * AsyncReplyChannel<PutResult>
81.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
…
}
type GetResult = Result<State * Version>
type PutResult = Result<unit>
82.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
…
}
83.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
…
}
84.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
…
}
type Message =
| Get of AsyncReplyChannel<GetResult>
| Put of State * Version * AsyncReplyChannel<PutResult>
85.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
…
}
86.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
…
}
87.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Put(_, v, reply)) ->
reply.Reply <| Failure(VersionMismatch(version, v))
return! workingState(state, version)
}
88.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
…
| Some(Put(_, v, reply)) ->
reply.Reply <| Failure(VersionMismatch(version, v))
return! workingState(state, version)
} type Result<‘T> =
| Success of ’T
| Failure of Exception
89.
let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None -> …
| Some(Get(reply)) -> …
| Some(Put(newState, v, reply)) when version = v -> …
| Some(Put(_, v, reply)) -> …
}
157.
select GameTitle, UserId, TopScore
from GameScores
where GameTitle = “Starship X”
and TopScore >= 1000
order desc
limit 3
with (NoConsistentRead, Index(GameTitleIndex, true))
162.
F# & FParsec*
*www.quanttec.com/fparsec
External DSL
via
163.
SELECT * FROM GameScore
Abstract Syntax Tree (AST)
FParsec
164.
select GameTitle, UserId, TopScore
from GameScores
where GameTitle = “Starship X”
and TopScore >= 1000
order desc
limit 3
with (NoConsistentRead, Index(GameTitleIndex, true))