The third example completing the request in another Actor is exactly what I 
needed! Thanks a lot!
But when I previously tried passing the request to an actor without a 
promise, it compiled but didn't complete the request :(

Now it works exactly as I want. 

class TestActorTwo extends Actor with SprayLikeRest {

  override def receive: Receive = {
    
    case (req: ImperativeRequestContext, msg: String) => {
      req.complete(HttpResponse(StatusCodes.OK, entity = s"Completed before 
sleep: $msg"))
      Thread.sleep(2000)
      req.complete(HttpResponse(StatusCodes.OK, entity = s"Completed after 
sleep: $msg"))
    }
    case x => println(x)

  }

}


Now the response the client gets is the one before Thread.sleep part. But 
previously, when I didn't use any promise but just used "ask", it returned 
the last line that was returned. Can you please explain why that happens?


On Tuesday, December 20, 2016 at 2:11:29 PM UTC+2, Julien L. wrote:
>
> I'm not sure but maybe this article could help you on "how to complete a 
> request directly from an actor" : 
> https://markatta.com/codemonkey/blog/2016/08/03/actor-per-request-with-akka-http/
>
>
>
> On Tuesday, December 20, 2016 at 12:46:18 PM UTC+1, Konrad Malawski wrote:
>>
>> As I've said, this is a feature in comparison with Spray.
>> We explicitly chose to require completing. In Spray it was possible to 
>> forget completing requests, how it's statically enforced.
>>
>> No need to do this:
>>
>>     get { ctx =>
>>
>>
>> It's as simple as: 
>>
>> val f = Future("")
>> onComplete(f) {
>>   case Success(s) => complete("YAY " + s)
>>   case Failure(ex) => complete("OY...")
>> }
>>
>>
>> or simply
>>
>> val f = Future("")
>> complete(f)
>>
>> If you don't need full control over the failure case, it'd just render an 
>> 500 page if fails.
>>
>> Promise is simply
>>
>> val p = Promise[String]()
>>
>> someone ! PleaseCompleteThis(p)
>>
>> onComplete(p.future) {
>>   case Success(s) => complete("YAY " + s)
>>   case Failure(ex) => complete("OY...")
>> }
>>
>>
>> Happy hakking.
>>
>> Please read the docs of those directives, they all have examples :)
>> -- 
>> Konrad `ktoso` Malawski
>> Akka <http://akka.io> @ Lightbend <http://lightbend.com>
>>
>> On 20 December 2016 at 12:40:56, Sid Feiner (sidf...@gmail.com) wrote:
>>
>> And are there any plans on allowing us to call `complete` outside of the 
>> router? Or is that the way it'll always be with akka-http? 
>>
>> And about the first option, I tried using onComplete and it didn't work:
>>
>> pathPrefix("messaging-service") {
>>   pathPrefix("test") {
>>     get { ctx =>
>>       val f = (testActor ? "Hello").mapTo[RouteResult]
>>       onComplete(f) {
>>         case Success(result) => ctx.complete(StatusCodes.OK)
>>         case Failure(ex) => ctx.complete(StatusCodes.InternalServerError)
>>       }
>>     }
>>   }
>> }
>>
>>
>> And I get the following error from the compiler:
>> Error:(84, 49) type mismatch;
>>  found   : scala.concurrent.Future[akka.http.scaladsl.server.RouteResult]
>>  required: akka.http.scaladsl.server.RequestContext => 
>> scala.concurrent.Future[akka.http.scaladsl.server.RouteResult]
>>             case Success(result) => ctx.complete(StatusCodes.OK)
>>
>>
>>
>> On Tuesday, December 20, 2016 at 11:40:56 AM UTC+2, Konrad Malawski 
>> wrote: 
>>>
>>> Either of the two work. Use ask to integrate with the Actor.
>>>
>>> The complete has to be in the route - yes. This is a feature we added 
>>> while we reflected on this while moving Spray to become Akka HTTP.
>>> In Spray people would forget to call complete() and it would still 
>>> compile, now you have to complete in the routes.
>>>
>>> -- 
>>> Konrad `ktoso` Malawski
>>> Akka <http://akka.io> @ Lightbend <http://lightbend.com>
>>>
>>> On 20 December 2016 at 10:36:11, Sid Feiner (sidf...@gmail.com) wrote:
>>>
>>> Hey, I've posted this question also on Stack Overflow but I'll post it 
>>> here as well as I have a bigger chance of getting help :) 
>>>
>>> I am pretty new to the Akka world and I have to migrate a project from 
>>> Spray to akka-http.
>>>
>>> In spray, a route was of type Route = RequestContext ⇒ Unit.
>>> But in akka-http, it is of type Route = RequestContext ⇒ 
>>> Future[RouteResult].
>>>
>>> So in spray, we would often handle and complete our requests through a 
>>> chain of Actors (outside of the main controller) using only fire-and-forget 
>>> so we didn't have to "ask" and the performance was great. Now, we have to 
>>> use "ask" every time we pass the request to another Actor (correct me if 
>>> I'm wrong)
>>>
>>> I've been searching a lot and I found a few options which I'm not sure 
>>> if they fully satisfy me (the need to complete a request in another Actor 
>>> without the need to return it back to the controller). So that's where you 
>>> could help me :)
>>>
>>>
>>> *Option 1: Using onSuccess/onComplete* 
>>> Does using this block my main controller from receiving more requests?
>>>
>>>
>>> *Option 2: Using Futures and using RouteResult.Complete*
>>>
>>> I've found the following example at How to complete a request in 
>>> another actor when using akka-http 
>>> <http://stackoverflow.com/questions/32011503>:
>>>
>>> import akka.actor.{ActorSystem, Actor, Props}import akka.pattern.askimport 
>>> akka.stream.ActorMaterializerimport akka.http.scaladsl.Httpimport 
>>> akka.http.scaladsl.server.Directives._import 
>>> akka.http.scaladsl.server.{RequestContext, RouteResult}import 
>>> scala.concurrent.Futureimport akka.http.scaladsl.model.HttpResponseimport 
>>> akka.util.Timeout
>>> class RequestActor extends Actor {
>>>
>>>   //business logic - returns empty HttpResponse
>>>   def handleRequestMessage(requestContext : RequestContext) =   
>>>     RouteResult.Complete(new HttpResponse())
>>>
>>>   override def receive = {
>>>     case reqContext : RequestContext =>   
>>>       sender ! handleRequestMessage(reqContext)
>>>   }}//end class RequestActor
>>> object RouteActorTest extends App {
>>>   implicit val as = ActorSystem("RouteActorTest")
>>>   implicit val timeout = new Timeout(1000)
>>>
>>>   val actorRef = as actorOf Props[RequestActor]
>>>
>>>   def handleRequest(reqContext : RequestContext) : Future[RouteResult] =
>>>     ask(actorRef,reqContext).mapTo[RouteResult]        
>>>
>>>   val route = path("") { get(handleRequest) }
>>>
>>>   //rest of application...
>>> }//end object RouteActorTest
>>>
>>>
>>> But this actually passes the response back every time to the previous 
>>> Actor (the sender) until it reaches the main controller. Another thing 
>>> about this option is that in the code, it says:
>>>
>>> /**
>>>  * The result of handling a request.
>>>  *
>>>  * As a user you typically don't create RouteResult instances directly.
>>>  * Instead, use the methods on the [[RequestContext]] to achieve the 
>>> desired effect.
>>>  */
>>>
>>> So I'm not sure if it's a recommended way of doing it.
>>>
>>>
>>> I've tried using requestContext.complete() in another actor but it 
>>> doesn't work (no error thrown, simply doesn't send response) Does anybody 
>>> know what the best way is to implement the previous architecture we had - 
>>> The ability to fire-and-forget the request between Actors and completing it 
>>> any Actor I want?
>>>
>>> Thanks a lot!
>>> --
>>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>>> >>>>>>>>>> Check the FAQ: 
>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>> >>>>>>>>>> Search the archives: 
>>> https://groups.google.com/group/akka-user
>>> ---
>>> You received this message because you are subscribed to the Google 
>>> Groups "Akka User List" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to akka-user+...@googlegroups.com.
>>> To post to this group, send email to akka...@googlegroups.com.
>>> Visit this group at https://groups.google.com/group/akka-user.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>> --
>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>> >>>>>>>>>> Check the FAQ: 
>> http://doc.akka.io/docs/akka/current/additional/faq.html
>> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
>> ---
>> You received this message because you are subscribed to the Google Groups 
>> "Akka User List" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to akka-user+...@googlegroups.com.
>> To post to this group, send email to akka...@googlegroups.com.
>> Visit this group at https://groups.google.com/group/akka-user.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to