scala - How does spray.routing.HttpService dispatch requests? -


disclaimer: have no scala experience now, question connected basics.

consider following example (it may incomplete):

import akka.actor.{actorsystem, props} import akka.io.io import spray.can.http import akka.pattern.ask import akka.util.timeout import scala.concurrent.duration._ import akka.actor.actor import spray.routing._ import spray.http._  object boot extends app {   implicit val system = actorsystem("my-actor-system")   val service = system.actorof(props[myactor], "my")   implicit val timeout = timeout(5.seconds)   io(http) ? http.bind(service, interface = "localhost", port = 8080) }  class myactor extends actor myservice {   def actorreffactory = context    def receive = runroute(myroute) }  trait myservice extends httpservice {   val myroute =     path("my") {       post {         complete {           "pong"         }       }     } } 

my question is: happens when control reaches complete block? question seems general, let me split it.

  1. i see creation of single actor in example. mean application single-threaded , uses 1 cpu core?
  2. what happens if blocking call inside complete?
  3. if p. 1 true , p. 2 block, how dispatch requests utilize cpus? see 2 ways: actor per request , actor per connection. second 1 seems reasonable, cannot find way using spray library.
  4. if previous question irrelevant, detach directive do? , passing function returning future complete directive? difference between detach , passing function returning future?
  5. what proper way configure number of working threads , balance requests/connections?

it great if point me explanations in official documentation. extensive , believe missing something.

thank you.

it's answered here mathias - 1 of spray authors. copying reply reference:

in end thing completes request call requestcontext.complete. thereby doesn't matter thread or actor context call made from. matters happen within configured "request-timeout" period. can of course issue call in way or another, spray gives number of pre-defined constructs maybe fit architecture better passing actual requestcontext around. these are:

  1. the complete directive, provides sugar on top of "raw" ctx => ctx.complete(…) function literal.
  2. the future marshaller, calls ctx.complete future.oncomplete handler.
  3. the produce directive, extracts function t => unit can later used complete request instance of custom type.

architecturally, in cases, it's idea not have api layer "leak into" core of application. i.e. application should not know api layer or http. should deal objects of own domain model. therefore passing requestcontext directly application core not best solution.

resorting "ask" , relying on future marshaller obvious, understood , rather easy alternative. comes (small) drawback ask comes mandatory timeout check logically isn't required (since spray-can layer takes care of request timeouts). timeout on ask required technical reasons (so underlying promiseactorref can cleaned if expected reply never comes).

another alternative passing requestcontext around produce directive (e.g. produce(instanceof[foo]) { completer => …). extracts function can pass on application core. when core logic calls complete(foo) completion logic run , request completed. thereby application core remains decoupled api layer , overhead minimal. drawbacks of approach twofold: first completer function not serializable, cannot use approach across jvm boundaries. , secondly completion logic running directly in actor context of application core, might change runtime behavior in unwanted ways if marshaller[foo] has non-trivial tasks.

a third alternative spawn per-request actor in api layer , have handle response coming application core. not have use ask. still, end same problem promiseactorref underlying ask has: how clean if no response ever comes application core? re-request actor have full freedom implement solution question. however, if decide rely on timeout (e.g. via context.setreceivetimeout) benefits on "ask" might non-existent.

which of described solutions best fits architecture need decide yourself. however, able show, have couple of alternatives choose from.

to answer of specific questions: there single actor/handler services route if make block spray block. means want either complete route or dispatch work using either of 3 options above.

there many examples on web these 3 options. easiest wrap code in future. check "actor per request" option/example. in end architecture define appropriate way go.

finally, spray runs on top of akka, akka configuration still applies. see hocon reference.conf , application.conf actor threading settings.


Comments

Popular posts from this blog

php - Admin SDK -- get information about the group -

dns - How To Use Custom Nameserver On Free Cloudflare? -

Python Error - TypeError: input expected at most 1 arguments, got 3 -