WS.Response response = httpreq.get(); // blocks until request completes
JsonNode documentReferences = response.asJson().get("documents"); My question is, does this allow the server to service other clients on the same thread while waiting for the response? My understanding is that Play keeps a pool of N+1 threads for N cores, and uses these async waiting points to allocate the same thread to other clients while the first request is waiting on a response from elsewhere. Do I need to use the async/callback method to make this work, or is promise.get() fine?
> My question is, does this allow the server to service other clients on the
> same thread while waiting for the response? My understanding is that Play
> keeps a pool of N+1 threads for N cores, and uses these async waiting points
> to allocate the same thread to other clients while the first request is
> waiting on a response from elsewhere. Do I need to use the async/callback
> method to make this work, or is promise.get() fine?
> - Jonathan
> --
> You received this message because you are subscribed to the Google Groups
> "play-framework" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/play-framework/-/egckmYkCbQAJ.
> To post to this group, send email to play-framework@googlegroups.com.
> To unsubscribe from this group, send email to
> play-framework+unsubscribe@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/play-framework?hl=en.
Hi, my questions pertains to this exact problem Jonathan has introduced, but from a different angle and I haven't been able to find a solution (at least not of the kind that would enlighten me) online. Namely, while it is self-evident, how you get to a JsonNode (or any other data) in the second Jonathan's example, I can't seem to get my head around comprehending, how do you get a JsonNode or any other data out of the async() method through Java libraries? All the examples I have come across only deal with returning a Result with an ok() method.
Using F.Promise's get() blocks the thread (or at least so I understand) and as such obviously negates one of the Play!'s fortes, while async() as per my understanding only takes Promise<Result> as an argument and returns AsyncResult exclusively, and neither Result nor AsyncResult seem to offer any usable method. Is there any way to collect/fetch data from Result or AsyncResult that I am not aware of? Or is there an altogether different way of tackling this?
On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
> Hi, my questions pertains to this exact problem Jonathan has introduced, > but from a different angle and I haven't been able to find a solution (at > least not of the kind that would enlighten me) online. Namely, while it is > self-evident, how you get to a JsonNode (or any other data) in the second > Jonathan's example, I can't seem to get my head around comprehending, how > do you get a JsonNode or any other data out of the async() method through > Java libraries? All the examples I have come across only deal with > returning a Result with an ok() method.
> Using F.Promise's get() blocks the thread (or at least so I understand) > and as such obviously negates one of the Play!'s fortes, while async() as > per my understanding only takes Promise<Result> as an argument and returns > AsyncResult exclusively, and neither Result nor AsyncResult seem to offer > any usable method. Is there any way to collect/fetch data from Result or > AsyncResult that I am not aware of? Or is there an altogether different way > of tackling this?
On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
> I also have the same question. Especially when you have to perform more > actions on the result from the WS call before returning a result to the > user?
> AsyncResult won't allow you to do that so you're left with blocking the > server.
> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>> Hi, my questions pertains to this exact problem Jonathan has introduced, >> but from a different angle and I haven't been able to find a solution (at >> least not of the kind that would enlighten me) online. Namely, while it is >> self-evident, how you get to a JsonNode (or any other data) in the second >> Jonathan's example, I can't seem to get my head around comprehending, how >> do you get a JsonNode or any other data out of the async() method through >> Java libraries? All the examples I have come across only deal with >> returning a Result with an ok() method.
>> Using F.Promise's get() blocks the thread (or at least so I understand) >> and as such obviously negates one of the Play!'s fortes, while async() as >> per my understanding only takes Promise<Result> as an argument and returns >> AsyncResult exclusively, and neither Result nor AsyncResult seem to offer >> any usable method. Is there any way to collect/fetch data from Result or >> AsyncResult that I am not aware of? Or is there an altogether different way >> of tackling this?
I think you've fundamentally misunderstood how promises work. A promise says "at some point in future, I promise I will make one of these available." In the case of the WS API, that is a WS.Response, ie Promise<WS.Response>. When returning an async response to Play, you want to return a promise for a result, ie Promise<Result>. You can convert a Promise<WS.Response> to a Promise<Result> by calling the map function, which accepts a function that takes a WS.Response and returns a Result. This isn't invoked immediately, it's invoked when the first promise makes the WS.Response available. You could map it to something else first if you really wanted, and then map that thing to a promise, eg:
But that's a bit unnecessary, because you don't need the intermediate fooPromise, you could put your code that converts to/from json in the first map function. This is also, if you were to call other libraries, where you would put all that code. If you want to do another async operation (eg two WS calls), then you can use flatmap:
The thing to be aware, is once you start working with Promises, you can never directly work with the result, everything gets done in map() and flatMap().
There's a keynote presentation and example code here that I did for a Play user group:
> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>> I also have the same question. Especially when you have to perform more >> actions on the result from the WS call before returning a result to the >> user?
>> AsyncResult won't allow you to do that so you're left with blocking the >> server.
>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>> Hi, my questions pertains to this exact problem Jonathan has introduced, >>> but from a different angle and I haven't been able to find a solution (at >>> least not of the kind that would enlighten me) online. Namely, while it is >>> self-evident, how you get to a JsonNode (or any other data) in the second >>> Jonathan's example, I can't seem to get my head around comprehending, how >>> do you get a JsonNode or any other data out of the async() method through >>> Java libraries? All the examples I have come across only deal with >>> returning a Result with an ok() method.
>>> Using F.Promise's get() blocks the thread (or at least so I understand) >>> and as such obviously negates one of the Play!'s fortes, while async() as >>> per my understanding only takes Promise<Result> as an argument and returns >>> AsyncResult exclusively, and neither Result nor AsyncResult seem to offer >>> any usable method. Is there any way to collect/fetch data from Result or >>> AsyncResult that I am not aware of? Or is there an altogether different way >>> of tackling this?
Do you happen to have a video or slides from that talk you gave? I have a very poor understanding of what should be wrapped in a promise and the docs are quite anemic on the topic. E.g. should all of my calls via the Mongo Jackson Mapper be wrapped in promises? Or just external HTTP requests? How long should an action take before it is recommended to wrap it in a promise? Why not just wrap every single request in a promise? I'm having a really hard time understanding what tradeoffs are in play here.
On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
> I think you've fundamentally misunderstood how promises work. A promise > says "at some point in future, I promise I will make one of these > available." In the case of the WS API, that is a WS.Response, ie > Promise<WS.Response>. When returning an async response to Play, you want > to return a promise for a result, ie Promise<Result>. You can convert a > Promise<WS.Response> to a Promise<Result> by calling the map function, > which accepts a function that takes a WS.Response and returns a Result. > This isn't invoked immediately, it's invoked when the first promise makes > the WS.Response available. You could map it to something else first if you > really wanted, and then map that thing to a promise, eg:
> But that's a bit unnecessary, because you don't need the intermediate > fooPromise, you could put your code that converts to/from json in the first > map function. This is also, if you were to call other libraries, where you > would put all that code. If you want to do another async operation (eg two > WS calls), then you can use flatmap:
> The thing to be aware, is once you start working with Promises, you can > never directly work with the result, everything gets done in map() and > flatMap().
> There's a keynote presentation and example code here that I did for a Play > user group:
>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>> I also have the same question. Especially when you have to perform more >>> actions on the result from the WS call before returning a result to the >>> user?
>>> AsyncResult won't allow you to do that so you're left with blocking the >>> server.
>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>> Hi, my questions pertains to this exact problem Jonathan has >>>> introduced, but from a different angle and I haven't been able to find a >>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>> the second Jonathan's example, I can't seem to get my head around >>>> comprehending, how do you get a JsonNode or any other data out of the >>>> async() method through Java libraries? All the examples I have come across >>>> only deal with returning a Result with an ok() method.
>>>> Using F.Promise's get() blocks the thread (or at least so I understand) >>>> and as such obviously negates one of the Play!'s fortes, while async() as >>>> per my understanding only takes Promise<Result> as an argument and returns >>>> AsyncResult exclusively, and neither Result nor AsyncResult seem to offer >>>> any usable method. Is there any way to collect/fetch data from Result or >>>> AsyncResult that I am not aware of? Or is there an altogether different way >>>> of tackling this?
On Sunday, September 2, 2012 11:43:00 PM UTC+2, Ben McCann wrote:
> Hi James,
> Do you happen to have a video or slides from that talk you gave? I have a > very poor understanding of what should be wrapped in a promise and the docs > are quite anemic on the topic. E.g. should all of my calls via the Mongo > Jackson Mapper be wrapped in promises? Or just external HTTP requests? > How long should an action take before it is recommended to wrap it in a > promise? Why not just wrap every single request in a promise? I'm having > a really hard time understanding what tradeoffs are in play here.
> Thanks, > Ben
> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>> I think you've fundamentally misunderstood how promises work. A promise >> says "at some point in future, I promise I will make one of these >> available." In the case of the WS API, that is a WS.Response, ie >> Promise<WS.Response>. When returning an async response to Play, you want >> to return a promise for a result, ie Promise<Result>. You can convert a >> Promise<WS.Response> to a Promise<Result> by calling the map function, >> which accepts a function that takes a WS.Response and returns a Result. >> This isn't invoked immediately, it's invoked when the first promise makes >> the WS.Response available. You could map it to something else first if you >> really wanted, and then map that thing to a promise, eg:
>> But that's a bit unnecessary, because you don't need the intermediate >> fooPromise, you could put your code that converts to/from json in the first >> map function. This is also, if you were to call other libraries, where you >> would put all that code. If you want to do another async operation (eg two >> WS calls), then you can use flatmap:
>> The thing to be aware, is once you start working with Promises, you can >> never directly work with the result, everything gets done in map() and >> flatMap().
>> There's a keynote presentation and example code here that I did for a >> Play user group:
>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>> I also have the same question. Especially when you have to perform more >>>> actions on the result from the WS call before returning a result to the >>>> user?
>>>> AsyncResult won't allow you to do that so you're left with blocking the >>>> server.
>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>> Hi, my questions pertains to this exact problem Jonathan has >>>>> introduced, but from a different angle and I haven't been able to find a >>>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>>> the second Jonathan's example, I can't seem to get my head around >>>>> comprehending, how do you get a JsonNode or any other data out of the >>>>> async() method through Java libraries? All the examples I have come across >>>>> only deal with returning a Result with an ok() method.
>>>>> Using F.Promise's get() blocks the thread (or at least so I >>>>> understand) and as such obviously negates one of the Play!'s fortes, while >>>>> async() as per my understanding only takes Promise<Result> as an argument >>>>> and returns AsyncResult exclusively, and neither Result nor AsyncResult >>>>> seem to offer any usable method. Is there any way to collect/fetch data >>>>> from Result or AsyncResult that I am not aware of? Or is there an >>>>> altogether different way of tackling this?
On Wednesday, October 3, 2012 9:37:22 PM UTC+2, Nico wrote:
> +1 to see slides or other materials :-)
> And I also wonder why every actions are not wrapped into a Promise / async > by default ?..
> On Sunday, September 2, 2012 11:43:00 PM UTC+2, Ben McCann wrote:
>> Hi James,
>> Do you happen to have a video or slides from that talk you gave? I have >> a very poor understanding of what should be wrapped in a promise and the >> docs are quite anemic on the topic. E.g. should all of my calls via the >> Mongo Jackson Mapper be wrapped in promises? Or just external HTTP >> requests? How long should an action take before it is recommended to wrap >> it in a promise? Why not just wrap every single request in a promise? I'm >> having a really hard time understanding what tradeoffs are in play here.
>> Thanks, >> Ben
>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>> I think you've fundamentally misunderstood how promises work. A promise >>> says "at some point in future, I promise I will make one of these >>> available." In the case of the WS API, that is a WS.Response, ie >>> Promise<WS.Response>. When returning an async response to Play, you want >>> to return a promise for a result, ie Promise<Result>. You can convert a >>> Promise<WS.Response> to a Promise<Result> by calling the map function, >>> which accepts a function that takes a WS.Response and returns a Result. >>> This isn't invoked immediately, it's invoked when the first promise makes >>> the WS.Response available. You could map it to something else first if you >>> really wanted, and then map that thing to a promise, eg:
>>> But that's a bit unnecessary, because you don't need the intermediate >>> fooPromise, you could put your code that converts to/from json in the first >>> map function. This is also, if you were to call other libraries, where you >>> would put all that code. If you want to do another async operation (eg two >>> WS calls), then you can use flatmap:
>>> The thing to be aware, is once you start working with Promises, you can >>> never directly work with the result, everything gets done in map() and >>> flatMap().
>>> There's a keynote presentation and example code here that I did for a >>> Play user group:
>>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>>> I also have the same question. Especially when you have to perform >>>>> more actions on the result from the WS call before returning a result to >>>>> the user?
>>>>> AsyncResult won't allow you to do that so you're left with blocking >>>>> the server.
>>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>>> Hi, my questions pertains to this exact problem Jonathan has >>>>>> introduced, but from a different angle and I haven't been able to find a >>>>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>>>> the second Jonathan's example, I can't seem to get my head around >>>>>> comprehending, how do you get a JsonNode or any other data out of the >>>>>> async() method through Java libraries? All the examples I have come across >>>>>> only deal with returning a Result with an ok() method.
>>>>>> Using F.Promise's get() blocks the thread (or at least so I >>>>>> understand) and as such obviously negates one of the Play!'s fortes, while >>>>>> async() as per my understanding only takes Promise<Result> as an argument >>>>>> and returns AsyncResult exclusively, and neither Result nor AsyncResult >>>>>> seem to offer any usable method. Is there any way to collect/fetch data >>>>>> from Result or AsyncResult that I am not aware of? Or is there an >>>>>> altogether different way of tackling this?
Sorry, I completely missed this message a month ago.
There's no strict rules here, multiple solutions will work well, and it's very dependent on the profile of your app.
I don't have a video from the talk, there are keynote slides in the github repository but there's not much in them. I will probably be giving this talk again in the not too distant future at a conference that does record video, and it will go into more detail and I'll produce more comprehensive notes for it, so you'll be able to see it then.
I think a good start is that anything that relies on third party services should be asynchronous. There's nothing worse than your app going down because some other system completely outside of your control is not responding and tying up all your applications threads while you try to make calls on it. Calls to internal systems in your company are also good to make asynchronous, and I would always do that, means my services can't bring each other down so easily.
When it comes to talking to databases, for simple lookups that are entirely from indexes, then I'd say unless you have an asynchronous driver for that database, then it's probably not necessary to do things asynchronously. The exception to this is if you need to make many database calls per request, then doing them in parallel is a good idea. If you've got big queries, map reduces etc, then this may be good to do asynchronously too. And if you're doing lots of all of the above, then take a look at Akka, because with Akka you will have a lot more control over how many threads are devoted to doing what. Klout did a great blog post about this: http://corp.klout.com/blog/2012/10/scaling-the-klout-api-with-scala-a...
The final thing to be said, if you're doing Java, using promises or any sort of async stuff has a huge boiler plate overhead, and this needs to be considered, if your simplest code paths are just one anonymous class after another, then you are making large maintainability/code readability trade offs, and it might not be worth it. If doing Scala on the other hand, working with Promises is no harder than working with Options, and so from a code perspective, as long as you're comfortable with the concepts of map and flatmap, there's no disadvantage to using promises.
On Monday, 3 September 2012 07:43:00 UTC+10, Ben McCann wrote:
> Hi James,
> Do you happen to have a video or slides from that talk you gave? I have a > very poor understanding of what should be wrapped in a promise and the docs > are quite anemic on the topic. E.g. should all of my calls via the Mongo > Jackson Mapper be wrapped in promises? Or just external HTTP requests? > How long should an action take before it is recommended to wrap it in a > promise? Why not just wrap every single request in a promise? I'm having > a really hard time understanding what tradeoffs are in play here.
> Thanks, > Ben
> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>> I think you've fundamentally misunderstood how promises work. A promise >> says "at some point in future, I promise I will make one of these >> available." In the case of the WS API, that is a WS.Response, ie >> Promise<WS.Response>. When returning an async response to Play, you want >> to return a promise for a result, ie Promise<Result>. You can convert a >> Promise<WS.Response> to a Promise<Result> by calling the map function, >> which accepts a function that takes a WS.Response and returns a Result. >> This isn't invoked immediately, it's invoked when the first promise makes >> the WS.Response available. You could map it to something else first if you >> really wanted, and then map that thing to a promise, eg:
>> But that's a bit unnecessary, because you don't need the intermediate >> fooPromise, you could put your code that converts to/from json in the first >> map function. This is also, if you were to call other libraries, where you >> would put all that code. If you want to do another async operation (eg two >> WS calls), then you can use flatmap:
>> The thing to be aware, is once you start working with Promises, you can >> never directly work with the result, everything gets done in map() and >> flatMap().
>> There's a keynote presentation and example code here that I did for a >> Play user group:
>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>> I also have the same question. Especially when you have to perform more >>>> actions on the result from the WS call before returning a result to the >>>> user?
>>>> AsyncResult won't allow you to do that so you're left with blocking the >>>> server.
>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>> Hi, my questions pertains to this exact problem Jonathan has >>>>> introduced, but from a different angle and I haven't been able to find a >>>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>>> the second Jonathan's example, I can't seem to get my head around >>>>> comprehending, how do you get a JsonNode or any other data out of the >>>>> async() method through Java libraries? All the examples I have come across >>>>> only deal with returning a Result with an ok() method.
>>>>> Using F.Promise's get() blocks the thread (or at least so I >>>>> understand) and as such obviously negates one of the Play!'s fortes, while >>>>> async() as per my understanding only takes Promise<Result> as an argument >>>>> and returns AsyncResult exclusively, and neither Result nor AsyncResult >>>>> seem to offer any usable method. Is there any way to collect/fetch data >>>>> from Result or AsyncResult that I am not aware of? Or is there an >>>>> altogether different way of tackling this?
In actual fact, every action is wrapped in a promise/future, when Play receives a request, it passes it off to Akka to handle asynchronously. But as to whether your code in the action is asynchronous, well Play has no control over that, that's up to you. The reason why Play doesn't force you to return a Promise from every action is to make the simple case simple, otherwise every action where you didn't make some call into the promise API you'd have to wrap your result in Promise.pure().
On Thursday, 4 October 2012 05:37:22 UTC+10, Nico wrote:
> +1 to see slides or other materials :-)
> And I also wonder why every actions are not wrapped into a Promise / async > by default ?..
> On Sunday, September 2, 2012 11:43:00 PM UTC+2, Ben McCann wrote:
>> Hi James,
>> Do you happen to have a video or slides from that talk you gave? I have >> a very poor understanding of what should be wrapped in a promise and the >> docs are quite anemic on the topic. E.g. should all of my calls via the >> Mongo Jackson Mapper be wrapped in promises? Or just external HTTP >> requests? How long should an action take before it is recommended to wrap >> it in a promise? Why not just wrap every single request in a promise? I'm >> having a really hard time understanding what tradeoffs are in play here.
>> Thanks, >> Ben
>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>> I think you've fundamentally misunderstood how promises work. A promise >>> says "at some point in future, I promise I will make one of these >>> available." In the case of the WS API, that is a WS.Response, ie >>> Promise<WS.Response>. When returning an async response to Play, you want >>> to return a promise for a result, ie Promise<Result>. You can convert a >>> Promise<WS.Response> to a Promise<Result> by calling the map function, >>> which accepts a function that takes a WS.Response and returns a Result. >>> This isn't invoked immediately, it's invoked when the first promise makes >>> the WS.Response available. You could map it to something else first if you >>> really wanted, and then map that thing to a promise, eg:
>>> But that's a bit unnecessary, because you don't need the intermediate >>> fooPromise, you could put your code that converts to/from json in the first >>> map function. This is also, if you were to call other libraries, where you >>> would put all that code. If you want to do another async operation (eg two >>> WS calls), then you can use flatmap:
>>> The thing to be aware, is once you start working with Promises, you can >>> never directly work with the result, everything gets done in map() and >>> flatMap().
>>> There's a keynote presentation and example code here that I did for a >>> Play user group:
>>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>>> I also have the same question. Especially when you have to perform >>>>> more actions on the result from the WS call before returning a result to >>>>> the user?
>>>>> AsyncResult won't allow you to do that so you're left with blocking >>>>> the server.
>>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>>> Hi, my questions pertains to this exact problem Jonathan has >>>>>> introduced, but from a different angle and I haven't been able to find a >>>>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>>>> the second Jonathan's example, I can't seem to get my head around >>>>>> comprehending, how do you get a JsonNode or any other data out of the >>>>>> async() method through Java libraries? All the examples I have come across >>>>>> only deal with returning a Result with an ok() method.
>>>>>> Using F.Promise's get() blocks the thread (or at least so I >>>>>> understand) and as such obviously negates one of the Play!'s fortes, while >>>>>> async() as per my understanding only takes Promise<Result> as an argument >>>>>> and returns AsyncResult exclusively, and neither Result nor AsyncResult >>>>>> seem to offer any usable method. Is there any way to collect/fetch data >>>>>> from Result or AsyncResult that I am not aware of? Or is there an >>>>>> altogether different way of tackling this?
Due to the very reason of what James Roper mentioned in the amount of boiler plate code for Java we're staying completely non-async for now. Ended up following James Ward's blog on how to tune a Play 2 app for non-async (James works for Heroku) http://www.jamesward.com/2012/06/25/optimizing-play-2-for-database-dr.... All of our data comes off an in-house rest service from our CRM that is sitting directly on a DB. As much as we would have liked to go async, the Java code was going to be extremely thick as even our webapp text (which we cache in memcached) comes out of our CRM. Over time, we will start migrating our slower methods (methods that don't return within 1 sec) to async.
I would like to point out one very glaring issue that James Ward did not mention though - even though you've "tuned" the environment, as James Roper points out ALL requests are handed off to the Akka handler - from our testing - this appears to include static content! So say you have 20 threads, and all 20 are blocked at the moment, then 1 thread finishes and sends the result to the browser - the browser loads the HTML and sends requests back to the play server to get the static content referenced in the dynamic html output from play.. well, now your simple static content requests may be blocked waiting on those blocking akka calls to finish before it can return your simple static content! We experienced this in our testing using firebug and gatling. We were noticing that while running a gatling instance against our blocking app, we could load pages (with a wait time) but then noticed that the static resources in firebug were also blocking instead of being immediately returned! To fix this, we ended up going to a front-end apache server so play only deals with dynamic content now. If you went' all async, you wouldn't have to worry about this as Play encourages you to do. Ultimately, it would be nice if Play had a separate akka thread pool for static content so you never would be at risk for this happening.
If I'm wrong on any of this - please correct me! :-)
On Thursday, October 4, 2012 5:42:47 PM UTC-5, James Roper wrote:
> Hi Ben,
> Sorry, I completely missed this message a month ago.
> There's no strict rules here, multiple solutions will work well, and it's > very dependent on the profile of your app.
> I don't have a video from the talk, there are keynote slides in the github > repository but there's not much in them. I will probably be giving this > talk again in the not too distant future at a conference that does record > video, and it will go into more detail and I'll produce more comprehensive > notes for it, so you'll be able to see it then.
> I think a good start is that anything that relies on third party services > should be asynchronous. There's nothing worse than your app going down > because some other system completely outside of your control is not > responding and tying up all your applications threads while you try to make > calls on it. Calls to internal systems in your company are also good to > make asynchronous, and I would always do that, means my services can't > bring each other down so easily.
> When it comes to talking to databases, for simple lookups that are > entirely from indexes, then I'd say unless you have an asynchronous driver > for that database, then it's probably not necessary to do things > asynchronously. The exception to this is if you need to make many database > calls per request, then doing them in parallel is a good idea. If you've > got big queries, map reduces etc, then this may be good to do > asynchronously too. And if you're doing lots of all of the above, then > take a look at Akka, because with Akka you will have a lot more control > over how many threads are devoted to doing what. Klout did a great blog > post about this: > http://corp.klout.com/blog/2012/10/scaling-the-klout-api-with-scala-a...
> The final thing to be said, if you're doing Java, using promises or any > sort of async stuff has a huge boiler plate overhead, and this needs to be > considered, if your simplest code paths are just one anonymous class after > another, then you are making large maintainability/code readability trade > offs, and it might not be worth it. If doing Scala on the other hand, > working with Promises is no harder than working with Options, and so from a > code perspective, as long as you're comfortable with the concepts of map > and flatmap, there's no disadvantage to using promises.
> Cheers,
> James
> On Monday, 3 September 2012 07:43:00 UTC+10, Ben McCann wrote:
>> Hi James,
>> Do you happen to have a video or slides from that talk you gave? I have >> a very poor understanding of what should be wrapped in a promise and the >> docs are quite anemic on the topic. E.g. should all of my calls via the >> Mongo Jackson Mapper be wrapped in promises? Or just external HTTP >> requests? How long should an action take before it is recommended to wrap >> it in a promise? Why not just wrap every single request in a promise? I'm >> having a really hard time understanding what tradeoffs are in play here.
>> Thanks, >> Ben
>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>> I think you've fundamentally misunderstood how promises work. A promise >>> says "at some point in future, I promise I will make one of these >>> available." In the case of the WS API, that is a WS.Response, ie >>> Promise<WS.Response>. When returning an async response to Play, you want >>> to return a promise for a result, ie Promise<Result>. You can convert a >>> Promise<WS.Response> to a Promise<Result> by calling the map function, >>> which accepts a function that takes a WS.Response and returns a Result. >>> This isn't invoked immediately, it's invoked when the first promise makes >>> the WS.Response available. You could map it to something else first if you >>> really wanted, and then map that thing to a promise, eg:
>>> But that's a bit unnecessary, because you don't need the intermediate >>> fooPromise, you could put your code that converts to/from json in the first >>> map function. This is also, if you were to call other libraries, where you >>> would put all that code. If you want to do another async operation (eg two >>> WS calls), then you can use flatmap:
>>> The thing to be aware, is once you start working with Promises, you can >>> never directly work with the result, everything gets done in map() and >>> flatMap().
>>> There's a keynote presentation and example code here that I did for a >>> Play user group:
>>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>>> I also have the same question. Especially when you have to perform >>>>> more actions on the result from the WS call before returning a result to >>>>> the user?
>>>>> AsyncResult won't allow you to do that so you're left with blocking >>>>> the server.
>>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>>> Hi, my questions pertains to this exact problem Jonathan has >>>>>> introduced, but from a different angle and I haven't been able to find a >>>>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>>>> the second Jonathan's example, I can't seem to get my head around >>>>>> comprehending, how do you get a JsonNode or any other data out of the >>>>>> async() method through Java libraries? All the examples I have come across >>>>>> only deal with returning a Result with an ok() method.
>>>>>> Using F.Promise's get() blocks the thread (or at least so I >>>>>> understand) and as such obviously negates one of the Play!'s fortes, while >>>>>> async() as per my understanding only takes Promise<Result> as an argument >>>>>> and returns AsyncResult exclusively, and neither Result nor AsyncResult >>>>>> seem to offer any usable method. Is there any way to collect/fetch data >>>>>> from Result or AsyncResult that I am not aware of? Or is there an >>>>>> altogether different way of tackling this?
No you're right on this. What we probably should do is have a few different configuration profiles documented that a user can use. Out of the box, Play is tuned for async. We should make it very easy for the user to switch to a more traditional model, such as what most servlet containers use, where there is one large (150 threads) thread pool that handles all requests.
On Saturday, 6 October 2012 05:40:58 UTC+10, Ryan Means wrote:
> Due to the very reason of what James Roper mentioned in the amount of > boiler plate code for Java we're staying completely non-async for now. > Ended up following James Ward's blog on how to tune a Play 2 app for > non-async (James works for Heroku) > http://www.jamesward.com/2012/06/25/optimizing-play-2-for-database-dr.... > All of our data comes off an in-house rest service from our CRM that is > sitting directly on a DB. As much as we would have liked to go async, the > Java code was going to be extremely thick as even our webapp text (which we > cache in memcached) comes out of our CRM. Over time, we will start > migrating our slower methods (methods that don't return within 1 sec) to > async.
> I would like to point out one very glaring issue that James Ward did not > mention though - even though you've "tuned" the environment, as James Roper > points out ALL requests are handed off to the Akka handler - from our > testing - this appears to include static content! So say you have 20 > threads, and all 20 are blocked at the moment, then 1 thread finishes and > sends the result to the browser - the browser loads the HTML and sends > requests back to the play server to get the static content referenced in > the dynamic html output from play.. well, now your simple static content > requests may be blocked waiting on those blocking akka calls to finish > before it can return your simple static content! We experienced this in our > testing using firebug and gatling. We were noticing that while running a > gatling instance against our blocking app, we could load pages (with a wait > time) but then noticed that the static resources in firebug were also > blocking instead of being immediately returned! To fix this, we ended up > going to a front-end apache server so play only deals with dynamic content > now. If you went' all async, you wouldn't have to worry about this as Play > encourages you to do. Ultimately, it would be nice if Play had a separate > akka thread pool for static content so you never would be at risk for this > happening.
> If I'm wrong on any of this - please correct me! :-)
> On Thursday, October 4, 2012 5:42:47 PM UTC-5, James Roper wrote:
>> Hi Ben,
>> Sorry, I completely missed this message a month ago.
>> There's no strict rules here, multiple solutions will work well, and it's >> very dependent on the profile of your app.
>> I don't have a video from the talk, there are keynote slides in the >> github repository but there's not much in them. I will probably be giving >> this talk again in the not too distant future at a conference that does >> record video, and it will go into more detail and I'll produce more >> comprehensive notes for it, so you'll be able to see it then.
>> I think a good start is that anything that relies on third party services >> should be asynchronous. There's nothing worse than your app going down >> because some other system completely outside of your control is not >> responding and tying up all your applications threads while you try to make >> calls on it. Calls to internal systems in your company are also good to >> make asynchronous, and I would always do that, means my services can't >> bring each other down so easily.
>> When it comes to talking to databases, for simple lookups that are >> entirely from indexes, then I'd say unless you have an asynchronous driver >> for that database, then it's probably not necessary to do things >> asynchronously. The exception to this is if you need to make many database >> calls per request, then doing them in parallel is a good idea. If you've >> got big queries, map reduces etc, then this may be good to do >> asynchronously too. And if you're doing lots of all of the above, then >> take a look at Akka, because with Akka you will have a lot more control >> over how many threads are devoted to doing what. Klout did a great blog >> post about this: >> http://corp.klout.com/blog/2012/10/scaling-the-klout-api-with-scala-a...
>> The final thing to be said, if you're doing Java, using promises or any >> sort of async stuff has a huge boiler plate overhead, and this needs to be >> considered, if your simplest code paths are just one anonymous class after >> another, then you are making large maintainability/code readability trade >> offs, and it might not be worth it. If doing Scala on the other hand, >> working with Promises is no harder than working with Options, and so from a >> code perspective, as long as you're comfortable with the concepts of map >> and flatmap, there's no disadvantage to using promises.
>> Cheers,
>> James
>> On Monday, 3 September 2012 07:43:00 UTC+10, Ben McCann wrote:
>>> Hi James,
>>> Do you happen to have a video or slides from that talk you gave? I have >>> a very poor understanding of what should be wrapped in a promise and the >>> docs are quite anemic on the topic. E.g. should all of my calls via the >>> Mongo Jackson Mapper be wrapped in promises? Or just external HTTP >>> requests? How long should an action take before it is recommended to wrap >>> it in a promise? Why not just wrap every single request in a promise? I'm >>> having a really hard time understanding what tradeoffs are in play here.
>>> Thanks, >>> Ben
>>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>>> I think you've fundamentally misunderstood how promises work. A >>>> promise says "at some point in future, I promise I will make one of these >>>> available." In the case of the WS API, that is a WS.Response, ie >>>> Promise<WS.Response>. When returning an async response to Play, you want >>>> to return a promise for a result, ie Promise<Result>. You can convert a >>>> Promise<WS.Response> to a Promise<Result> by calling the map function, >>>> which accepts a function that takes a WS.Response and returns a Result. >>>> This isn't invoked immediately, it's invoked when the first promise makes >>>> the WS.Response available. You could map it to something else first if you >>>> really wanted, and then map that thing to a promise, eg:
>>>> But that's a bit unnecessary, because you don't need the intermediate >>>> fooPromise, you could put your code that converts to/from json in the first >>>> map function. This is also, if you were to call other libraries, where you >>>> would put all that code. If you want to do another async operation (eg two >>>> WS calls), then you can use flatmap:
>>>> The thing to be aware, is once you start working with Promises, you can >>>> never directly work with the result, everything gets done in map() and >>>> flatMap().
>>>> There's a keynote presentation and example code here that I did for a >>>> Play user group:
>>>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>>>> I also have the same question. Especially when you have to perform >>>>>> more actions on the result from the WS call before returning a result to >>>>>> the user?
>>>>>> AsyncResult won't allow you to do that so you're left with blocking >>>>>> the server.
>>>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>>>> Hi, my questions pertains to this exact problem Jonathan has >>>>>>> introduced, but from a different angle and I haven't been able to find a >>>>>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>>>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>>>>> the second Jonathan's example, I can't seem to get my head around >>>>>>> comprehending, how do you get a JsonNode or any other data out of the >>>>>>> async() method through Java libraries? All the examples I have come across >>>>>>> only deal with returning a Result with an ok() method.
>>>>>>> Using F.Promise's get() blocks the thread (or at least so I >>>>>>> understand) and as such obviously negates one of the Play!'s fortes, while >>>>>>> async() as per my understanding only takes Promise<Result> as an argument >>>>>>> and returns AsyncResult exclusively, and neither Result nor AsyncResult >>>>>>> seem to offer any usable method. Is there any way to collect/fetch data >>>>>>> from Result or AsyncResult that I am not aware of? Or is there an
Just for info, with scala2.10 and the new futures will come the ability to
separate execution contexts based on threadpools, thus allowing in theory
separating HTTP threads from akka threads from jdbc threads etc...
Pascal
Le 8 oct. 2012 03:11, "James Roper" <jrop...@gmail.com> a écrit :
> No you're right on this. What we probably should do is have a few
> different configuration profiles documented that a user can use. Out of
> the box, Play is tuned for async. We should make it very easy for the user
> to switch to a more traditional model, such as what most servlet containers
> use, where there is one large (150 threads) thread pool that handles all
> requests.
> On Saturday, 6 October 2012 05:40:58 UTC+10, Ryan Means wrote:
>> Due to the very reason of what James Roper mentioned in the amount of
>> boiler plate code for Java we're staying completely non-async for now.
>> Ended up following James Ward's blog on how to tune a Play 2 app for
>> non-async (James works for Heroku) http://www.jamesward.com/2012/** >> 06/25/optimizing-play-2-for-**database-driven-apps<http://www.jamesward.com/2012/06/25/optimizing-play-2-for-database-dr...>.
>> All of our data comes off an in-house rest service from our CRM that is
>> sitting directly on a DB. As much as we would have liked to go async, the
>> Java code was going to be extremely thick as even our webapp text (which we
>> cache in memcached) comes out of our CRM. Over time, we will start
>> migrating our slower methods (methods that don't return within 1 sec) to
>> async.
>> I would like to point out one very glaring issue that James Ward did not
>> mention though - even though you've "tuned" the environment, as James Roper
>> points out ALL requests are handed off to the Akka handler - from our
>> testing - this appears to include static content! So say you have 20
>> threads, and all 20 are blocked at the moment, then 1 thread finishes and
>> sends the result to the browser - the browser loads the HTML and sends
>> requests back to the play server to get the static content referenced in
>> the dynamic html output from play.. well, now your simple static content
>> requests may be blocked waiting on those blocking akka calls to finish
>> before it can return your simple static content! We experienced this in our
>> testing using firebug and gatling. We were noticing that while running a
>> gatling instance against our blocking app, we could load pages (with a wait
>> time) but then noticed that the static resources in firebug were also
>> blocking instead of being immediately returned! To fix this, we ended up
>> going to a front-end apache server so play only deals with dynamic content
>> now. If you went' all async, you wouldn't have to worry about this as Play
>> encourages you to do. Ultimately, it would be nice if Play had a separate
>> akka thread pool for static content so you never would be at risk for this
>> happening.
>> If I'm wrong on any of this - please correct me! :-)
>> On Thursday, October 4, 2012 5:42:47 PM UTC-5, James Roper wrote:
>>> Hi Ben,
>>> Sorry, I completely missed this message a month ago.
>>> There's no strict rules here, multiple solutions will work well, and
>>> it's very dependent on the profile of your app.
>>> I don't have a video from the talk, there are keynote slides in the
>>> github repository but there's not much in them. I will probably be giving
>>> this talk again in the not too distant future at a conference that does
>>> record video, and it will go into more detail and I'll produce more
>>> comprehensive notes for it, so you'll be able to see it then.
>>> I think a good start is that anything that relies on third party
>>> services should be asynchronous. There's nothing worse than your app going
>>> down because some other system completely outside of your control is not
>>> responding and tying up all your applications threads while you try to make
>>> calls on it. Calls to internal systems in your company are also good to
>>> make asynchronous, and I would always do that, means my services can't
>>> bring each other down so easily.
>>> When it comes to talking to databases, for simple lookups that are
>>> entirely from indexes, then I'd say unless you have an asynchronous driver
>>> for that database, then it's probably not necessary to do things
>>> asynchronously. The exception to this is if you need to make many database
>>> calls per request, then doing them in parallel is a good idea. If you've
>>> got big queries, map reduces etc, then this may be good to do
>>> asynchronously too. And if you're doing lots of all of the above, then
>>> take a look at Akka, because with Akka you will have a lot more control
>>> over how many threads are devoted to doing what. Klout did a great blog
>>> post about this: http://corp.klout.com/**blog/2012/10/scaling-the-** >>> klout-api-with-scala-akka-and-**play/<http://corp.klout.com/blog/2012/10/scaling-the-klout-api-with-scala-a...>
>>> The final thing to be said, if you're doing Java, using promises or any
>>> sort of async stuff has a huge boiler plate overhead, and this needs to be
>>> considered, if your simplest code paths are just one anonymous class after
>>> another, then you are making large maintainability/code readability trade
>>> offs, and it might not be worth it. If doing Scala on the other hand,
>>> working with Promises is no harder than working with Options, and so from a
>>> code perspective, as long as you're comfortable with the concepts of map
>>> and flatmap, there's no disadvantage to using promises.
>>> Cheers,
>>> James
>>> On Monday, 3 September 2012 07:43:00 UTC+10, Ben McCann wrote:
>>>> Hi James,
>>>> Do you happen to have a video or slides from that talk you gave? I
>>>> have a very poor understanding of what should be wrapped in a promise and
>>>> the docs are quite anemic on the topic. E.g. should all of my calls via
>>>> the Mongo Jackson Mapper be wrapped in promises? Or just external HTTP
>>>> requests? How long should an action take before it is recommended to wrap
>>>> it in a promise? Why not just wrap every single request in a promise? I'm
>>>> having a really hard time understanding what tradeoffs are in play here.
>>>> Thanks,
>>>> Ben
>>>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>>>> I think you've fundamentally misunderstood how promises work. A
>>>>> promise says "at some point in future, I promise I will make one of these
>>>>> available." In the case of the WS API, that is a WS.Response, ie
>>>>> Promise<WS.Response>. When returning an async response to Play, you want
>>>>> to return a promise for a result, ie Promise<Result>. You can convert a
>>>>> Promise<WS.Response> to a Promise<Result> by calling the map function,
>>>>> which accepts a function that takes a WS.Response and returns a Result.
>>>>> This isn't invoked immediately, it's invoked when the first promise makes
>>>>> the WS.Response available. You could map it to something else first if you
>>>>> really wanted, and then map that thing to a promise, eg:
>>>>> But that's a bit unnecessary, because you don't need the intermediate
>>>>> fooPromise, you could put your code that converts to/from json in the first
>>>>> map function. This is also, if you were to call other libraries, where you
>>>>> would put all that code. If you want to do another async operation (eg two
>>>>> WS calls), then you can use flatmap:
>>>>> The thing to be aware, is once you start working with Promises, you
>>>>> can never directly work with the result, everything gets done in map() and
>>>>> flatMap().
>>>>> There's a keynote presentation and example code here that I did for a
>>>>> Play user group:
>>>>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>>>>> I also have the same question. Especially when you have to perform
>>>>>>> more actions on the result from the WS call before returning a result to
>>>>>>> the user?
>>>>>>> AsyncResult won't allow you to do that so you're left with blocking
>>>>>>> the server.
>>>>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>>>>> Hi, my questions pertains to this exact problem Jonathan has
>>>>>>>> introduced, but from a different angle and I haven't been able to find a
>>>>>>>> solution (at least not of the
As far as I understand, two threads pools should be used:
- one for all computations based on asynchronous IO,
- and one for CPU intensive tasks
The thread pool for IO could be used for static content, ahc...
The thread pool for CPU intensive tasks could be used for controllers.
Is it the actual configuration?
The non asynchronous stuff is still problematic to handle. It is the
typical problem of JEE applications, where we can only use a high
number of threads, leading to context-switching.
Therefore, all synchronous stuff should maybe handled by a separate
thread pool, which destiny is not to exist... :)
Yann
2012/10/8 Pascal Voitot Dev <pascal.voitot....@gmail.com>:
> Just for info, with scala2.10 and the new futures will come the ability to
> separate execution contexts based on threadpools, thus allowing in theory
> separating HTTP threads from akka threads from jdbc threads etc...
> Pascal
> Le 8 oct. 2012 03:11, "James Roper" <jrop...@gmail.com> a écrit :
>> No you're right on this. What we probably should do is have a few
>> different configuration profiles documented that a user can use. Out of the
>> box, Play is tuned for async. We should make it very easy for the user to
>> switch to a more traditional model, such as what most servlet containers
>> use, where there is one large (150 threads) thread pool that handles all
>> requests.
>> On Saturday, 6 October 2012 05:40:58 UTC+10, Ryan Means wrote:
>>> Due to the very reason of what James Roper mentioned in the amount of
>>> boiler plate code for Java we're staying completely non-async for now. Ended
>>> up following James Ward's blog on how to tune a Play 2 app for non-async
>>> (James works for Heroku)
>>> http://www.jamesward.com/2012/06/25/optimizing-play-2-for-database-dr....
>>> All of our data comes off an in-house rest service from our CRM that is
>>> sitting directly on a DB. As much as we would have liked to go async, the
>>> Java code was going to be extremely thick as even our webapp text (which we
>>> cache in memcached) comes out of our CRM. Over time, we will start migrating
>>> our slower methods (methods that don't return within 1 sec) to async.
>>> I would like to point out one very glaring issue that James Ward did not
>>> mention though - even though you've "tuned" the environment, as James Roper
>>> points out ALL requests are handed off to the Akka handler - from our
>>> testing - this appears to include static content! So say you have 20
>>> threads, and all 20 are blocked at the moment, then 1 thread finishes and
>>> sends the result to the browser - the browser loads the HTML and sends
>>> requests back to the play server to get the static content referenced in the
>>> dynamic html output from play.. well, now your simple static content
>>> requests may be blocked waiting on those blocking akka calls to finish
>>> before it can return your simple static content! We experienced this in our
>>> testing using firebug and gatling. We were noticing that while running a
>>> gatling instance against our blocking app, we could load pages (with a wait
>>> time) but then noticed that the static resources in firebug were also
>>> blocking instead of being immediately returned! To fix this, we ended up
>>> going to a front-end apache server so play only deals with dynamic content
>>> now. If you went' all async, you wouldn't have to worry about this as Play
>>> encourages you to do. Ultimately, it would be nice if Play had a separate
>>> akka thread pool for static content so you never would be at risk for this
>>> happening.
>>> If I'm wrong on any of this - please correct me! :-)
>>> On Thursday, October 4, 2012 5:42:47 PM UTC-5, James Roper wrote:
>>>> Hi Ben,
>>>> Sorry, I completely missed this message a month ago.
>>>> There's no strict rules here, multiple solutions will work well, and
>>>> it's very dependent on the profile of your app.
>>>> I don't have a video from the talk, there are keynote slides in the
>>>> github repository but there's not much in them. I will probably be giving
>>>> this talk again in the not too distant future at a conference that does
>>>> record video, and it will go into more detail and I'll produce more
>>>> comprehensive notes for it, so you'll be able to see it then.
>>>> I think a good start is that anything that relies on third party
>>>> services should be asynchronous. There's nothing worse than your app going
>>>> down because some other system completely outside of your control is not
>>>> responding and tying up all your applications threads while you try to make
>>>> calls on it. Calls to internal systems in your company are also good to
>>>> make asynchronous, and I would always do that, means my services can't bring
>>>> each other down so easily.
>>>> When it comes to talking to databases, for simple lookups that are
>>>> entirely from indexes, then I'd say unless you have an asynchronous driver
>>>> for that database, then it's probably not necessary to do things
>>>> asynchronously. The exception to this is if you need to make many database
>>>> calls per request, then doing them in parallel is a good idea. If you've
>>>> got big queries, map reduces etc, then this may be good to do asynchronously
>>>> too. And if you're doing lots of all of the above, then take a look at
>>>> Akka, because with Akka you will have a lot more control over how many
>>>> threads are devoted to doing what. Klout did a great blog post about this:
>>>> http://corp.klout.com/blog/2012/10/scaling-the-klout-api-with-scala-a...
>>>> The final thing to be said, if you're doing Java, using promises or any
>>>> sort of async stuff has a huge boiler plate overhead, and this needs to be
>>>> considered, if your simplest code paths are just one anonymous class after
>>>> another, then you are making large maintainability/code readability trade
>>>> offs, and it might not be worth it. If doing Scala on the other hand,
>>>> working with Promises is no harder than working with Options, and so from a
>>>> code perspective, as long as you're comfortable with the concepts of map and
>>>> flatmap, there's no disadvantage to using promises.
>>>> Cheers,
>>>> James
>>>> On Monday, 3 September 2012 07:43:00 UTC+10, Ben McCann wrote:
>>>>> Hi James,
>>>>> Do you happen to have a video or slides from that talk you gave? I
>>>>> have a very poor understanding of what should be wrapped in a promise and
>>>>> the docs are quite anemic on the topic. E.g. should all of my calls via the
>>>>> Mongo Jackson Mapper be wrapped in promises? Or just external HTTP
>>>>> requests? How long should an action take before it is recommended to wrap
>>>>> it in a promise? Why not just wrap every single request in a promise? I'm
>>>>> having a really hard time understanding what tradeoffs are in play here.
>>>>> Thanks,
>>>>> Ben
>>>>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>>>>> I think you've fundamentally misunderstood how promises work. A
>>>>>> promise says "at some point in future, I promise I will make one of these
>>>>>> available." In the case of the WS API, that is a WS.Response, ie
>>>>>> Promise<WS.Response>. When returning an async response to Play, you want to
>>>>>> return a promise for a result, ie Promise<Result>. You can convert a
>>>>>> Promise<WS.Response> to a Promise<Result> by calling the map function, which
>>>>>> accepts a function that takes a WS.Response and returns a Result. This
>>>>>> isn't invoked immediately, it's invoked when the first promise makes the
>>>>>> WS.Response available. You could map it to something else first if you
>>>>>> really wanted, and then map that thing to a promise, eg:
>>>>>> But that's a bit unnecessary, because you don't need the intermediate
>>>>>> fooPromise, you could put your code that converts to/from json in the first
>>>>>> map function. This is also, if you were to call other libraries, where you
>>>>>> would put all that code. If you want to do another async operation (eg two
>>>>>> WS calls), then you can use flatmap:
>>>>>> The thing to be aware, is once you start working with Promises, you
>>>>>> can never directly work with the result, everything gets done in map() and
>>>>>> flatMap().
>>>>>> There's a keynote presentation and example code here that I did for a
>>>>>> Play user group:
Thanks for the response James! Even though there are some gray areas right now when trying to do blocking style apps - we still believe that Play is the best web development framework out there for Java development shops - you just need to figure out how to work around things like async and understand the ramifications (such as what happens to your static content). Thanks for the good work - I'm excited to see what Play will look like one year from now..
On Sunday, October 7, 2012 8:11:40 PM UTC-5, James Roper wrote:
> No you're right on this. What we probably should do is have a few > different configuration profiles documented that a user can use. Out of > the box, Play is tuned for async. We should make it very easy for the user > to switch to a more traditional model, such as what most servlet containers > use, where there is one large (150 threads) thread pool that handles all > requests.
> On Saturday, 6 October 2012 05:40:58 UTC+10, Ryan Means wrote:
>> Due to the very reason of what James Roper mentioned in the amount of >> boiler plate code for Java we're staying completely non-async for now. >> Ended up following James Ward's blog on how to tune a Play 2 app for >> non-async (James works for Heroku) >> http://www.jamesward.com/2012/06/25/optimizing-play-2-for-database-dr.... >> All of our data comes off an in-house rest service from our CRM that is >> sitting directly on a DB. As much as we would have liked to go async, the >> Java code was going to be extremely thick as even our webapp text (which we >> cache in memcached) comes out of our CRM. Over time, we will start >> migrating our slower methods (methods that don't return within 1 sec) to >> async.
>> I would like to point out one very glaring issue that James Ward did not >> mention though - even though you've "tuned" the environment, as James Roper >> points out ALL requests are handed off to the Akka handler - from our >> testing - this appears to include static content! So say you have 20 >> threads, and all 20 are blocked at the moment, then 1 thread finishes and >> sends the result to the browser - the browser loads the HTML and sends >> requests back to the play server to get the static content referenced in >> the dynamic html output from play.. well, now your simple static content >> requests may be blocked waiting on those blocking akka calls to finish >> before it can return your simple static content! We experienced this in our >> testing using firebug and gatling. We were noticing that while running a >> gatling instance against our blocking app, we could load pages (with a wait >> time) but then noticed that the static resources in firebug were also >> blocking instead of being immediately returned! To fix this, we ended up >> going to a front-end apache server so play only deals with dynamic content >> now. If you went' all async, you wouldn't have to worry about this as Play >> encourages you to do. Ultimately, it would be nice if Play had a separate >> akka thread pool for static content so you never would be at risk for this >> happening.
>> If I'm wrong on any of this - please correct me! :-)
>> On Thursday, October 4, 2012 5:42:47 PM UTC-5, James Roper wrote:
>>> Hi Ben,
>>> Sorry, I completely missed this message a month ago.
>>> There's no strict rules here, multiple solutions will work well, and >>> it's very dependent on the profile of your app.
>>> I don't have a video from the talk, there are keynote slides in the >>> github repository but there's not much in them. I will probably be giving >>> this talk again in the not too distant future at a conference that does >>> record video, and it will go into more detail and I'll produce more >>> comprehensive notes for it, so you'll be able to see it then.
>>> I think a good start is that anything that relies on third party >>> services should be asynchronous. There's nothing worse than your app going >>> down because some other system completely outside of your control is not >>> responding and tying up all your applications threads while you try to make >>> calls on it. Calls to internal systems in your company are also good to >>> make asynchronous, and I would always do that, means my services can't >>> bring each other down so easily.
>>> When it comes to talking to databases, for simple lookups that are >>> entirely from indexes, then I'd say unless you have an asynchronous driver >>> for that database, then it's probably not necessary to do things >>> asynchronously. The exception to this is if you need to make many database >>> calls per request, then doing them in parallel is a good idea. If you've >>> got big queries, map reduces etc, then this may be good to do >>> asynchronously too. And if you're doing lots of all of the above, then >>> take a look at Akka, because with Akka you will have a lot more control >>> over how many threads are devoted to doing what. Klout did a great blog >>> post about this: >>> http://corp.klout.com/blog/2012/10/scaling-the-klout-api-with-scala-a...
>>> The final thing to be said, if you're doing Java, using promises or any >>> sort of async stuff has a huge boiler plate overhead, and this needs to be >>> considered, if your simplest code paths are just one anonymous class after >>> another, then you are making large maintainability/code readability trade >>> offs, and it might not be worth it. If doing Scala on the other hand, >>> working with Promises is no harder than working with Options, and so from a >>> code perspective, as long as you're comfortable with the concepts of map >>> and flatmap, there's no disadvantage to using promises.
>>> Cheers,
>>> James
>>> On Monday, 3 September 2012 07:43:00 UTC+10, Ben McCann wrote:
>>>> Hi James,
>>>> Do you happen to have a video or slides from that talk you gave? I >>>> have a very poor understanding of what should be wrapped in a promise and >>>> the docs are quite anemic on the topic. E.g. should all of my calls via >>>> the Mongo Jackson Mapper be wrapped in promises? Or just external HTTP >>>> requests? How long should an action take before it is recommended to wrap >>>> it in a promise? Why not just wrap every single request in a promise? I'm >>>> having a really hard time understanding what tradeoffs are in play here.
>>>> Thanks, >>>> Ben
>>>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>>>> I think you've fundamentally misunderstood how promises work. A >>>>> promise says "at some point in future, I promise I will make one of these >>>>> available." In the case of the WS API, that is a WS.Response, ie >>>>> Promise<WS.Response>. When returning an async response to Play, you want >>>>> to return a promise for a result, ie Promise<Result>. You can convert a >>>>> Promise<WS.Response> to a Promise<Result> by calling the map function, >>>>> which accepts a function that takes a WS.Response and returns a Result. >>>>> This isn't invoked immediately, it's invoked when the first promise makes >>>>> the WS.Response available. You could map it to something else first if you >>>>> really wanted, and then map that thing to a promise, eg:
>>>>> But that's a bit unnecessary, because you don't need the intermediate >>>>> fooPromise, you could put your code that converts to/from json in the first >>>>> map function. This is also, if you were to call other libraries, where you >>>>> would put all that code. If you want to do another async operation (eg two >>>>> WS calls), then you can use flatmap:
>>>>> The thing to be aware, is once you start working with Promises, you >>>>> can never directly work with the result, everything gets done in map() and >>>>> flatMap().
>>>>> There's a keynote presentation and example code here that I did for a >>>>> Play user group:
>>>>>> On Friday, August 31, 2012 1:54:42 AM UTC+10, Steven Wong wrote:
>>>>>>> I also have the same question. Especially when you have to perform >>>>>>> more actions on the result from the WS call before returning a result to >>>>>>> the user?
>>>>>>> AsyncResult won't allow you to do that so you're left with blocking >>>>>>> the server.
>>>>>>> On Tuesday, July 10, 2012 6:39:31 AM UTC+10, Aldrion wrote:
>>>>>>>> Hi, my questions pertains to this exact problem Jonathan has >>>>>>>> introduced, but from a different angle and I haven't been able to find a >>>>>>>> solution (at least not of the kind that would enlighten me) online. Namely, >>>>>>>> while it is self-evident, how you get to a JsonNode (or any other data) in >>>>>>>> the second Jonathan's example, I can't seem to get my head
Serving all of your static content direct to users from Play is simple but I think a better solution is to proxy the static content requests through a caching CDN or proxy server. Setting things up so that deployment is still simple, is pretty easy to do with services like Amazon CloudFront. Here is another blog post I did that walks through how to do that: http://www.jamesward.com/2012/08/08/edge-caching-with-play2-heroku-cl...
Alternatively you could setup a Squid or Varnish server in front of your Play app that will serve your static assets. The benefit of this (or the CloudFront) approach is that everything is still in one app but most of the requests hit a cache (preferably edge-cached) tier. Then you just need to provide a way to configure your app to use different URLs for the static assets. Play 1 had a way to do this and I'd love to create a nice way to do this in Play 2.
On Monday, October 8, 2012 7:12:35 AM UTC-6, Ryan Means wrote:
> Thanks for the response James! Even though there are some gray areas right > now when trying to do blocking style apps - we still believe that Play is > the best web development framework out there for Java development shops - > you just need to figure out how to work around things like async and > understand the ramifications (such as what happens to your static content). > Thanks for the good work - I'm excited to see what Play will look like one > year from now..
> On Sunday, October 7, 2012 8:11:40 PM UTC-5, James Roper wrote:
>> No you're right on this. What we probably should do is have a few >> different configuration profiles documented that a user can use. Out of >> the box, Play is tuned for async. We should make it very easy for the user >> to switch to a more traditional model, such as what most servlet containers >> use, where there is one large (150 threads) thread pool that handles all >> requests.
>> On Saturday, 6 October 2012 05:40:58 UTC+10, Ryan Means wrote:
>>> Due to the very reason of what James Roper mentioned in the amount of >>> boiler plate code for Java we're staying completely non-async for now. >>> Ended up following James Ward's blog on how to tune a Play 2 app for >>> non-async (James works for Heroku) >>> http://www.jamesward.com/2012/06/25/optimizing-play-2-for-database-dr.... >>> All of our data comes off an in-house rest service from our CRM that is >>> sitting directly on a DB. As much as we would have liked to go async, the >>> Java code was going to be extremely thick as even our webapp text (which we >>> cache in memcached) comes out of our CRM. Over time, we will start >>> migrating our slower methods (methods that don't return within 1 sec) to >>> async.
>>> I would like to point out one very glaring issue that James Ward did not >>> mention though - even though you've "tuned" the environment, as James Roper >>> points out ALL requests are handed off to the Akka handler - from our >>> testing - this appears to include static content! So say you have 20 >>> threads, and all 20 are blocked at the moment, then 1 thread finishes and >>> sends the result to the browser - the browser loads the HTML and sends >>> requests back to the play server to get the static content referenced in >>> the dynamic html output from play.. well, now your simple static content >>> requests may be blocked waiting on those blocking akka calls to finish >>> before it can return your simple static content! We experienced this in our >>> testing using firebug and gatling. We were noticing that while running a >>> gatling instance against our blocking app, we could load pages (with a wait >>> time) but then noticed that the static resources in firebug were also >>> blocking instead of being immediately returned! To fix this, we ended up >>> going to a front-end apache server so play only deals with dynamic content >>> now. If you went' all async, you wouldn't have to worry about this as Play >>> encourages you to do. Ultimately, it would be nice if Play had a separate >>> akka thread pool for static content so you never would be at risk for this >>> happening.
>>> If I'm wrong on any of this - please correct me! :-)
>>> On Thursday, October 4, 2012 5:42:47 PM UTC-5, James Roper wrote:
>>>> Hi Ben,
>>>> Sorry, I completely missed this message a month ago.
>>>> There's no strict rules here, multiple solutions will work well, and >>>> it's very dependent on the profile of your app.
>>>> I don't have a video from the talk, there are keynote slides in the >>>> github repository but there's not much in them. I will probably be giving >>>> this talk again in the not too distant future at a conference that does >>>> record video, and it will go into more detail and I'll produce more >>>> comprehensive notes for it, so you'll be able to see it then.
>>>> I think a good start is that anything that relies on third party >>>> services should be asynchronous. There's nothing worse than your app going >>>> down because some other system completely outside of your control is not >>>> responding and tying up all your applications threads while you try to make >>>> calls on it. Calls to internal systems in your company are also good to >>>> make asynchronous, and I would always do that, means my services can't >>>> bring each other down so easily.
>>>> When it comes to talking to databases, for simple lookups that are >>>> entirely from indexes, then I'd say unless you have an asynchronous driver >>>> for that database, then it's probably not necessary to do things >>>> asynchronously. The exception to this is if you need to make many database >>>> calls per request, then doing them in parallel is a good idea. If you've >>>> got big queries, map reduces etc, then this may be good to do >>>> asynchronously too. And if you're doing lots of all of the above, then >>>> take a look at Akka, because with Akka you will have a lot more control >>>> over how many threads are devoted to doing what. Klout did a great blog >>>> post about this: >>>> http://corp.klout.com/blog/2012/10/scaling-the-klout-api-with-scala-a...
>>>> The final thing to be said, if you're doing Java, using promises or any >>>> sort of async stuff has a huge boiler plate overhead, and this needs to be >>>> considered, if your simplest code paths are just one anonymous class after >>>> another, then you are making large maintainability/code readability trade >>>> offs, and it might not be worth it. If doing Scala on the other hand, >>>> working with Promises is no harder than working with Options, and so from a >>>> code perspective, as long as you're comfortable with the concepts of map >>>> and flatmap, there's no disadvantage to using promises.
>>>> Cheers,
>>>> James
>>>> On Monday, 3 September 2012 07:43:00 UTC+10, Ben McCann wrote:
>>>>> Hi James,
>>>>> Do you happen to have a video or slides from that talk you gave? I >>>>> have a very poor understanding of what should be wrapped in a promise and >>>>> the docs are quite anemic on the topic. E.g. should all of my calls via >>>>> the Mongo Jackson Mapper be wrapped in promises? Or just external HTTP >>>>> requests? How long should an action take before it is recommended to wrap >>>>> it in a promise? Why not just wrap every single request in a promise? I'm >>>>> having a really hard time understanding what tradeoffs are in play here.
>>>>> Thanks, >>>>> Ben
>>>>> On Thursday, August 30, 2012 11:10:33 PM UTC-7, James Roper wrote:
>>>>>> I think you've fundamentally misunderstood how promises work. A >>>>>> promise says "at some point in future, I promise I will make one of these >>>>>> available." In the case of the WS API, that is a WS.Response, ie >>>>>> Promise<WS.Response>. When returning an async response to Play, you want >>>>>> to return a promise for a result, ie Promise<Result>. You can convert a >>>>>> Promise<WS.Response> to a Promise<Result> by calling the map function, >>>>>> which accepts a function that takes a WS.Response and returns a Result. >>>>>> This isn't invoked immediately, it's invoked when the first promise makes >>>>>> the WS.Response available. You could map it to something else first if you >>>>>> really wanted, and then map that thing to a promise, eg:
>>>>>> But that's a bit unnecessary, because you don't need the intermediate >>>>>> fooPromise, you could put your code that converts to/from json in the first >>>>>> map function. This is also, if you were to call other libraries, where you >>>>>> would put all that code. If you want to do another async operation (eg two >>>>>> WS calls), then you can use flatmap:
>>>>>> The thing to be aware, is once you start working with Promises, you >>>>>> can never directly work with the result, everything gets done in map() and >>>>>> flatMap().
>>>>>> There's a keynote presentation and example code here that I did for a >>>>>> Play user group: