 I'm Konstantin and I'm here to talk about real-time rack up front. I have to say this you'll see a lot of code in this presentation so if you're easily offended by code you should leave now. Before I get to rack I'll talk a bit about me so you get to know me I'm from Germany and I'm I have a blog I'm on GitHub like probably everyone else of you I have this extremely long Twitter name so it's probably best you just go to my blog and click on the URL to Twitter so you don't have to type that. I'm mainly still a student at University and I work part-time as a Ruby developer and I love code I love code so much I put it in nearly every slide even the second slide about me so if you check me out on GitHub I'm currently taking care of the Sinatra gem you guys probably have heard of it and also lots of other gems you guys probably haven't heard of and I'm regularly contributing to tilt and Rubinius and stuff like that rack and I also spent like the last summer working on Rails for Ruby Summer of Code and if you check out my GitHub page my most popular project is called Almost Sinatra it's a Sinatra clone in eight lines of code and yeah just wanted to include that the I know if you saw the literal criticism talk for Rubius there was a great talk I really had to really remind me of this project it's just some nonsense I did and it becomes super popular it was like for two weeks or so it was trending topic on GitHub that's just crazy and there were actually some people that didn't get that it's a joke actually asked for me to can I combine that with fiber so it will scale automatically stuff like that so and who have you seen the talk about event machine by Matthias good good it will probably be helpful so if you saw that then you'll probably notice a slight difference to my talk so yeah I've no memes but that one and I included it to create a paradox on so you if you would like thinking about the paradox and all the time I'm sorry so rack I'll tell you how to use rack for stuff it's not meant to be useful so if you if you take real time web responses in Ruby all the talks I've seen almost most of the talks I've seen so far just deal with him here's this awesome library to use it to use and I'll tell you how to use it and this is not what this talk is about I'll tell you what mechanisms the the libraries use under the hood so I first have to make sure you understand what rack is so but why would we want to do you want to do this if you're building like a rich rich internet application like Twitter or so where you where you have a constant updates coming in without having to reload the page from others sort of interaction you you want to avoid polling the updates you even want to avoid long polling which is a technique thoughts and owners comment where you're just fire request and and it doesn't the server doesn't respond until until something happens so you're not like polling every second for for for updates and this is the basic idea is to decide to decide from this I'm talking about a server side like most of the time and from the server side the the important technique is to just start streaming to the client and then while streaming decide what to stream not up front this is the basic principle of real-time HTTP communication and you can use that for like streaming API's like the Twitter streaming API some of you probably have seen that and then there's one thing that is pretty uncommon at the moment still unfortunately that's server sent events and of course web sockets I'll go into detail about those two so I'll start with the demo just to to show what's possible all of you should be all of you should be familiar with this little thing you should know it from Ruby development where you can just go like oh one plus one yeah that's too cool yeah yeah so this example is using server sent events to to so the my presentation is using show of don't know if you guys have heard of it that's by one of the github guys it's a presentation to where you're basically your presentation is a website and it's served from from rex server it's written in with Sinatra so I have basically have to use it and I'm I'm using server sent events so I'm this is basically just an input field you see the completion and I'm using I just posted to the server and use server sent events to stream that in that in back at me and that's completely evented so nothing blocks the event loop short demo so this is just going on until I stop it so there we go it's and it's all triggered from the from the from the server side so that code is actually executed on the server and stream back to the client which is yeah I kind of like that so I hope all of you know at least have heard about rack rack is like the protocol specification on how our web server is able to run Ruby web application like rails or Sinatra and any web server that speaks it can actually run rails up so like I've used passenger here to just and passenger just speaks rec and can run rails and unicorn can run Sinatra and even Sinatra can use a rails application and you can like build crazy crazy trees of applications where they just hand on the information and yeah this is this is the start of the of the middleware tree for the current presentation so as you can see of the of the example embedded into the into the rec middleware tree and that's why it's just being served from the presentation I'm just going to go through this quickly so I'm too to make sure we're all in the same page here so this is the basic rec application a rec application is any Ruby object this that responds to call call will be called on it with a with and with an n-fash that's a normal Ruby hash containing stuff like HTTP headers or other means of communication and it has to return an array with three elements the first one is an integer for the status code the second one is a hash of headers that will be returned to the HTTP client and the third one is an object that responds to each and will call for will yield the block that is passed to each for strings that will be sent to the client and you can write it obviously simpler in Sinatra this is basically about the same it really doesn't do much more but check in the path so I'm going to use use Sinatra just to show for cool it is a few times in this presentation mainly to to reduce the code on the slides because to show what's important and you can write your own middleware this is a stupid little rec middleware that you can chain in front of your rails application that will take the response body and just make it up all uppercase like in the comment above and it does so by calling call with the n-fash on on the application you're chained it in front of it and then loops through all the all the strings and and up case is done yeah and I could have used map but that would like violate the rack protocol because I can't just assume it's an array yeah that's how you really would use it and like in conflict or drew if you ever seen that it's like in your rails three app there's one and yeah and this is what the server would do it would like pass the incoming HTTP request create a hash from it and for all the middleware it creates an instance of that middleware with the with the app it's wrapping as parameter and then just calls call and from the result generates HTTP that this is really important to this is the basic thing we have to trick because there's no that's it doesn't intend you to to do streaming and real-time stuff at that point so but the cost the main thing is it's actually doing it's processing the request handing it to your application the application is then generating a response and the web server is from that generating the real HTTP response there's no way to do to do to send just a bit and then later on just make up your mind and send something different but there are there's streaming built into rec you can stream with the method each of the return body by just returning any object that that implements each and and yeah yield strings for that this rec application would actually 20 sleep one second after every every every paragraph with the current time in it and and do that 20 times but their issues with that I come to that later and you can use that to do this is pretty stupid because it you could just generate that you know up front what's coming and let's build a messaging server like imagine we are doing an app app in a shed application a website or something like that and everyone everyone that's going to the website should get an push notification we could do it like this where basically we have two routes to actions where one where we create this magical subscriber object and just stored for latest so with one subscriber object per open chat connection and then if someone just posts data to the server we'll just use the message and propagate it to all the subscribers and the subscriber is pretty easy to look something something like this basically it's about the same like the like the first streaming example example we have a sleep and the year with the string we just sleep for an indefinite time until someone decides to wake us up and then just we'll send the we'll send the line we're supplied with now if you if you do a lot of programming with concurrency and so on you're already noticed that this isn't really the really good thing cause it blocks the current that the sleep call it assumes that you have one thread per per incoming request which really doesn't scale because creating threads is expensive having pets in parallel is expensive and it doesn't work well with middleware remember the middleware where we where I upcase everything if you if you do that it will wait it will actually call each before handing the response on so with the with the 20 times 20 lines example it will actually take 20 seconds until it reaches your web server which then can propagate it to the client and with the with the chat example it just will never reach the web server because you just keep the connection open indefinitely and it doesn't work like at all with evented servers like thin goliath app and rainbows because the the it will just pile up the events the the the data sends in the event loop but you'll never reach the end of the event loop because with the sleep you are blocking the event loop so what we really want is invented streaming and this isn't this isn't part of rec this is if you take just the rec specification this is impossible but thin and rainbows and the other servers expose an API for that they have an asynchronous callback feature which allows you to to do the whole thing asynchronously and you will have an event loop where you already know you already know about this from the event machine talk that the other connections are coming in in the events in the event loop and the callbacks are fired which is the root processing and and you just have to register new callbacks instead of blocking which is web scale and it looks like this in this example we're we're we're trying to we're if the client sends a request we keep it waiting for 10 seconds and after that 10 seconds we are sending our response but we we are able to answer other requests in the meantime from the same process from the same thread because we we have queued it on the on the event loop by using the the asynchronous callback which is basically just a proc or a method object we can call call on again with the with the rec response and the tricky thing is we have to tell the web server to not respond yet to just keep the connection dangling until we decide to respond and there are two ways to do that one is with throw don't know if you guys have ever used throw it's like raising an exception but it's not an it's explicitly not an exception so you can catch it somewhere with the catch method show some code in a minute and basically you can implement your own control structures like break and next with that and this will skip all your all your middleware so you eliminate the issue with the with the with the middleware that's like like the up casing middleware that's blocking your your connection by just throwing that right at the at the web server and the other way is to return a status code of minus one this actually will go through all the middleware but it works well cause like nothing bad happens if the if the up casing middleware calls each on this empty array and status code of minus one tells the tells the web server that you you're going to respond later to that the main issue with this approach it's far nicer this approach because your middleware can if you have middleware that is logging requests the the request won't just disappear from the lock they will still appear and and stuff like that but the main issue is that rack will complain about this in development mode since minus one is an illegal status code so you have to either run in some other environment or you have to monkey patch reclaimed which is pretty easy but ugly and yeah again you can do this easier in Sinatra there's a Sinatra async gem by or async Sinatra as the gem name by James Tucker which does gives you this a get and does all the asynchronous response stuff for you and this is this is somewhat what the rack handler will do it will pass the incoming request generate the n-fash from it it will set up a callback that will then in turn actually generate the HTTP response rob everything in a catch so you can just leave the the execution with this gun and yeah just call your application and if your status code is not minus one it will trigger the the the HTTP generation this is pretty close to what thin and up to I'm not sure about the others I haven't looked at the code but this is basically what really what's in there they're using methods instead of proxbyn you get the idea but that's actually not streaming that's that's postponing we don't want to send the request after 10 so we do want to send the request after 10 seconds where keep in mind the timer could also be not just wait 10 seconds but actually wait for like our red is back and to answer or anything else fire request to another website and then use that response to generate our response so how can we do the streaming thing because if you would like if we if we would return the subscriber object from earlier again we would be blocking the event loop which we are trying to avoid if you've been to the red is talk he already mentioned event machine deferrable which can be used to register callbacks can create an object that has the callback interface and if you return a deferrable object as body the server will actually wait until it succeeds so on deferrable object has three states where it hasn't succeeded yet and the state where it succeeded or where it failed you can register different callbacks for that so we have to modify this code because it's not hasn't integrated the asynchronous handling yet so the asynchronous version would use a get for example and we don't have to return a string here because we the return value doesn't really matter yeah but that's about it the question now is how would the subscriber look like yeah it's pretty simple we create just our own deferrable object and instead in instead of calling the block pass to each we just stored for later so we can call it any time at any time we call it the string will be sent to the to the HTTP client like this and we no longer block anything and to close the connection we just have to call succeed on on the on the body object and one use case is service and events you've seen it in the demo service and events are used like this from the JavaScript side they're actually built into WebKit and they're coming for the other browsers and they're like a one way what's web socket we're just stream from the server to the client you can't write on them from the client side but you can just fire new Ajax request for that and they don't need an protocol upgrade I come to that in a minute this is really big issue with with web sockets they are resumable that means if the connection is lost they can be they have built in functionality to recognize at what point you actually lost the connection and start streaming from there without you having to write basically any code for that and you can actually implement them in JavaScript for modern browsers I think you can't for Internet Explorer 6 but you can for for Firefox up back to something so there's no reason not to use them if you just don't care about Internet Explorer 6 and they degrade gracefully to polling so if yeah that's the way you could actually use them in Internet Explorer 6 that's related to these resumability but then again we trying to avoid polling so you probably want to use flash or something else and Internet Explorer and this is the complete server-side implementation of such an event socket it's pretty much the same as the implementation you saw before but it has just a bit of metadata one data element is prefixed by data and you send an empty line in between and this and you can add an ID this is used to resume yes if we have time I can show you the the code of the of the web IRB session afterwards and then finally there are the glorious web sockets they're like two way event sources web sockets have major issues for one the client needs patching it needs to be aware of of protocol upgrade so you can web sockets don't rely on pure HTTP they add features to it and you have these upgrade headers and the server needs patching the server needs to be able to to use the to also perform the protocol upgrade and all the web socket implementations that bring web sockets that to rack they actually patch thin or rainbows or so on more of what the proxy needs patching HAProxy isn't able to handle web sockets that just doesn't work because of the protocol upgrade again and rack needs patching because even though there is a way to to stream from the server to the client it doesn't work well with the other way around and it has major security issues that's why web sockets are disabled in Firefox 4 and opera so it won't work on most browsers you use it like this and you might be saying wow I know this looks pretty much like this and yeah that's true you the only difference mainly is that on the client side you also have a send method for the web socket so you can actually send data and you can use it for instance with the EM web socket implementation and you basically have the exact same protocol like on the client side on the server side and one last method for streaming is the speedy protocol it's actually created by by Google if you have a decent version of Chrome and you're browsing a Google service via HTTPS it's actually not using HTTPS but speedy instead and it's modified HTTPS version where they actually send multiple requests over the same SSL connection and the fun thing is that you have this SSL connection already open so why not do pushing over it just as soon as you have updates and Google is currently doing that for instance a few on Google Maps they're using push notifications I think and for Google made stuff like that there's some threatened articles about that how they're using it but the the main issue is there's no Ruby implementation so far making use of it so you can't use it now and it's only supported by Chrome but this is an interesting thing because the the HTTP protocol sent over the SSL connection is basically still the same without the protocol upgrade so I was intentionally keeping this a bit shorter so I can go at the code and demo that a bit and yeah so the the code is rather short for my live demo the color scheme sucks then how do I change it he wrote the editor Mac classic yes this works so here's the this event source implementation is exactly the event source implementation I showed before with the yeah it's 100 percent the same and I'm doing also about the same I did in the demo I keep a list of subscribers and also I keep keep a line number I this is the the number of the like for error messages so if you're in the live demo if you produce an error actually contains a line number which is increasing and I use that I just counted up and I use that also as an ID for the resumability the browser is using that to to recognize if a line has been sent two times yeah apart from that it's basically the same I have I have to keep the binding so I can actually access local variables yeah so to make this work I have to use the same binding over and over again yeah and I implemented the same method basically to do the timer thing apart from that this is the complete implementation is including the including the templates is about 120 lines including new lines and and CSS and the JavaScript I actually use coffee script and yeah all I do is just execute the code capture the output and if there's an error display the error and just propagate that to all clients it means if I open two sessions they will share the same same IRB session actually and yeah the the the client site is also pretty easy it's this is mainly for just output and input stuff I have a form and I just intercept submits form submits and instead do a post manually and refocus and yeah here's the the actual code is here down here so I think I'm I was rather fast so if you have question to the code I can't show you anything or if you have other question or I could tell you more about any part of the talk no okay in that case we have like 13 minutes left it's short okay then the monkey patching for the linter I don't have an example right now but I can go into rec it's basically like one method where it checks the check status and the searches that the status must be bigger than 100 and if you do something like this it will just work so any more questions you probably don't want to use this directly you probably want to use a library but I find it rather important that to understand what's going on under the hood and people often pop up an IRC that asks questions about this because there's next to no documentation about this so there's this documentation that you can use as a callback but apart from that so the like the deferrable thing I had to figure that out from from reading the cramp code cramp is an asynchronous web framework was already mentioned by Matthias yesterday yeah so you have to do pretty much of digging to to find those solutions yeah so you can use something like socket IO that uses web sockets if available if not it's degrading to to service and events and if that's not available it's trying flash and silver light I think and if that's not working it's degrading to to long polling so that's a nice library that wraps it I think there is there are ruby bindings available there's your client side JavaScript and there there's an server-side implementation for no chairs and I think for a ruby yes oh cool cool he also did the em web socket implementation I think and was mentioned yesterday a lot yes that's the same guy so any other questions okay and thanks my slides are available on github