Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
F# in real world (LambdaCon15)
Next
Download to read offline and view in fullscreen.

13

Share

Download to read offline

F# at GameSys

Download to read offline

F# at GameSys

  1. 1. F# at GameSys! (how we used F# to build games for millions)
  2. 2. Hi, my name is Yan Cui.
  3. 3. agenda
  4. 4. Domain Modelling! Infrastructure! Game Logic! Algorithms! DSLs! OSS
  5. 5. 1MILLION USERS ACTIVE DAILY
  6. 6. 250MILLION DAY PER REQUEST
  7. 7. 2MONTH TB P E R sec ops 25,000
  8. 8. we are polyglot C#
  9. 9. why F#?
  10. 10. time to market
  11. 11. correctness
  12. 12. efficient
  13. 13. tame complexity
  14. 14. Collectables Wager Size Special Symbol Avg Wager Size Web Server call
  15. 15. • 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
  16. 16. What symbols should land?! Any special symbol wins?! Did the player win anything?
  17. 17. What the player’s new average wager?
  18. 18. Should the player receive collectables?
  19. 19. type Symbol = Standard! of string! ! ! ! | Wild
  20. 20. type Symbol = Standard! of string! ! ! ! | Wild e.g.! Standard “hat”! ! Standard “shoe”! ! Standard “bonus”! ! …
  21. 21. type Symbol = Standard! of string! ! ! ! | Wild i.e.! Wild
  22. 22. ! ! ! type Win = LineWin of int * Symbol * int! ! | ScatterWin of Symbol * int
  23. 23. ! ! ! type Win = LineWin of int * Symbol * int! ! | ScatterWin of Symbol * int e.g.! LineWin (5, Standard “shoe”, 4)
  24. 24. ! ! ! type Win = LineWin of int * Symbol * int! ! | ScatterWin of Symbol * int e.g.! ScatterWin (Standard “bonus”, 3)
  25. 25. type LineNum = int! type Count! = int! ! type Win = LineWin of LineNum * Symbol * Count! ! | ScatterWin of Symbol * Count
  26. 26. type LineNum = int! type Count! = int! ! type Win = LineWin of LineNum * Symbol * Count! ! | ScatterWin of Symbol * Count e.g.! LineWin (5, Standard “shoe”, 4)
  27. 27. type LineNum = int! type Count! = int! ! type Win = LineWin of LineNum * Symbol * Count! ! | ScatterWin of Symbol * Count e.g.! ScatterWin (Standard “bonus”, 3)
  28. 28. make invalid states unrepresentable
  29. 29. [<Measure>]! type Pence e.g.! 42<Pence>! ! 153<Pence>! ! …
  30. 30. 10<Meter> / 2<Second> ! = 5<Meter/Second>! 10<Meter> * 2<Second> ! = 20<Meter Second> ! 10<Meter> + 10<Meter> ! = 20<Meter>! 10<Meter> * 10! ! ! = 100<Meter>! 10<Meter> * 10<Meter> ! = 100<Meter2>! 10<Meter> + 2<Second> ! // error! 10<Meter> + 2 ! ! ! // error
  31. 31. 10<Meter> / 2<Second> ! = 5<Meter/Second>! 10<Meter> * 2<Second> ! = 20<Meter Second> ! 10<Meter> + 10<Meter> ! = 20<Meter>! 10<Meter> * 10! ! ! = 100<Meter>! 10<Meter> * 10<Meter> ! = 100<Meter2>! 10<Meter> + 2<Second> ! // error! 10<Meter> + 2 ! ! ! // error
  32. 32. type Wager = int64<Pence>! type Multiplier = int! ! type Payout = Coins! of Wager! ! ! | MultipliedCoins of Multiplier * Wager! ! ! | Multi! of Payout list! ! ! | BonusGame
  33. 33. type Wager = int64<Pence>! type Multiplier = int! ! type Payout = Coins! of Wager! ! ! | MultipliedCoins of Multiplier * Wager! ! ! | Multi! of Payout list! ! ! | BonusGame
  34. 34. type Wager = int64<Pence>! type Multiplier = int! ! type Payout = Coins! of Wager! ! ! | MultipliedCoins of Multiplier * Wager! ! ! | Multi! of Payout list! ! ! | BonusGame
  35. 35. type State = ! {! AvgWager! : Wager! SpecialSymbol : Symbol! Collectables : Map<Collectable, Count>! }
  36. 36. New avg wager Got a Collectable! A pay line win!
  37. 37. Recap
  38. 38. lightweight syntax for types & hierarchies
  39. 39. great for domain modelling
  40. 40. make invalid states unrepresentable
  41. 41. better correctness
  42. 42. order of magnitude increase in productivity
  43. 43. player states are big
  44. 44. Stateless Server DatabaseClient
  45. 45. 1:1 read-write ratio
  46. 46. ServerClient Session 1 Session 2
  47. 47. ServerClient Database
  48. 48. Elastic Load Balancer S3 Auto scaling Group Server A Server B ... EC2 CloudFront Stateful Server
  49. 49. 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
  50. 50. 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
  51. 51. 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
  52. 52. Stateful Server Game Server Player A Player B S3 Worker C Worker B Gatekeeper RequestHandlers Asynchronous
  53. 53. Stateful Server Game Server Worker C Worker B Gatekeeper Worker A ok RequestHandlers Player A Player B Asynchronous S3
  54. 54. Stateful Server Game Server S3 Worker C Worker B Gatekeeper Worker A RequestHandlers Player A Player B Asynchronous
  55. 55. Stateful Server Game Server S3 Worker C Gatekeeper Worker A RequestHandlers Player A Player B Asynchronous
  56. 56. Stateful Server Game Server Worker C Worker A Gatekeeper error RequestHandlers Player A Player B S3 Asynchronous
  57. 57. type Agent<‘T> = MailboxProcessor<‘T>! ! ! !
  58. 58. type Agent<‘T> = MailboxProcessor<‘T>! ! type Message = ! | Get of AsyncReplyChannel<…>! | Put of State * Version * AsyncReplyChannel<…>
  59. 59. type Agent<‘T> = MailboxProcessor<‘T>! ! type Message = ! | Get of AsyncReplyChannel<…>! | Put of State * Version * AsyncReplyChannel<…>
  60. 60. type Result<‘T> =! | Success! of ’T! | Failure! of Exception! ! ! !
  61. 61. type Result<‘T> =! | Success! of ’T! | Failure! of Exception! ! type GetResult = Result<State * Version>! type PutResult = Result<unit>!
  62. 62. type Agent<‘T> = MailboxProcessor<‘T>! ! type Message = ! | Get of AsyncReplyChannel<GetResult>! | Put of State * Version * AsyncReplyChannel<PutResult>
  63. 63. type Agent<‘T> = MailboxProcessor<‘T>! ! type Message = ! | Get of AsyncReplyChannel<GetResult>! | Put of State * Version * AsyncReplyChannel<PutResult>
  64. 64. type Worker (playerId) =! let agent = Agent<Message>.Start(fun inbox ->! let state = getCurrentState playerId! ! let rec workingState (state, version) = ! async { … }! and closedState () =! async { … }! ! workingState (state, 1))
  65. 65. type Worker (playerId) =! let agent = Agent<Message>.Start(fun inbox ->! let state = getCurrentState playerId! ! let rec workingState (state, version) = ! async { … }! and closedState () =! async { … }! ! workingState (state, 1))
  66. 66. type Worker (playerId) =! let agent = Agent<Message>.Start(fun inbox ->! let state = getCurrentState playerId! ! let rec workingState (state, version) = ! async { … }! and closedState () =! async { … }! ! workingState (state, 1))
  67. 67. type Worker (playerId) =! let agent = Agent<Message>.Start(fun inbox ->! let state = getCurrentState playerId! ! let rec workingState (state, version) = ! async { … }! and closedState () =! async { … }! ! workingState (state, 1))
  68. 68. type Worker (playerId) =! let agent = Agent<Message>.Start(fun inbox ->! let state = getCurrentState playerId! ! let rec workingState (state, version) = ! async { … }! and closedState () =! async { … }! ! workingState (state, 1))
  69. 69. let rec workingState (state, version) = ! async { ! let! msg = inbox.TryReceive(60000)! match msg with! | None -> ! do! persist state! return! closedState()! …! }!
  70. 70. let rec workingState (state, version) = ! async { ! let! msg = inbox.TryReceive(60000)! match msg with! | None -> ! do! persist state! return! closedState()! …! }!
  71. 71. let rec workingState (state, version) = ! async { ! let! msg = inbox.TryReceive(60000)! match msg with! | None -> ! do! persist state! return! closedState()! …! }!
  72. 72. non-blocking I/O
  73. 73. let rec workingState (state, version) = ! async { ! let! msg = inbox.TryReceive(60000)! match msg with! | None -> ! do! persist state! return! closedState()! …! }!
  74. 74. let rec workingState (state, version) = ! async { ! let! msg = inbox.TryReceive(60000)! match msg with! | None -> ! do! persist state! return! closedState()! …! }!
  75. 75. 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)! …! }!
  76. 76. 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)! …! }
  77. 77. 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)! }
  78. 78. 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)) ! ! ! -> …! }
  79. 79. and closedState () = ! async { ! let! msg = inbox.Receive()! match msg with! | Get(reply) ->! reply.Reply <| Failure(WorkerStopped)! return! closedState()! | Put(_, _, reply) ->! reply.Reply <| Failure(WorkerStopped)! return! closedState()! }
  80. 80. and closedState () = ! async { ! let! msg = inbox.Receive()! match msg with! | Get(reply) ->! reply.Reply <| Failure(WorkerStopped)! return! closedState()! | Put(_, _, reply) ->! reply.Reply <| Failure(WorkerStopped)! return! closedState()! }
  81. 81. 5x efficient improvement
  82. 82. 60% latency drop
  83. 83. no databases
  84. 84. 90% cost saving
  85. 85. need to ensure server affinity
  86. 86. need to balance load
  87. 87. need to avoid hotspots
  88. 88. • Persist player state after short inactivity! • Move player to another server after persistence
  89. 89. need to gracefully scale down
  90. 90. Recap
  91. 91. Agents! • no locks! • async message passing! !
  92. 92. Agents! • no locks! • async message passing! • self-contained! • easy to reason with
  93. 93. Agents! • low level! • exceptions kills agents! • primitive error monitoring! • no supervision! • no distribution
  94. 94. MS Orleans Cricket akka.Net
  95. 95. Async Workflow! • non-blocking I/O! • no callbacks
  96. 96. Pattern Matching! • clear & concise
  97. 97. Caught a Gnome
  98. 98. EXP Item Gold Quest Progress Caught a Gnome
  99. 99. Level Up Quest Progress EXP Item Gold Caught a Gnome Quest Complete
  100. 100. Level Up Quest Progress EXP Item Gold Caught a Gnome New Quest Quest Complete
  101. 101. Quest Progress EXP Item Gold Caught a Gnome Quest Complete New Quest Level Up
  102. 102. Quest Progress New Quest Achievement Progress EXP Item Gold Quest Complete Level Up Caught a Gnome
  103. 103. Level Up Quest Progress EXP Item Gold Caught a Gnome Quest Complete New Quest Achievement Progress Achievement Complete
  104. 104. Level Up Quest Progress EXP Item Gold Caught a Gnome Quest Complete New Quest Achievement Progress Achievement Complete
  105. 105. 100+ actions
  106. 106. triggered by different abstraction layers
  107. 107. non-functional requirements
  108. 108. message-broker pattern
  109. 109. Caught Gnome Trapping Queue Levelling Quests Achievements Analytics Partner Reporting
  110. 110. Caught Gnome Trapping Queue Levelling Quests Achievements Analytics Partner Reporting Ignore Process Process Process Process Ignore
  111. 111. Caught Gnome Trapping Queue Levelling Quests Achievements Analytics Partner Reporting EXP Item Gold
  112. 112. Caught Gnome Trapping Queue Levelling Quests Achievements Analytics Partner Reporting EXP Item Gold
  113. 113. Caught Gnome Trapping Queue Levelling Quests Achievements Analytics Partner Reporting EXP Item Gold Process Ignore Ignore Ignore Process Ignore
  114. 114. Caught Gnome Trapping Queue Levelling Quests Achievements Analytics Partner Reporting EXP Item Gold Level Up
  115. 115. Caught Gnome Trapping Queue Levelling Quests Achievements Analytics Partner Reporting EXP Item Gold Level Up
  116. 116. need lots of facts
  117. 117. type Fact =! | GotExp! ! of Exp! | GotGold! ! of Gold! | GotItem! ! of Item * Count! | CaughtMonster! of Monster * Bait * Location! | LevelUp! ! of OldLevel * NewLevel! …
  118. 118. type Reward =! | GotExp! ! of Exp! | GotGold! ! of Gold! | GotItem! ! of Item * Count! ! type StateChange =! | LevelUp! ! of OldLevel * NewLevel! …
  119. 119. type Fact =! | StateChange! of StateChange! | Reward! ! of Reward! | Trapping! ! of Trapping! | Fishing! ! of Fishing! …
  120. 120. let process fact =! match fact with! | StateChange(stateChange)! -> …! | Reward(reward)! ! ! -> …! | Trapping(trapping)! ! -> …! …
  121. 121. C# interop
  122. 122. …! var fact = Fact.NewStateChange(! ! StateChange.NewLevelUp(oldLvl, newLvl));! …
  123. 123. type IFact = interface end! ! type Reward =! | GotExp! ! of Exp! | GotGold! ! of Gold! | GotItem! ! of Item * Count! interface IFact
  124. 124. type IFact = interface end! ! type Reward =! | GotExp! ! of Exp! | GotGold! ! of Gold! | GotItem! ! of Item * Count! interface IFact
  125. 125. let process (fact : IFact) =! match fact with! | :? StateChange ! as stateChange!-> …! | :? Reward ! ! as reward! ! -> …! | :? Trapping! ! as trapping! -> …! …! | _ -> raise <| NotSupportedFact fact
  126. 126. let process (fact : IFact) =! match fact with! | :? StateChange ! as stateChange!-> …! | :? Reward ! ! as reward! ! -> …! | :? Trapping! ! as trapping! -> …! …! | _ -> raise <| NotSupportedFact fact
  127. 127. simple
  128. 128. flexible
  129. 129. saver
  130. 130. location bait attraction rate catch rate
  131. 131. auto-tuning trapping stats
  132. 132. Monster strength speed intelligence Trap strength speed technology
  133. 133. Monster strength speed intelligence Trap strength speed technology Catch Rate %
  134. 134. trial-and-error
  135. 135. genetic algorithms
  136. 136. F#-powered DSLs.! Awesome!
  137. 137. wanna find correlations?
  138. 138. wanna find correlations? you can DIY it! ! ;-)
  139. 139. why was payment service slow last night?
  140. 140. Pain Driven Development
  141. 141. Amazon! ! .CloudWatch! ! .Selector github.com/fsprojects/Amazon.CloudWatch.Selector
  142. 142. Find metrics whose 5 min average exceeded 1 second during last 12 hours
  143. 143. cloudWatch.Select( unitIs “milliseconds” + average (>) 1000.0 @ last 12 hours |> intervalOf 5 minutes)
  144. 144. cloudWatch.Select(“ unitIs ‘milliseconds’ and average > 1000.0 duringLast 12 hours at intervalOf 5 minutes”)
  145. 145. did any cache nodes’ CPU spike yesterday?
  146. 146. cloudWatch.Select( namespaceLike “elasticache” + nameLike “cpu” + max (>) 80.0 @ last 24 hours |> intervalOf 15 minutes)
  147. 147. cloudWatch.Select( namespaceLike “elasticache” + nameLike “cpu” + max (>) 80.0 @ last 24 hours |> intervalOf 15 minutes) regex support
  148. 148. Amazing F# =
  149. 149. usable from anywhere you can run F# code e.g. F# REPL, executable, .. Internal DSL
  150. 150. useful for building tools e.g. CLI, … External DSL
  151. 151. Recap
  152. 152. managed! key-value store
  153. 153. redundancy! 9-9s guarantee
  154. 154. great performance
  155. 155. name your throughput
  156. 156. hash key + range key
  157. 157. hash_key_1 hash_key_2 hash_key_3 range_key_1 range_key_2 range_key_1 range_key_2 range_key_1 range_key_2
  158. 158. Hash Key Range Key
  159. 159. Hash Key Range Key Local Secondary Index
  160. 160. Hash Key Range Key Local Secondary Index Global Secondary Index
  161. 161. query:! ! given a hash key! ! filter on! ! ! range key, or! ! ! local secondary index
  162. 162. Hash Key Range Key Local Secondary Index Global Secondary Index Who are the TOP 3 players in “Starship X” with a score of at least 1000?
  163. 163. DynamoDB.SQL github.com/fsprojects/DynamoDb.SQL
  164. 164. GOAL Disguise complexity
  165. 165. GOAL SELECT UserId, TopScore FROM GameScore WHERE GameTitle CONTAINS “Zelda” ORDER DESC! LIMIT !! 3 WITH (NoConsistentRead)
  166. 166. Query AST Execution
  167. 167. F# & FParsec* *www.quanttec.com/fparsec External DSL via
  168. 168. SELECT * FROM GameScore Abstract Syntax Tree (AST) FParsec
  169. 169. select GameTitle, UserId, TopScore from GameScores where GameTitle = “Starship X” and TopScore >= 1000 order desc limit 3 with (NoConsistentRead, Index(GameTitleIndex, true))
  170. 170. S3 Provider github.com/fsprojects/S3Provider F# type provider for Amazon S3
  171. 171. compile time validation
  172. 172. no code generation
  173. 173. a long time ago, in a language far far away from .Net - Erlang. there was an idea to let you pattern match again binary payloads and work with them at a bit level…
  174. 174. <<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
  175. 175. <<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
  176. 176. <<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
  177. 177. <<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
  178. 178. <<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
  179. 179. <<SourcePort:16, DestinationPort:16, ! SeqNumber:32,! AckNumber:32, DataOffset:4, ! Reserved:3, Flags:9, WindSize:16,! CheckSum:16, UrgentPointer:16,! Payload/binary>> = SomeBinary
  180. 180. BitSyntax github.com/theburningmonk/bitsyntax Working with Stream at bit level
  181. 181. do bitWriter stream {! do! BitWriter.WriteInt16(12345s) ! // source port! do! BitWriter.WriteInt16(12321s)! // destination port! do! BitWriter.WriteInt32(1) ! // sequence number! do! BitWriter.WriteInt32(1) ! // ack number! do! BitWriter.WriteInt32(2, numBits = 4) // data offset! do! BitWriter.WriteInt32(0, numBits = 3) // reserved! do! BitWriter.WriteBool(false) ! // NS! …! do! BitWriter.WriteInt16(42s)! ! // Checksum! do! BitWriter.WriteInt16(1208s)! // Urgent Pointer! do! BitWriter.WriteString("Hello World!") // payload! }
  182. 182. do bitWriter stream {! do! BitWriter.WriteInt16(12345s) ! // source port! do! BitWriter.WriteInt16(12321s)! // destination port! do! BitWriter.WriteInt32(1) ! // sequence number! do! BitWriter.WriteInt32(1) ! // ack number! do! BitWriter.WriteInt32(2, numBits = 4) // data offset! do! BitWriter.WriteInt32(0, numBits = 3) // reserved! do! BitWriter.WriteBool(false) ! // NS! …! do! BitWriter.WriteInt16(42s)! ! // Checksum! do! BitWriter.WriteInt16(1208s)! // Urgent Pointer! do! BitWriter.WriteString("Hello World!") // payload! } 16 bits
  183. 183. do bitWriter stream {! do! BitWriter.WriteInt16(12345s) ! // source port! do! BitWriter.WriteInt16(12321s)! // destination port! do! BitWriter.WriteInt32(1) ! // sequence number! do! BitWriter.WriteInt32(1) ! // ack number! do! BitWriter.WriteInt32(2, numBits = 4) // data offset! do! BitWriter.WriteInt32(0, numBits = 3) // reserved! do! BitWriter.WriteBool(false) ! // NS! …! do! BitWriter.WriteInt16(42s)! ! // Checksum! do! BitWriter.WriteInt16(1208s)! // Urgent Pointer! do! BitWriter.WriteString("Hello World!") // payload! } 32 bits
  184. 184. do bitWriter stream {! do! BitWriter.WriteInt16(12345s) ! // source port! do! BitWriter.WriteInt16(12321s)! // destination port! do! BitWriter.WriteInt32(1) ! // sequence number! do! BitWriter.WriteInt32(1) ! // ack number! do! BitWriter.WriteInt32(2, numBits = 4) // data offset! do! BitWriter.WriteInt32(0, numBits = 3) // reserved! do! BitWriter.WriteBool(false) ! // NS! …! do! BitWriter.WriteInt16(42s)! ! // Checksum! do! BitWriter.WriteInt16(1208s)! // Urgent Pointer! do! BitWriter.WriteString("Hello World!") // payload! } take ’first’ N bits
  185. 185. bitReader stream {! let! srcPort ! = BitReader.ReadInt32(numBits = 16)! let! destPort ! = BitReader.ReadInt32(numBits = 16)! let! seqNum ! = BitReader.ReadInt32(numBits = 32)! let! ackNum ! = BitReader.ReadInt32(numBits = 32)! let! dataOffset ! = BitReader.ReadInt32(numBits = 4)! let! _ ! = BitReader.ReadByte(numBits = 3)! …! let! payload ! = BitReader.Rest(UTF8.GetString)! ! return srcPort, destPort, … payload! }
  186. 186. bitReader stream {! let! srcPort ! = BitReader.ReadInt32(numBits = 16)! let! destPort ! = BitReader.ReadInt32(numBits = 16)! let! seqNum ! = BitReader.ReadInt32(numBits = 32)! let! ackNum ! = BitReader.ReadInt32(numBits = 32)! let! dataOffset ! = BitReader.ReadInt32(numBits = 4)! let! _ ! = BitReader.ReadByte(numBits = 3)! …! let! payload ! = BitReader.Rest(UTF8.GetString)! ! return srcPort, destPort, … payload! } packs into 32 bit int
  187. 187. Byte1! Byte2! 00000000! 00000000 memory address Byte1! Byte2!
  188. 188. bitReader stream {! let! srcPort ! = BitReader.ReadInt32(numBits = 16)! let! destPort ! = BitReader.ReadInt32(numBits = 16)! let! seqNum ! = BitReader.ReadInt32(numBits = 32)! let! ackNum ! = BitReader.ReadInt32(numBits = 32)! let! dataOffset ! = BitReader.ReadInt32(numBits = 4)! let! _ ! = BitReader.ReadByte(numBits = 3)! …! let! payload ! = BitReader.Rest(UTF8.GetString)! ! return srcPort, destPort, … payload! } packs into a byte
  189. 189. 0 1 0 1 1 0 1 1 …! let! dataOffset = BitReader.ReadInt32(numBits = 4)! …
  190. 190. 0 1 0 1 1 0 1 1 …! let! dataOffset = BitReader.ReadInt32(numBits = 4)! … 0 1 1 0 1 1 0 0 <<< 2
  191. 191. 0 1 0 1 1 0 1 1 …! let! dataOffset = BitReader.ReadInt32(numBits = 4)! … 0 1 1 0 1 1 0 0 <<< 2 0 0 0 0 0 1 1 0 >>> 4
  192. 192. 0 0 0 0 0 1 1 0 …! let! dataOffset = BitReader.ReadInt32(numBits = 4)! … 6uy
  193. 193. …! let! dataOffset = BitReader.ReadInt32(numBits = 4)! … 6uy 6 padding padding padding byte 0 0 0 0 0 1 1 0
  194. 194. 1 0 0 1 0 0 0 1 …! let! dataOffset = BitReader.ReadInt32(numBits = 4)! … 1 0 0 0 1 0 1 1
  195. 195. 1 0 0 1 0 0 0 1 …! let! dataOffset = BitReader.ReadInt32(numBits = 17)! … 1 0 0 0 1 0 1 1 1 1 0 1 1 0 1 0 0 1 0 0 1 0 0 0
  196. 196. Filbert github.com/fsprojects/Filbert BERT serializer and BERT-RPC client
  197. 197. @theburningmonk theburningmonk.com github.com/theburningmonk
  • Titaye

    Aug. 4, 2015
  • kinggudu

    Aug. 3, 2015
  • yanshuai

    Jul. 31, 2015
  • orendon

    Jul. 30, 2015
  • phodek

    Jul. 30, 2015
  • soyrochus

    Jul. 30, 2015
  • jumtanaka

    Jul. 26, 2015
  • MattPD1

    Jul. 18, 2015
  • teramonagi

    Jul. 7, 2015
  • matarillo

    Jul. 7, 2015
  • pmonster

    Jul. 7, 2015
  • nickersPL

    Jul. 7, 2015
  • praveennerd

    Jul. 7, 2015

Views

Total views

4,979

On Slideshare

0

From embeds

0

Number of embeds

2,222

Actions

Downloads

22

Shares

0

Comments

0

Likes

13

×