Actor Based Asyncronous IO in Akka

4,960
-1

Published on

Asynchronous IO is one of the most important building blocks when designing high-performance systems. Over the years various patterns emerged on top of the selector based services provided by the operating system. In this talk I will give a quick overview of the most important asynchronous IO patterns from callbacks to iteratees. Finally I will show how these approaches map to the actor world, introducing the new IO model designed by the Akka and Spray team available in Akka 2.2.

Published in: Technology, Business

Actor Based Asyncronous IO in Akka

  1. 1. ––
  2. 2. ––––
  3. 3. ––
  4. 4. while (hasData) {output.write(someData) // Blocks until complete}
  5. 5. while (input.isOpen) {val event = input.read() // Blocks until event arriveshandleEvent(event) // Dispatch event}
  6. 6. ––
  7. 7. output.write(someData).onComplete { success =>// What should I do here???}
  8. 8.
  9. 9. –––
  10. 10. ––
  11. 11. 
  12. 12. class SimpleSender(remote: InetSocketAddress)extends Actor {IO(Udp) ! Udp.SimpleSender // Acquire a managerdef receive = {case Udp.SimpleSenderReady ⇒context.become(ready(sender))}def ready(socket: ActorRef): Receive = {case msg: String ⇒socket ! Udp.Send(ByteString(msg), remote)}}
  13. 13. IO(Udp) ! Udp.Bind(self,new InetSocketAddress("localhost", 53))def receive = {case Udp.Bound(local) ⇒context.become(ready(sender))}def ready(socket: ActorRef): Receive = {case Udp.Received(data, remote) ⇒// Process data}
  14. 14. –
  15. 15. –––
  16. 16. –––
  17. 17. def receive = {case SendIt(data) ⇒buffer(data)connection ! Write(data, Ack)context.become({case SendIt(data) ⇒ buffer(data)case Ack ⇒// Start serving from buffer …}, discardOld = false)case PeerClosed ⇒ context stop self}
  18. 18. ––––
  19. 19. ––––
  20. 20. class MyStageextends PipelineStage[Ctxt, CmdAbove, CmdBelow, EvtAbove, EvtBelow]
  21. 21. class MyStageextends PipelineStage[Ctxt, CmdAbove, CmdBelow, EvtAbove, EvtBelow]
  22. 22. override def apply(ctx: PipelineContext) = new PipePair[CmdAbove,CmdBelow, EvtAbove, EvtBelow] {override val commandPipeline = {cmdAbove: CmdAbove ⇒ ctx.singleCommand(someCmdBelow)}override val eventPipeline = {evtBelow: EvtBelow ⇒ ctx.singleEvent(someEvtAbove)}}
  23. 23. val init = TcpPipelineHandler.withLogger(log,new StringByteStringAdapter("utf-8") >>new DelimiterFraming(maxSize = 1024, delimiter = ByteString(n)) >>new TcpReadWriteAdapter >>new BackpressureBuffer(lowBytes = 100,highBytes = 1000,maxBytes = 10000))val pipeline = context.actorOf(TcpPipelineHandler.props(init, connectionActor, userListenerActor))

×