elasticmq: a fully asynchronous, akka-based sqs server

22
#DV13 #elasticmq @adamwarski ElasticMQ a fully async, Akka-based Amazon SQS server Adam Warski SoftwareMill Wednesday 13 November 13

Upload: adam-warski

Post on 11-May-2015

2.909 views

Category:

Technology


0 download

DESCRIPTION

Presentation from Devoxx 2013 on ElasticMQ (an in-memory implementation of Amazon SQS), with some technical details on how Scala, Akka and Spray are used to create a fully reactive service.

TRANSCRIPT

Page 1: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

ElasticMQ a fully async, Akka-based

Amazon SQS serverAdam WarskiSoftwareMill

Wednesday 13 November 13

Page 2: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

What is Amazon SQS?

• MQ-as-a-service

• Send, Receive, Delete

• At-least-once delivery

Wednesday 13 November 13

Page 3: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

How to test SQS apps?

1. Don’t?

Wednesday 13 November 13

Page 4: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

How to test SQS apps?

2. Just use SQS?

Wednesday 13 November 13

Page 5: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

How to test SQS apps?

3. Use a local SQS server

Wednesday 13 November 13

Page 6: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

ElasticMQ

• (relevant) subset of SQS

• In-memory

• Lightweight

Wednesday 13 November 13

Page 7: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

$  java  -­‐jar  elasticmq-­‐server-­‐0.7.1.jar

[main]  INFO    org.elasticmq.server.Main$  -­‐  Starting  ElasticMQ  server  (0.7.1)  ...

[main]  INFO    o.e.rest.sqs.TheSQSRestServerBuilder  -­‐  Started  SQS  rest  server,  bind  address  0.0.0.0:9324,  visible  server  address  http://localhost:9324

[main]  INFO    org.elasticmq.server.Main$  -­‐  ===  ElasticMQ  server  (0.7.1)  started  in  1444  ms  ===

Stand-alone

Wednesday 13 November 13

Page 8: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

import  com.amazonaws.auth.BasicAWSCredentialsimport  com.amazonaws.services.sqs.AmazonSQSClient

client  =  new  AmazonSQSClient(new  BasicAWSCredentials("x",  "x"))client.setEndpoint("http://localhost:9324")

val  queueUrl  =  client.createQueue(new  CreateQueueRequest("testQueue1"))

client.sendMessage(new  SendMessageRequest(queueUrl,  "Hello!"))

Using ElasticMQ

Wednesday 13 November 13

Page 9: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

<dependency>      <groupId>org.elasticmq</groupId>      <artifactId>elasticmq-­‐rest-­‐sqs_2.10</artifactId>      <version>0.7.1</version></dependency>

val  server  =  SQSRestServerBuilder      .withPort(9325)      .withInterface("localhost")      .start()

//  ...  use  ...

server.stopAndWait()

Embedded

Wednesday 13 November 13

Page 10: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

That’s all!Thanks!

Wednesday 13 November 13

Page 11: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarskiWednesday 13 November 13

Page 12: ElasticMQ: a fully asynchronous, Akka-based SQS server

@adamwarski#DV13 #elasticmq

Technologies

• Scala• Akka• Spray

➡ reactive

Wednesday 13 November 13

Page 13: ElasticMQ: a fully asynchronous, Akka-based SQS server

@adamwarski#DV13 #elasticmq

Asynchronous: why?

• Traditional model could work well?

• Long polling

Wednesday 13 November 13

Page 14: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

import  spray.routing.SimpleRoutingApp

val  routes  =  sendMessage  ~  receiveMessage  ~  createQueue  ~  ...

val  app  =  new  SimpleRoutingApp  {}app.startServer(interface,  port,  "...")  {      routes}

Receive message walk-through

Wednesday 13 November 13

Page 15: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

val  receiveMessage  =    action("ReceiveMessage")  {                        //  path("")  and  param()        param("VisibilityTimeout".as[Int]?,                        "WaitTimeSeconds".as[Long]?)  {            (visibilityTimeout,  waitTimeSeconds)  =>                respondWithMediaType(MediaTypes.`text/xml`)  {                //  inner  route:  RequestContext  =>  Unit                        }        }    }

Receive message walk-through

Wednesday 13 November 13

Page 16: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

//  inner  route:  RequestContext  =>  Unitctx:  RequestContext  =>    val  actorMsg  =  ReceiveMessages(visibilityTimeout,                                                                      waitTimeSeconds)

   val  msgs:  Future[List[Message]]  =  queueActor  ?  actorMsg

   msgs.map  {  msgs  =>        ctx.complete(            <ReceiveMessageResponse>                ...            </ReceiveMessageResponse>          )  }

Receive message walk-through

Wednesday 13 November 13

Page 17: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

import  akka.actor.{Actor,  ActorRef}

class  QueueActor  extends  Actor  {    val  messageQueue  =  mutable.PriorityQueue[InternalMessage]()    val  awaiting  =  mutable.PriorityQueue[ActorRef]()

   def  receive  =  {        case  ReceiveMessages(...)  =>  {            //  if  there  are  messages,  reply            //  otherwise  put  the  sender  aside          //  schedule  a  timeout  in  20  seconds

   }  }  }

Receive message walk-through

Wednesday 13 November 13

Page 18: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

Dataflow

• Write async code as if it was sync!

• Many Futures, if-s => trouble

• Alternative: Scala Async

Wednesday 13 November 13

Page 19: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

val  result:  Future[ActorRef]  =  flow  {  (queueManager  ?  Lookup(name)).apply()  match  {      case  Some(queueActor)  =>  queueActor      case  None  =>            val  createFuture  =  queueManager  ?  Create(name)          createFuture.apply()  }}

Dataflow

Wednesday 13 November 13

Page 20: ElasticMQ: a fully asynchronous, Akka-based SQS server

@adamwarski#DV13 #elasticmq

Links

• http://github.com/adamw/elasticmq

• http://akka.io/

• http://spray.io/

• http://warski.org

Wednesday 13 November 13

Page 21: ElasticMQ: a fully asynchronous, Akka-based SQS server

#DV13 #elasticmq @adamwarski

There’s more!

• “The ideal module system and the harsh reality”

• Today, 17:50, Room 9

Wednesday 13 November 13

Page 22: ElasticMQ: a fully asynchronous, Akka-based SQS server

@adamwarski#DV13 #elasticmq

Thank you; Come & get a sticker

http://codebrag.com/devoxx/Wednesday 13 November 13