/examples/streams.fsx

https://github.com/Horusiath/Akkling · F# · 112 lines · 77 code · 26 blank · 9 comment · 0 complexity · 396371c76a7196e975f3a286d457263c MD5 · raw file

  1. #r "nuget: Akka.Serialization.Hyperion"
  2. #r "nuget: Akka.Streams"
  3. #r "nuget: Akkling"
  4. #r "nuget: Akkling.Streams"
  5. open System
  6. open Akka.Streams
  7. open Akka.Streams.Dsl
  8. open Akkling
  9. open Akkling.Streams
  10. let system = System.create "streams-sys" <| Configuration.defaultConfig()
  11. let mat = system.Materializer()
  12. let text = """
  13. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
  14. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
  15. when an unknown printer took a galley of type and scrambled it to make a type
  16. specimen book."""
  17. // 1. Basic stream transformation
  18. Source.ofArray (text.Split())
  19. |> Source.map (fun x -> x.ToUpper())
  20. |> Source.filter (String.IsNullOrWhiteSpace >> not)
  21. |> Source.runForEach mat (printfn "%s")
  22. |> Async.RunSynchronously
  23. // 2. Actor interop
  24. let behavior targetRef (m:Actor<_>) =
  25. let rec loop () = actor {
  26. let! msg = m.Receive ()
  27. targetRef <! msg
  28. return! loop ()
  29. }
  30. loop ()
  31. let spawnActor targetRef =
  32. spawnAnonymous system <| props (behavior targetRef)
  33. let s = Source.actorRef OverflowStrategy.DropNew 1000
  34. |> Source.mapMaterializedValue(spawnActor)
  35. |> Source.toMat(Sink.forEach(fun s -> printfn "Received: %s" s)) Keep.left
  36. |> Graph.run mat
  37. s <! "Boo"
  38. // 3. Dynamic streams
  39. let sink = Sink.forEach (printfn "%s")
  40. let consumer =
  41. Source.mergeHub 10
  42. |> Source.toMat sink Keep.left
  43. |> Graph.run mat
  44. Source.singleton "hello" |> Source.runWith mat consumer
  45. Source.singleton "world" |> Source.runWith mat consumer
  46. // 4. TCP stream
  47. open Akka.Streams.Dsl
  48. // server
  49. let echo = Flow.id
  50. async {
  51. //let! server =
  52. // system.TcpStream()
  53. // |> Tcp.bindAndHandle mat "localhost" 5000 echo
  54. let handler = Sink.forEach (fun (conn: Tcp.IncomingConnection) ->
  55. printfn "New client connected (local: %A, remote: %A)" conn.LocalAddress conn.RemoteAddress
  56. conn.HandleWith(echo, mat))
  57. let! server =
  58. system.TcpStream()
  59. |> Tcp.bind "localhost" 5000
  60. |> Source.toMat handler Keep.left
  61. |> Graph.run mat
  62. printfn "TCP server listetning on %A" server.LocalAddress
  63. Console.ReadLine() |> ignore
  64. do! server.AsyncUnbind()
  65. } |> Async.RunSynchronously
  66. // client
  67. open Akka.IO
  68. let parser =
  69. Flow.id
  70. |> Flow.takeWhile ((<>) "q")
  71. |> Flow.concat (Source.singleton "BYE")
  72. |> Flow.map (fun x -> ByteString.FromString(x + "\n"))
  73. let repl =
  74. Framing.delimiter true 256 (ByteString.FromString("\n"))
  75. |> Flow.map string
  76. |> Flow.iter (printfn "Server: %s")
  77. |> Flow.map (fun _ -> Console.ReadLine())
  78. |> Flow.via parser
  79. async {
  80. let! client =
  81. system.TcpStream()
  82. |> Tcp.outgoing "localhost" 5000
  83. |> Flow.join repl
  84. |> Graph.run mat
  85. printfn "Client connected (local: %A, remote: %A)" client.LocalAddress client.RemoteAddress
  86. } |> Async.RunSynchronously