SF Scala: James Ward, Reactive All The Way Down
Recording: SF Scala: James Ward, Reactive All The Way Down
thanks for coming tonight thanks for sharing your friday night with me um i'm visiting from colorado and was uh able to to be here for a friday night so so thanks for coming so i'm james ward from typesafe i've been working at typesa for a year and a half and i'm a contributor to play and activator and a couple other projects there and um and get to go around and teach developers about the platform so uh tonight's going to be about reactive all the way down i'm going to start with just uh i don't i don't know how much time we'll spend in slides couple minutes not very long and then i want to spend a lot of time just writing some code tonight and showing you some of the stuff and how it works so feel free to stop me at any point and ask questions we can try to make this as interactive if uh if you're not feeling interactive there's some beer in the back i got mine up front so so that'll make it more fun and then we're going out afterwards for alexi's birthday right so we'll find some place to to go celebrate with alexi so thanks for spending your birthday with us all right i gotta remember to start the video capture here go okay we're going to try to do screen capture on linux it's a new experiment it may it may go horribly wrong we'll find out okay so reactive all the way down what this is going to be about tonight is about building reactive applications that are reactive all the way from the back end to uh to the ui and so there's a bunch of different pieces that i'm going to go into some of this if you guys have been doing reactive programming it may be a little bit of review but hopefully some of the angular stuff will will be new and interesting for you and then i'll show some of the spt web stuff that i talked about last night a little bit of that svt web as alexi mentioned is the new asset pipeline in play 2-3 you can use it outside of play but it's a new way to write the client side of your application in a play application so if you want to learn more about kind of the ideas of reactive reactivemanifesto.org is really the best place to do that there are some high-level ideas that you can walk through what i'm going to focus on tonight is really the the implementation of reactive on the typesafe platform so in the typesafe platform how do you build reactive apps and so i want to start out with uh async and non-blocking will be the first thing that we try to tackle and we're going to start with that just in the on the website on the server and then get to the angular side so i'm going to start out with with writing a controller and i first need a new application so we're we have a tool called activator it's a way to create new apps and run them it's if you're familiar with the platform it is an sbt launcher with an optional ui so you can use it from the command line you can use it from a ui both it's up to you so i'm going to use it from the command line tonight so i'm going to run activator new and create a new application let's give this one a name we'll call it reactive all the way down sounds rat i didn't know that this would start with rat so that's fun and then i'm going to select a template application there's a bunch of templates to choose from an activator i'm going to use the hello play and then 2 3 scala so that's the the app i'm going to start with here and let's just run this thing so i'm going to do activator run if you can't see the fonts well enough or anything let me know and i can bump those up or move windows around so while that's while that's getting up and running i'm going to go open that up in intellij this is one of the nice new features in intellij is that i can just go to a project here in intellij and open it up i don't have to generate the project files with the scala plug-in and intellij it now knows what an spt project is and can just open an sbt project so it'll take a second to resolve dependencies and pull that project in but let's see if we can go load this this app that we're going to be working on here in the browser so there's there's my app and we'll start start writing some code so while this is loading up in intellij the way the play works is we we have a file that we define our routes in and the routes is where we define the forward routing information so that when play handles a web request we tell it based on an http verb and a path what controller is going to handle that request so let me show you that file here in intellij so that's in the comp routes file and so there's our routing definition for this application i have a get handler for slash when we make a request a get request to slash that's going to be handled by controllers.application.index and then i have a couple other controllers in here routes in here one for my static assets that that i'm managing and then one for the web jar assets that we'll talk about a little bit later so let's go take a look at when i when i was in my browser and made this request to localhost 9000 that was handled by the get slash route there so that went to app controllers application.scala so this is our standard controller here in a play application and so here we're extending controller you don't have to do that that just brings in some convenience methods and then we have a function here index an action all that an action really is is a wrapper around a function that takes a request and returns a result and the result is the http response the the request is the http request so you can get the headers and set the headers on you can get the headers on the request set the headers on the result so in this case this this controller what it's doing is it has a function here i'm not using the request so i don't have to specify it so now i'm just returning the result and the result is okay okay status code 200 so i'm returning a status code 200 result and the body of that result is this views.html.index and then it's passing a string to that so that's coming from down here in the views package play has a server-side templating language that's based in scala so if we open up this index.scala.html we'll see here's our template it takes a parameter which is a string and then we're using another template we're calling app main everything that scala is prefixed within that science we're calling the main template and you'll see that this template has two parameters a string and a content block of html here's our boilerplate page and then we fill in those two parameters here's the the first parameter that goes into the title and then here what is what goes into the body of the page so that's how we get this page rendered when we make that request to slash so some of the the cool little features of play are that we can make changes to all this stuff and just hit refresh in our browser so if i make a change to uh in the routes file that doesn't work and hit refresh then play is going to tell me that there's a compiler compiling the routes and likewise if i make a change to the controllers the templates the client-side stuff we'll see in a little bit we're going to see those so that's your quick little intro to play but now i want to dive into the reactive stuff but any questions about the the basics before i go on okay so now let's let's start heading towards reactive so one of the the parts of reactive is to be async and non-blocking async it's kind of strange to say async and non-blocking because you can't really be non-blocking without being async you can be async and not be non-blocking you can be async and blocking but you can't be non-blocking without being async so it's kind of weird to say both but for some reason we do and so what we're going to do is start heading down the path of of creating a controller that's going to be async and non-blocking and that's where we'll start to get into the reactive stuff so um so let's go create first a new route here i'm going to call it uh foo and then this is going to go to a foo method so let's define this method foo and i can just create an action and return a result okay status code 200 and now if i go to slash foo then we'll see there's my very exciting empty result which is a status code 200. so this was a there's nothing async there's nothing explicitly async about this controller method because i i right now i don't need to do anything asynchronously underneath the covers play is actually doing these controller method calls asynchronously that's why we define them as functions so that we can handle them asynchronously so we put these requests into a queue and then execute those on the queue pull those off the queue and execute them as we can get threads available so in this case there's nothing async about this um other than what's underneath the covers in play but if i want to be explicitly async then what i can do is i can instead of doing an action i can do an action.async and now instead of taking a function that takes a request and turns returns a result now i need to return a future of a result so i'm going to return to play not the thing but a future of the thing it's going to be something that will in the future produce that result rather than than the actual result and so the easy way to make this code work is to create a new future so i can do a future dot successful let's go import that scala concurrent future so future dot successful and now i'm creating a new future that's going to basically immediately fulfill with that same result so now i'm explicitly async and let's put something in the body so we can see a change here so now when i hit refresh there i see that that now this thing is working just like it was before but now it's explicitly async it's still not non-blocking because there's nothing to not block on yet but it is async and so uh so what that means is that instead of giving the thing back to play i'm giving a handle to the thing back to play and then when that thing produces a value then the response will be sent back to the user this is how play works under the covers for you no matter how you write your controllers but you don't have to write the extra boilerplate code if there's nothing to not block on and thus no reason to be async so questions about the async controller before we go on okay all right so now let's let's actually create something to not block on the really easy thing to not block on is just a timeout basically something that says hey call me back in some amount of time so i'm going to create a new future using the promise api so i'm going to do a promise.timeout and promise.timeout what it takes is the thing that i want to produce or the function that i want to call and so i can now just say ok and let's put a string in there and then the second parameter here is how long in a duration how long i want to wait to to actually trigger that so let's do five seconds and let's remove that and we're going to have to import a few things here so let's import now a scala concurrent or no yeah scholar concurrent duration underscore that'll give us our seconds there and then we'll see if we try to refresh in the browser that we actually get an error because now we're actually doing something that's going to require a thread and now that we're doing something that requires a thread we need to tell this application where it's going to get its thread from so now this is going to be operating on multiple threads when we did future.successful there actually wasn't a thread needed for that so it didn't require us to have an execution context but now that we are doing something that is going to operate on another thread possibly another thread could be the same thread we don't know but what's going to actually be on that thread is when that callback happens so when that timeout triggers when we call that function we need a thread to actually execute that thing on and so that's why we need to tell it an execution context an execution context is basically a thread pool it's it's an abstraction scala over the thread pools and so we need to tell this this thing where it's going to get its execution context from we could actually see where that was that where that was needed if we look at the method definition for promise.timeout you'll see that there's a second parameter set there that takes the execution context which can be supplied through an implicit and that's why the error message that i'm getting is that i don't have an implicit execution context and so i can import one and i want you all to take note of the the actual error message there scala.concurrent.executioncontext has anybody noticed the the how that's different from how scala used to be this is using a newer version of skull i don't remember i think it says 210 4 or something like that does anybody know what's different this was my only contribution to scala and i'm really proud of it so it used to just say import execution context. and now it actually gives you the fully qualified path to that global it kind of assumed that you knew where that thing was before and so now it gives you an error message that's actually useful so that's my only contribution to scala you know 10 characters or so but i'm really proud of of an error message that actually is helpful so thank you thanks yeah felt good to get something into skull and actually see it there in my demos that's awesome okay so let's import that thing and then let's hit refresh and now it's going to compile and then once it's done compiling you'll see that it's waiting so my browser is spinning for five seconds if we open up inspect we'll actually see that so let's try it again so we'll see it's waiting waiting waiting uh the browser is spinning and then after five seconds it fulfills the request with with the value so we just did that now async and non-blocking so now there's a request coming into this this controller and this controller immediately exits with a future of of the result and now there's no thread allocated to this request so there is somewhere a thread that's keeping track of all the timeouts in the system it's you know there has to be a thread there to keep track of these so there is some thread that's going to get reused for all the timeouts in the system but all the requests that come into this controller they are just going to make the request then no thread and we don't close the connection the connection is still open so this uses java nio under the covers to not have that thread per connection limit and then when the future completes with this value then we get a thread back for that connection and then can send the response back down to the browser so now this is obviously a lot more efficient way to to to have to use your threads on your system and so we're not just wasting threads when things are just sitting around waiting so that's async and on blocking questions about how that works okay all right i guess we need more beer oh there's a question great uh so the on the browser side the browser does have some limit in number of concurrent connections this doesn't address that this addresses the side on the server where on the server you the typical like tomcat server has a thread pool of like 250 connections which means that if you have 250 threads available you can only have 250 actual concurrent connections whether those things are blocking no matter what's going on what is that yeah so the reason one of the reasons why we we uh why tomcat only gives you a small number of threads is because there's a lot of context switching overhead as you increase your threads there's also a lot of memory consumption associated with threads i think the default stack size on the jvm is a mag and so that means that for each thread it's a minimum of a meg and so you really want to keep your threads as small as possible down to your number of cores and that's the the ideal and so so that's what we try to do is try to make much more efficient use of the threads the reason why tomcat needs to allocate all 250 threads is because they don't have a way to do non-blocking newer servlet apis do have a way but the traditional servo api is blocking yeah yeah garbage collection is another reason as well yeah nice yeah so let's say i want to do two outputs on this page with different timeouts like is it possible is it easy to do with play and what's involved timeouts on on how long it takes to fulfill that future and you you explicitly want a timeout okay so the the future um doesn't have a built-in concept of a timeout there's a few different ways to accomplish it you can do it purely with futures where you basically create two different futures and then there's a way to say the first one that completes is the one that i'm going to use and so you kind of aggregate a a a timeout future with your actual um like business logic future and then you say give me the result of whichever one of those completes first so that's one way to do timeouts with futures um the the other way is with akka and actors actors have a built-in timeout mechanism that we'll get into in a little bit does that that address is just the time out question was there another question that two pieces of the page yeah in each of them is surrenders by different functions and i want you know as soon as each is ready to show it so what's what's a way to do this yeah so the the easiest way to do this is with ajax you're gonna make different ajax requests and then you're gonna have those come back at probably different times and then when they come back you're gonna trigger some javascript and then change the page with the data that you got back from from the ajax request ajax is the easiest there is a a different way to do it which is what facebook is using it's called big pipe big pipes or something there's a great presentation by jim brickman linkedin is now starting to use this as well and there's a great presentation from pingconf on exactly how to do that with play the the challenge with with that is that right now uh if you look at this this view this view is actually blocking it that until that whole template is ready um it's not going to return a string and so jim brickman actually created a way to have templates based on futures and then they can aggregate together other pieces of templates that are also based on futures and so and then there's a way to do that uh so that the page renders correctly and so it's it's kind of a complex thing to do without ajax but when you need like seo um or there's other reasons to do it but seo is one of the primary ones yeah pink just search for ping comp videos so ping conf was the play conference in uh europe somewhere uh back at the beginning of the year and they recorded all the presentations so yeah just search for uh jim brinkman's video from pingconf yep okay other questions about our async and non-blocking code here okay all right so um so that's great we've we've got something async and non-blocking but now we want to do something more interesting obviously i hope you don't have promise.timeouts in your code not a whole lot of reason for them so let's do something slightly more interesting so now instead of making a instead of creating something non-blocking on a on a timeout let's do it based on a web request that's going to go out to another service so i'm going to create a new web request to jamesward.com and i'm going to use plays web service library to do this so let's oh and i forgot one piece to this new and play two three this is important for play people you now have to import explicitly import the web service library so you have to import playkeys.ws i hope that's what it is and then intellij should refresh and i'm going to have to restart activator as well so that's they actually factored out the web service client library in play 2 3 so now we have to explicitly import that and i should just have that not in this default template since it's pretty commonly used but once that finishes refreshing then we'll be able to not yet get make our web service client library request there we go okay so import that okay so this is the web service client library in play and this is an async and non-block in web service client library so i'm going to set the url let's just set it to for simplicity for now jamesward.com and then i'm going to make a get request to that url so this get method here it returns a future of a ws response so it's giving me back something that i can read the the web service response out of and that's not the same thing that i need to give to play because play needs a result so one the result is the side that i can write values into and this ws response is a side that i can read values out of and so there are two different apis so in order to fulfill this make this action.async happy i can't give it this future of ws response i have to give it a future of a result and so i need to now transform this future so to transform uh most of us scholar developers are probably familiar with it those newer to scala the map function is how we take the thing out of the box and turn it into something different so map i'm going to map on that future of ws response so now in this map i can actually work with the response and transform it so let's take our response here and now i'm going to produce the result that play needs so i'm going to produce a okay and then let's just give it the response body so i'm taking the when the response comes back from jamesward.com i'm going to transform that response into a result and give that back out but what comes out of this map now is now a future of s and s is the result which is what the function inside the map produces so that's that's how i'm going to now give play the the future of result that it needs oh and i need another implicit this one is also fully qualified so we'll just copy and paste that let's try that again and so there we go so there was uh what happened was i made a request from my browser to my play server and then my server made a request to jamesword.com and there is some amount of time where i'm just waiting for jamesward.com to respond and in that amount of time there's actually no threads allocated to this request so we take the threads away they can go do whatever they want somewhere else and then when the response comes back from jamesword.com then i get a thread back then i can return the response back to the user so this whole thing now is async and non-blocking all the way through uh in this case i'm just displaying text i didn't set the content type there so i'm just seeing the text for jamesword.com obviously we'll we'll be working with json data in most scenarios so so be more useful than a bunch of html text so now this thing is what we call reactive composition where it is composing together two different parts two different reactive requests together so just one reactive request and then with multiple in a chain like this is then we get reactive composition so we can take this to another level and then we'll we'll get uh move on to the client side but um if we want to make two requests let's say i also want to make a request out to twitter and let's add in here a new request and now what i want to do is compose together the results from both of these futures and not block on either of them and then when i get the response back from both of them then i want to fulfill the result so the the really kind of sexy way to do this in scala is with the four comprehension and so what i'm going to do is i'm going to say give me the the jw response out of the jw and then get me the twitter response out of the twitter future and then when we have both of those then yield okay and then let's take the twitter body plus the jw body okay so we're just gonna pen them together obviously totally uh not practical in the real world but there we go so now i make the request so there's a request from my browser to play then play makes a request to jamesword.com makes a request to twitter when both of those have come back then we fulfill the response back to the user and there's twitter.com and then somewhere down here is going to be jamesward.com so we've just concatenated those together so this whole thing now we have three requests this whole thing now is async and non-blocking so there's some point in time where i'm waiting for twitter to respond or i'm waiting for jamesford.com to respond or i'm waiting for both of them to respond and there's no block in on any of this stuff i'm returning a future back to play and so win those inner futures finished then i fulfill the outer future as well so the few the four comprehension is a really kind of sexy way to do this there's like 10 other ways to do this in scholar you can zip it you can do the expansion of the four comprehension which is flat map and map and there's a bunch of other ways to do this as well so questions about that yeah so you can do a future.sequence in a future.sequence you pass it a list of futures and then that creates a wrapper future single future around all those futures and then when all of the future is complete then you get a list of all of your results from from all those features so future dot sequence one way to do it uh but there there are others as well so yeah um yeah so under the covers we use ning under uh underneath it all and that's based on java nio and neti um we we will probably in the future change this to to sprays uh http library um but for now it's based on ning yep yeah other questions about reactive composition and how that works okay okay so we've we've got the basics of async and non-block in now let's go on to how we hook it hook this all up to the client side before we do that i'm going to change out i'm going to add another controller method here that's a little more more useful for for displaying some some interesting data so very similar to what we've seen before i have a new controller method this one's going to take a parameter which is the the query string or a query of type string and i'm going to use my little twitter search proxy service to make requests to twitter search request to twitter the reason why i have a proxy is because twitter doesn't let you hit their json api without an api key and i don't want to go through the rigging role of setting up an api key right now so i set up a little proxy that does that for me okay and so then let's import this thing so what i'm doing is when i get this response back from searching twitter i'm going to return a response and i'm assembling uh all of the the the tweets that i've just found in the search into a json array so this is accessing the json it's finding all of the uh the text elements in that json structure so that's the the property name that that twitter returns and it's json to actually get to the tweet and then i'm doing a distinct on this because when i get into the angular side the way that i was doing things in angular it required each of these elements to be unique so that's my my easy way to do that so there's there's my controller method let's add a route for this so let's call it tweets and this will be tweets and q is the the query string parameter that we're going to pass through so let's go test it out here let's go to tweets question mark q equals reactive let's see so there we go now we see my json array with a bunch of recent tweets mentioning reactive so there's my my twitter search service and still async and non-blocking obviously okay so that's my json service that i'm going to be working with so now let's go on to the client side of this thing with angular so there's going to be a little bit of setup to set up angular i'm going to use angular angular it's really the the becoming the de facto standard for client-side javascript frameworks now so if you're uh if you're looking at the different javascript frameworks just go with angular it's six months from now you're going to regret it but you don't have a better choice because there's a new javascript framework every six months that's a new hot thing so go with angular if you're deciding now and so that's what we're going to do tonight so i'm going to pull in a few dependencies here into my build looks like i already have most of these i'm not going to use require.js tonight angular and require.js really don't work very well together you can make them work together but angular is really not intended to asynchronously load things there are some hacky and crazy ways to do it uh if you really need it you know go go find those ways but but the two just really are not real compatible i've heard that oh and i don't need these two duplicated i've heard that in angular 3 or two whatever the next major version of angular is that they're going to try to address this but that's a ways away so we're not going to do the um the required js stuff tonight if you want to watch the video on how you can do require.js concatenation and minification then watch the video from from last night okay so we've got our dependency on on bootstrap and on angular so we're going to be using bootstrap for the css and angular for the kind of mvc part of this application web jars are client-side javascript and css libraries in jar files and on maven central so you can easily specify those and get the transitive dependencies and that kind of good stuff so um so we're going to set up now our page to pull in these pieces so let's go to here and let's go it looks like i already have some of this but we'll just override it so i'm going to pull in the bootstrap css the way that i do that with with web dryers is i'm i've set up a route so now i'm using reverse routing that's where i'm doing routes dot web jar assets i didn't mention reverse routing but real quickly reverse routing and play is that we create the forward definition of the routing in the routes file that's this one but play compiles a reverse routing definition as well this provides a type safe way to look up routes so you don't have to hard code routes in your code and that obviously makes it hard to refactor your code so we we compile for you this reverse routing table so routes.webdriverassets.uh that's looking up a route to to uh this this thing and then i'm using this web driver assets locate to find the the actual path to bootstrap.css because the web dryers are intentionally structured to have version numbers and and library names in them and that makes them really easily cacheable the client-side assets here and easy to put on a cdn but we don't want to clutter our code with the version numbers and that sort of stuff so so this is just a little helper library to get that path so then i'm pulling in the angular min.js and then i'm going to be creating a main.js script that's going to to be my my main javascript application i'll be working with so that's my my basic boilerplate page now let's go create that main.js file any questions before i do that about the the set up here with web jars and and uh require j or i'm not using require.js with angular and and web drawers and stuff questions about that yep is there any sorry what um you know i you you can pick all sorts of different options there's we actually for activators ui we use knockout uh backbone is a more traditional one there's ember there's there's really a hundred different ones those either been in the java world for a long time you'll remember when there's an explosion of web frameworks in the java space the same thing is happening right now on the javascript side just tons of them tons of new ones angular is is has a lot of momentum right now partially because google is investing a lot into it and so it's it's um it's getting a lot of investment not just from google but but also the community has really great components has integration with bootstrap uh so it's it's definitely um it's not just the uh a hype thing it really is a good framework and it's it's super simple you'll see once we get into the code did that answer that question okay yeah yeah modularization in angular is really hard um to do it asynchronously you can you can load everything up front and it works really well but but to to do basically lazy loading on modules in angular is really hard there are ways to to trick it and do it but but i've run into some issues with that so so i wouldn't recommend it um okay so we've got our basic setup here so now let's set up our page with some bootstrap and some angular stuff on it um that will go in here so um i'm not going to be using the main or the index.scala.html too much anymore i'm just going to do it all in a single page we don't need to really use reuse this so first up here i have a nav element this is going to give us our top level navigation in in bootstrap and then i have a div i have another div inside that and now i have a angular controller called hello and inside of this angular controller i have a form and i'm uh setting up a submit handler on this this form so that when when i hit submit in the browser it's going to call a send name function in the javascript code that i'll write in a second then this form has a label a input for the name and then a button and then i also have in here a ul and a list item where i'm going to tell it to repeat for all the tweets uh this list item and then just display the the tweet so this is data binding in angular so what i'm doing is i'm binding the the actual tweet here to the contents of the list item so that's the html side of of our simple little ui any questions this will probably make more sense once we see the javascript side of this but any questions so far about this okay so let's go i'm going to just copy and paste the the next part of this here so this is our angular javascript code that we're going to be using and so what i'm doing is i'm creating a new angular module called my app and i i'm not importing any any external modules you know you can import like the angular routes module or the angular animate module or other third-party modules here but in this case i'm not using any of them and then i'm setting up a controller my controller name is hello that corresponds with with my ng controller there and then i have a function that's going to actually set up this component for me and so this function can take a bunch of different parameters and in this case i'm taking a scope parameter an http parameter and a timeout parameter and we'll i'll show you why but these the the syntax is a little funky with the dollar signs i'm not sure why in javascript world they chose the dollar signs but that's the the um the syntax so then now in this on this scope one the reason why i'm using the scope one is because now these things get scoped to that component so this now has a component model that i can use with events and with state and and binding so i'm setting up here my message value is just going to be empty at first so that binds into this mess i'm not actually using that yet we'll use that we'll use that part later then i have my send name function and this is what's bound to hitting submit in this form so that's the function that actually gets called when i hit submit on in this form then when we hit submit what we're going to do is we're going to use the http part of angular which is just a wrapper around xml http request and now i'm going to make an http request it's going to be a get request the url is going to be tweets and then the parameters are going to be the q is my parameter name and then the parameter value is my scope and then your name if you look back here you'll see that i'm telling it through this ng model declaration that uh the it that's the name of this input form and so that's how i pull the value out of that form and can pass that there and then success is the the callback function for when we get the successful response back we could also set up air handlers and that and then what i'm going to do is i'm going to set set the scope that's this component i'm going to set its tweets to the data that i got back which is just an array of of tweets if we look back here those are bound here in the ng repeat and should show up in the list items so now this is all built on top of that async and non-blocking controller that we created earlier it's going to make a request to that so let's go try it out and see if our little app works so one of the oop and angular men ah i need to restart because i added some dependencies oh should we automatically do that something we want to work on but we'll have to restart to get those dependencies so the error was saying um i couldn't find angular min.js which you told me to look for and it couldn't find it because it's looking for it in the class path and we don't have it in the class path until we reload that that spt process so there we go we see my page and i'm not sure why we have all that weird space at the top um but oh well oh you know what it probably is i think i'm using an older version of uh of bootstrap but okay so um so now we have our form and for some reason it is not working this should be bound oh forgot one piece um we need to tell this thing that it is an angular app in order for this whole thing to work and i need to use my cheat sheet to find out um where what that thing looks like uh forgot that in my documentation so there's the magic right there make sure i didn't forget anything else so this is how we tell this whole thing to to to start working so now let's reload this and try again there we go okay looks like it's going to work now okay so um so we've got my form and it's asking for a name and let's just go put in a name like reactive and hit send that should make a request out to that twitter search service that's async and non-blocking and then when it returns a response then we get back uh the tweets something good in there uh so there we go and obviously if we make another search then then it should go refresh that so the cycle is we can pull up the network inspector here and and see what's going on so when i make a request that makes an ajax request to my tweets service and then the response comes back with the json array of of the tweets that it found from that twitter search service and then that is just updating my variable and my scope it's updating the the scope tweets and then the binding is kicking in and using that to to uh iterate through create the the list item elements with all the tweets okay so this is now async and non-block in all the way through from the client side all the way back to the backend service which is which is twitter so questions about all that stuff before we go on cool yeah um so twitter they do use scala they use finagle they are all async and non-blocking that's the only way that they can scale and so when i hit their service their services internally are all async and non-blocking that doesn't impact me at all because no matter what my web service client library is going to be async and non-blocking to them and how they decide to to handle threads is totally up to them in twitter's case in particular they do they are async and non-blocking and reactive but um but totally that's on their side um from my side as a client to their service uh i'm gonna be reactive at least that far yeah okay other questions about this all right so that's that is uh reactive request and reactive composition now let's go on to the next piece where we um where we get two-way so oh no before we do that we have to talk about actors okay um so um right now my my controller code here uh it's uh it is just based on futures and we have another model for concurrency and the typesafe platform called akka and akka is another way to manage this this concurrency and so we can use an actor model and the benefits of using an actor model are one we get timeouts built into it two we can go across across a cluster we can distribute these jobs across a whole cluster and then we also have a supervision and resiliency model one of the tenets of reactive is to be resilient and futures we do have a way to recover from failure but there's definitely some places where actors provide a much more much stronger way to to be resilient than than futures do and recovery on futures it provides uh with akka persistence now in akka 23 we can even persist these messages and guarantee once delivery on those messages so there's uh there's a lot of additional resiliency that we get when we move to actors so i want to show you how we take this code that i've i've written and turn this now from a future based implementation into an actor-based implementation so to do that um first we have to create our actor so let's go create a new actor here and so this will be a new scholar class we'll put in the actors package and we'll call this one the twitter actor and um this will extend actor let's import that and an actor the way that we uh the only way that you interact with an actor is you send it messages and then those messages go into a queue managed by the actor system and then one at a time we process those messages out of the queue and so the way that i do that is i override a receive method r-e-c-e-i-v-e receive is that right e before i um except after c no i before e except after c that's the rule uh okay so we have this receive method and this receive method is now going to handle when this actor gets a message and so what i'm going to say is that when i get a string method so i do pattern matching on this thing when i get a string message then then i'm going to now let's go just copy and paste this code so i'm going to now handle this this stuff that i was doing before so we'll paste all that in there so that we're going to make our request to the twitter search service let's rename that to q so that that works and then we let's assign this to our future response okay so when i get a response back from this twitter search service i don't i don't want to put my results in here i just want this to be the the js array um so what i'm going to actually return is just the the json array of data back from twitter so but i've i've made i've sent this message to this actor and really what i want for this web controller to get i want it to to be able to send a message but then i want to get an answer back and so there's a syntax in you can you can do this by sending a message to your sender so in an actor we always have a reference to the sender the person who sent us the message so i can just send a message back to them but there's a little bit of a problem in doing that because right now i'm actually going to be getting this response back on a different thread and so it's possible that my sender could be different my sender reference or state that i'm closing over could be different and so the way to deal with this is akka has a pattern for for handling this it's called pipe and so we're going to import the akka pattern pipe and then i'm going to say with my future i'm going to now pipe this to the sender so now this says it's a it's a way to send the message send this message which is my json array it's a way to send that to my sender but do it in a way that's going to be thread safe so that's that's a pattern we have to use when we're in this async world inside of an actor okay so we've got the actor that all looks pretty good i'm probably gonna have to import some execution context and stuff but we'll get to that in a second so now my controller when we make a request to the service i now want to send a message to this actor and have the actor give me a response back so to do that first i need to create the actor so let's create our actor ref in aca we never work with actors directly we always work with references to the actors part of the reason is is that the actor can be restarted out from underneath me that's the resiliency model in aca is that this actor can go away and then come back through a restart and so we don't work with the actual instance because that instance could die so that's one reason another reason is location transparency so this actor could actually be somewhere else on the cluster and i want to have one way to to interact with the actor so i work with it through a reference and the way that i create this reference is i'm going to go to the actor system in play let's import that so let's go to the actor system and i'm going to tell it create me an actor of and use props uh and then props is the way that we can create um we tell alka how to create an instance of an actor so i'm gonna do a props of my twitter actor there we go so this tells this tells akka how to create this where to create this what class to use to create this instance of this actor that's underneath all this but what i get back is a reference we look at actor of what it provides back to me as an actor ref okay so i've got my actor ref so now when this request comes in i'm creating a new actor ref and now i want to send it a message but i don't just want to send it a message i want to send it a message and get a response back so there's a pattern in akka to do this we have to come import it it's aka pattern and then ask is the pattern so instead of just a tell is ascend and then an ask is a tell and then a kind of wait for response so i'm going to now tell my actor ref i'm going to say question mark that's the the function to do an ask so i'm going to say send it q okay so now what i get back from doing this is not the actual thing because we want to be reactive we want to be async and non-blocking so i don't get back the actual result i'm going to get back a future of whatever this thing wants to send me back so let's just assign that to some value here so that's going to be my future if we look at future it is a future of any so i'm getting back a future of any because um akka can send any message type we don't know what it is and so we're going to get back a future of any so now i'm going to take that future of any and i'm going to map on that future of any and i'm going to say if this thing is a js array um we'll assign it to j and js array so if this thing is a js array then return ok and then just return in the body that okay that j okay so when we get back a response from the actor if it is a js array we're going to return it there's obviously other ways that that we could do that as well but that's kind of the easy one so now this f.map is going to return a future of a result okay so let's go try it out we are going to need some imports here for for some implicit so let's see first in our actor we need to import the play app so let's go do that and then we're probably going to need an execution context i'm so glad i can just copy and paste that whole thing there and then one other implicit so this is where the timeouts come into an actor has an ask against an actor has a timeout that i need to specify and so we can specify this as an implicit parameter so let's come in here and to my controller and i do need to specify a timeout obviously through uh implicit resolution i can specify it at lots of different levels but let's specify it here for the whole object so timeout uh oh and this needs to be implicit and this is going to be a duration of five dot seconds give that thing plenty of time to resolve and do that should work right oh no timeout timeout not a duration why do we have a timeout and a duration i think it's because a timeout is finite and a duration is not or doesn't have to be finite okay so let's try this again i think i'm still missing one implicit maybe maybe not we will see looks like it's compiling no it worked okay cool okay so now we've moved this this logic into an actor we're going to get better resiliency we could move it on around on a cluster all sorts of good reasons to put it into an actor but it should work now the same way let's give it a try yep and it looks like it did the other thing that i haven't showed yet but we could certainly do is i could add timeout or fail your handling on this future so that we could have a case that that we return some logical air if there is a timeout in not getting a response back in a timely manner from that actor okay so now we have actor-based reactive controllers there is one problem with this code which i'm not going to go into but i should probably actually shut down this actor in this case because on every request i'm creating a new actor and i can have millions of actors on the system they don't use any resources when they're not processing a message but they are going to eventually chew through my heap and so i should at the end of this shut it down or i should have a different mechanism for how i create these actors i could have pools there is there's different routing mechanisms in akka i can set up basically a router actor and that can route to a pool and it can use round robin and it can use smallest mailbox and all sorts of different things so there's lots of different ways to control the life cycle these actors how long they're around the the routing of the messages all that kind of stuff but this is the wrong way to do it because i'm not shutting down this actor and eventually i'm going to run out of memory so that's that's the actor so questions about the actor-based controller okay all making sense good okay so now let's go on to we've got our request handling with actors let's go on to two-way reactive with web sockets so it's great that now we've done this request response in and out but let's do something more exciting where now we have a bi-directional reactive channel so we have a reactive channel to push from the client to the server we have a reactive channel to push from the server down to the client so we're going to use websockets for this you could use things other than websockets if you want i'm going to use websocket so first let me build out the client side of this this app just a little bit of html here so i'm gonna put in here a new binding for a message that we're gonna get and then i'm also going to put into my controller a little bit of extra code that we'll we'll walk through so that's in main.js and so what i'm doing is for this this controller i'm creating a new websocket connection in this case i'm hard coding this this url there is a reverse routing table for javascript and play where we don't have to hard code these routes that's the recommended way to do it but this is the the easy way to do it and now when i get a message on this websocket i'm now uh i'm have a function that's going to handle this message and this is a kind of tricky part about angular but because this is async because this message is happening async i may have lost my context my scope context and so the way to handle that is you put this into a timeout i'm not sure why it's called a timeout but you put this into a timeout block and then we're going to assign our scope message to the message that we received from the websocket and we're going to prepend hello in front of that okay and then let's let's do one other thing here um so when the user hits that button in the browser i'm gonna send a message to the websocket so i'm gonna send a message up the websocket and it's just to send the name that they put into the form this is still very request responsive but hopefully you'll see how this could obviously be used for not just request response type of stuff but really simple example here okay so that's our client side um questions about that questions about the the angular side of this the client side does anybody know why that's in a timeout i don't know how the timeout gets us into the right scope for this controller it's some something funky about angular that i don't i don't understand yet yeah i don't know i don't know why no that's that timeouts outside of the website so it's anything anything that i do asynchronously in angular uh to get the right scope i need to put in that timeout uh callback i have yeah i have no idea why um okay so now let's do the the server side of this there is a way to do the server side of the websocket with with iteratis um and that's the default scala api today in play for for working with websockets it's really simple you can see the code there but there's a new way to do it in play 2-3 and that's what i want to show you because it's it's pretty cool i'm pretty excited about this so let's just go create a new websocket handler and play so first let's create a new route so we'll do a get handler for slash echo dash ws and then this is going to go to controllers dot application dot echo ws and now let's go put that method in here import a few things and then we're gonna have to create an actor okay so there's this new api in play 23 where instead of using iteratives we can just use actors and a lot of times when i built uh when i built websocket apps in play before i was basically just delegating from the iterates to an actor and so this is really just a convenience for how to do that so in this case i'm just going to be passing strings back and forth so i'm going to get strings in and strings out and then i've got nested callbacks here to get the request and the out channel and the out channel i'm going to give to this actor so what i return in this function is the props the the thing that will create this actor and i'm doing it this way because i need to specify i need to give this websocket a handle to the out connection so that it has a handle to push data down to the client uh okay and this out channel i should mention is an actor so this wraps the the typical uh it is the the enumerator in uh in play this is a uh actor wrapper around the enumerator that's underneath the covers in in play okay so now let's go create our new actor here so create the echo actor and i'm just gonna copy and paste this code okay so i've got an echo actor let's import a few things here don't need that okay so um there's my echo actor you'll see that it takes a parameter which is our actor that we can send messages out through and then when this actor gets a string so it's going to every time a message comes from the client to the server it's going to send a message to this actor and so when in that message because i parameterized it here as a string it's going to to be a string message of course i could be using json or whatever else i want for this as well so then when i get a message all i'm going to do is i'm going to turn around and i'm going to send this string that i just got out to the out actor which is tied to sending sending through the websocket from the server down to the client so that's my server-side implementation of of the actor for this websocket questions about the server side before we try it out and see if it works okay so we've got our echo actor we've got our client side let's just go take another look at our client side so our client side when we hit this send button when we submit this form it's going to call send name we're using binding here to display a message property and in main.js you'll see that i am first of all when i when the user hits send i'm sending through the websocket the name that i put into the form up to the websocket and then i have an on message handler that updates the message property which is going to update the binding and display okay so let's go try it out and see if it works here so test and there you'll see that it updated now the binding so i sent the message up through the websocket that turned around sent it back down to me and triggered it so this is now two reactive push channels they're both push channels just in different directions so one from client to server one from server down to the client and if we want to prove that this actually is not any kind of smoke and mirrors let's pull up the network inspector here and we can see let's go send a message and if we go to frames we'll see here's the message i think this is the message up and this is the message down so we see those are the the message messages that got sent up and down so that's actually going over the websocket so now obviously this is a trivial example request response style but now that i have this actor on my system that all i have to do is send it messages and it can serialize those send those down to the client now i could do all sorts of out of request response cycle types of things through this so that's the the basics of the request of the websocket and doing reactive with with the websocket and an actor i could also show the enumerator more if people want to see that but um yeah so questions about how that one works okay we need some more beer liven up the place it's friday night okay i think let's see yeah so that's that's really all i had um we can do some general q a and then go celebrate alexi's birthday somewhere so yeah do you have any questions yeah go ahead so this is all the way through yesterday yeah oh i didn't show the um the spt web part of this so the only thing i'm really using from spt web here is that there's now an spt web this this cool uh linting tool so we run js hint automatically so you'll see i have i did a typo in my javascript and now just like i would normally see server side compile layers i see those compile layers or in this case linting errors right in my browser so this is using something called sbt js hint if we look in my project and then plugins.spt we'll see here is the i'm all i'm doing is adding that plugin there and now it's it's automatically applying that linting to all of my my the javascript in my project uh so that's that one there's a bunch more that i covered last night there's a required js one that does the concatenation and minification there's a coffeescript one which compiles coffeescript there's less which compiles less into css there's a digest one which creates digest md5 and optionally shot one digest files that contain those signatures in them so that we can do better asset caching there's a gzip one create gzip versions of all of our static assets and then spt moca is a new javascript testing plugin for sbt so that we can actually write javascript tests as part of our play application those javascript tests run when you run activator test so it's now built into the the test cycle of sbt so those are the current current new sbt web plugins and the whole architecture is new and a whole lot better um in a in a nutshell what we do is we actually run the the native essentially compilers which are all written in javascript all these compilers the copy script the less ones all those are written in javascript we run those and they're all written against the node.js api so we run those either on the jvm through an implementation of node on the jvm called triream or if you want to you can also run them through the native node executables as well so now we have uh we make sure that that the the asset compilers work the same way in play as they would if you're using grunt or some other tool so that's that's a short synopsis of what i talked about last night in sbt web a little bit of latency so that you know if you have you're just getting slammed with throughput you don't just keep pushing off these requests yeah yeah good question so there's there's all sorts of different parameters and different types of execution context that you can use the default execution context is fork join and it has some different parameters it's like your number of cpus plus one or something like that and so you can tweak those you can also use if you want to be able to get better throughput there's a different execution context you can use not fork join but i forget the name of it if you look for some akka performance test where they're looking for like just raw message throughput performance what they'll do is they'll switch from fork joint to a different one and then there's a way where you can actually tell the the execution context to execute like 200 operations on a single thread before it uses another thread and so that's there's all sorts of different knobs you can turn to to tweak your your throughput you know if that's what you want to optimize for but because we have this concept of an execution context we have this abstraction over how the threads are actually used how um how many threads are in the thread pool what the thread pull is actually using underneath the covers um all that sort of stuff so does that help with that question phil yeah okay yeah along with similar lines is there any facility or yeah good question uh we're working on something that will address that with actors specifically maybe there's something in open source already for this but we are working on something there the uh the iteratives when you're down in play iterati land there already is back pressure there so so iteratives definitely have back pressure built into them the one of the typical places where this gets used in play specifically is if you have a file upload coming in to your server and then you're taking those bytes and you're shoving them off to s3 you can actually put back pressure on the upload if s3 can't keep up with you so you're not building up big buffers in play so so that's a very we call that like 2a reactive uh or wait no yeah 2a reactive i think is what we're calling that so so that's that's where i hook two reactive channels together and can apply the back pressure all the way through that so yeah so that's built into iteratives uh there may be something already for actors out there i'm not sure but we are working on something for how many pool actors threads like between the handling of the request and the actual control good question yeah so we um it before like play two two one i think it was it was really bad like a single request would hit like 30 different threads it was it was horrible uh so we now have that down to two uh so we're we're doing trampolining on the x on the iteratives and the trampolining on the iteratives was fantastic work that rich doherty did in on the play team and that trampolining was able to to significantly reduce the number of threads that we're hitting and obviously get much better performance because we're avoiding all those contact switches so um so two is probably as low as we can get um but uh because of of how we're hooking netty to play maybe we could get it down to one when we switch over to uh to spray as the underpinnings there but um but for now we're at two so it's pretty good how do you is that any tool you recommend like if i want to see another line yeah yes uh it's it it's not exactly catered to this but i use um your kit which i thought i had installed but uh i thought that's what it was um where is that thing oh visual vm sorry not u-kit you can use u-kit but i've used visual vm and we could actually go in and see see my not intellij let's open up this one we can actually go see the the threads and stuff that are going on here so so this is a a great tool visual vm comes with the jdk but then your uk your kit i always forget which one it is uh is also a great tool there's there is some production monitoring support for for play and akka uh app dynamics has play and akka support new relic just has play support right now and we're working with them to improve that so you can get this kind of information in a production system so um so these are the best times uh the best tools uh ukit and visual vm for for kind of local mostly local development testing but production monitoring we're working with partners to make those better yeah is there a question over here yeah well sort of the point of using accuracy is because it seemed complex yeah yeah yeah definitely that's one of the downsides of actors is you lose some type safety you should use whichever api works best for you the one of the benefits of using actors is that now when i'm in a clustered environment now i have a way to communicate across those those things so a very typical example of this is let's say i have a chat room and i've got two servers and one user is connected through one server the other user is connected through the other server and i need to send messages to both of those i'm going to have to have some way to broadcast a message to the actors on each of those nodes because those actors are what's going to there would be really no way to do this outside of a message bus with iteratives but with actors now i have a model where i have an actor for each of those users and then if i want to broadcast messages to them i can send through aqua clustering i can send messages there's a broadcast message in akka clustering so i can broadcast a message to the cluster then both of those actors could receive that message and then send that down through their channels so that's that's uh one of the primary places where it makes sense but if that's not a use case that you need then then you know you may not need uh in this case you may not need actors so yeah good question cool any other questions before we wrap up all right where are we going for drinks okay who are the locals not me where should we go for drinks anyone it's a lexi's birthday so we gotta live it up beer yeah well if you want to go out for drinks find us we'll we'll all be going out yeah thank you thanks cool thanks for coming