 All right, I'm gonna start with apologies. I've been having a lot of slide envy and presentation envy. So I've used a time-honored method of getting someone with a British accent to make my talk sound more sophisticated in certain parts. Also works good for imagining what the ancient Romans might have sounded like, because apparently that's what you do in new things, but there you go. So I did see in some talks here, I realized that they seemed like they were nowhere as dark here. What people are concerned about. So I have two alternate subtitles for my talk. We own the rails while still using rails. Or... Rails come the other stuff I want anymore and fill it with tech. Makes me want to cry. There you go. So the prayer of the day to this president is a question. So why have you come here and become? Now arguably the answer for that is that you like Ruby. So that brings another question. Why do you like Ruby? Arguably again, because it makes you happy. So for me, the purpose of life is partly to have joy. Programmers often feel joy when they can concentrate on the creative side of programming. So Ruby is designed to make programmers happy. Yes. Ruby is designed to make programmers happy. So therefore you could say, happiness is the Ruby way, right? The objective then of this talk is to ensure that you, the Rubyist, stays happy. There's always memes or two that go on at RubyConf. So happiness is a recurring theme that actually is the same theme I realize in all my presentations where I seem to pick technology based on what makes me happy. I call it JDD, Joy Driven Development. Basically it's about coding and loving it. So if we talk about what do we like about Ruby? The language itself, it's pretty wonderful. I think most of you guys know that, right? An entire talk can be done on that one, so I really won't do one. But I will point you to an example I came across. So I was doing some devise config editing recently and I came across this one line, config.passwordlength is 82128. And so what I really like about this in Ruby in general is that the intent. The intent is just so clear, right? There's nothing extraneous there, just the essence of what you want, right? Typical Java or JavaScript way might be something like new time range, eight. Peren, eight comma 128 close peren, right? Just less noise. It's beautiful. All right, there's, in theory, there's sound here. Okay, you missed that one, that was music. Oh, I can play back. Okay, so Ruby makes me happy, right? The other thing you might like about Ruby is all the gems and frameworks, right? There's lots of gems, almost anything you could pick from. Even among those gems, there's choice. Sometimes there's more than one gem for the job. One is maybe more suited to you than the others. Gem authors tend to emulate max in that they want to make software that makes you happy too. There's lots of really elegant DSLs, right? And so if we're gonna talk about Ruby gems, the 800 pound gorilla of Ruby gems is really Ruby on Rails, right? So for Rails, show of hands, who codes in Rails? Pretty high percentage there. Who came to Ruby from Rails? About a third, I'm actually surprised. So then the other question is, of course, who is coding Ruby before Rails? That does not add up to 100, I gotta say, 100%. And so who loves Rails? I do love Rails. I mean, there's reasons to not love Rails, but there's reasons to love Rails. And lastly, who has a job because of Rails? All right, it's clearly the majority, right? So Rails has been good, so why do we love Rails? Whole talk can be done on this, I won't do one. But in nutshell, productivity, right? We're all very productive in Rails, and you know, Matt's talks about Omokase and his tailored to him, make me happy sort of thing, and it tends to make most of us happy when it does what we want, so it's a good thing, right? So. Oh, you're my favorite. So Rails can make you pretty happy. The problem now is Ruby's not a panacea, right? It's not a solve, it doesn't solve everything for you nor should it. Some reasons you might not use Ruby are just pure speed. So you're doing image processing, video encoding, stuff that does not a good fit for Ruby, right? Scaling, Ruby doesn't scale so well, things that are resource heavy, computation heavy, not the best fit for Ruby for the most part. Sometimes the functionality you want is not in Ruby, so if you want to do, say, scientific programming, Python support is better. Be kind of silly to rewrite that unless you really have to. So these are all legit reasons not to use Ruby. The problem we get is some of these non-Ruby things are less happy-making, right? We already established that being happy is important here. So common alternative is, of course, node, right? Node. What is. Okay, it's not true, it's not good for anything, it is actually good for some things. Quick, non-blocking IO concurrency, these are typically the things you talk about. So very often you use the chat app to demonstrate the sweet spots of node. What's in a chat app? It's high concurrency, lots of people talking. Quick, very low CPU transactions, that's chat. The server push thing that's so popular. It's what they call the modern web app. That being said, so node is not good at everything. What's it not good at? Vertical scaling, they're trying to work on this, but it's single threaded, they're trying to fork, all kinds of stuff, not particularly good at this. Once you do CPU intensive or slow running things, you lose the entire benefit of node. So if you start blocking on these things, then no point in using node unless you like JavaScript. Integration with other systems, not particularly good, not necessarily worse than anything else, but not really designed for that. Language, right, we're at RubyConf, so the Ruby bias is JavaScript is no good. So too much JavaScript and sad panda is sad. So the question is, how do we bring back that word? One way is vertex, right? So who's heard of vertex? About five people. Oversimplified vertex, you could call node for the JVM. That's not a great analogy, but it communicates a lot there. You might think more like node plus plus and much more. So let's go to their website. They do mention in their little blurb, design for modern applications, I'm just gonna highlight some things. It's polyglot, it supports a bunch of languages, but at RubyConf we really care about Ruby by way of JRuby, and I have to call this out because people have asked me during lunch, so do you have to use JRuby with that? Because yes, you do. Simple, not simplistic. It's got a good API, does good stuff. Scalability is, and we'll talk a little bit more about this, thought from the beginning as well as concurrency. Some key features we're talking about are the event plus. So you can see what they wrote here. The nervous system of vertex and connects your system side components. This is part of the connect everything together. I can't read my thing. WebSockets, Sockets.io, server push. This is a big thing, they thought about it. Their module system is basically the vertex equivalent of gems, right? And so you can register these things. And a very interesting thing about the vertex module system is you don't have to install it. You know how we, you know, do bundle, install, install, like deploy. You can actually deploy a vertical, give it a fully qualified path theme. It'll go to the repo and actually, I guess temporarily download it and run for it. So you don't actually have to pre, it's an interesting thing there. So like node handles the concurrency, same reactor pattern that it and a ton of event-based systems use. Good with the non-blocking IO, it's fast. In a number of ways, it's better than node. Node is not good for CPU intensive. We're on the JVM, you know, highly optimized for these things. And of course, of the Ruby's, JRuby's the fastest. You know, it's a JVM. So JVM's, if you need to do threads, it knows how to do threads, right? Blocking IO, slow running things. So node is not good for this. Vertex has the concept of a worker vertical. The vertical is sort of the unit of work in Vertex. And so by default, those verticals are set up for asynchronous, but they have the concept of worker verticals that use thread pools and intend for you to just sit there and do long things and then again communicate via the event bus. Scaling, so they thought about it. Horizontally, you can cluster. They have high availability, vertical. You easily run a vertical per CPU and Java stuff. So that's covered. Polyglot, so they have official idiomatic APIs for these languages. Java, JavaScript, Ruby, CoffeeScript, Ruby. Of course, by the way of JRuby and Python. And of course, at this conference, what we really care about is Ruby. In beta, they have closed your skull. Those make sense. It's like, okay, if you wanna do that. And run PHP on the JVM, okay. So ultimately, any JVM language will work or somebody compiles a JVM. So any of those other things that compile the JavaScript, you could figure out a way to run here. There you go. It is actually a general applications platform. So while the modern web app with the server push and asynchronous is supported, it's got a lot of traditional backend support. Again, by nature of the JVM. And it's also designed to build systems of systems. So I got a bunch of slides that repeat a lot. Availability, clustering, subsystem communication, event bus, shared data. Core APIs that it has, TCP, SSL clients and servers, HTTP, website, it's OxJS, file system APIs, event bus, which is a communication, DNS, UDP. Pretty much, you can pretty much build everything you want and you have the foresight of being able to connect them together. So I'm gonna take a side segue into duct tape. So this picture is called duct tape moving man. You can pretty much duct tape anything together, right? Open source systems typically are duct taped together. I think a lot of us know, oh, I got this and I put it together. We as open source programmers often figure out how to duct tape these together. Perl once upon a time was the duct tape of the internet. Ruby's a better Perl. So I guess to pick up some of that slack. Gems kind of formalize that duct taping sometimes. Node being relatively less mature, I think you do a lot more duct taping there. I know certainly in building apps, you end up rewriting stuff that you've long had gems for. On the contrary, Vertex is designed for integrated systems. Again, so we have the vertical for asynchronous and we have the worker vertical for non-asynchronous. So we kind of cover both cases there. Interprocess communication. The big one here is the event bus. This sort of allows you to, it supports the publish, supports direct messaging. It supports direct reply to a direct message and extends in the browser. So typically you think of the event bus sitting between your server side components. You can actually have the browsers sit in the same bus. That's actually a very useful thing. Sure data, they have that one. They support the hash and the set. You know a lot of times you use Redis or something like that to basically do a similar kind of thing. They've thought about scaling. So clustering, the way you run a vertical with clustering is Vertex, name of the file. And again, a given example is a Ruby file. It could be a Java file, a Scala file, whatever, dash dash cluster. I'll talk a little bit more about this a little later. High availability again, how do you invoke that dash HA? So there's lots more. There could be a whole talk be done on Vertex. There has been. But I'll point you to two good overview videos. So this first one is Tim Fox, introducing Vertex 2.0. Tim Fox is the guy who wrote Vertex. And so this is a really good talk about overview of all the various features it does. He's got tons and tons of live demos where he's just kicking off processes. He shows high availability, he shows clustering. It's a really good, worthwhile look. Vertex, this ain't your dad's node. This one's good at showing how Vertex is better than node in a lot of ways. Oh, you're my best friend. So Vertex is pretty awesome. But with every new tech, there's always more to learn. So, sad panda thing comes, guy, because we always have so much time to learn everything, right? So, question is, what if I could keep coding Ruby and extend it as I needed in Ruby? And the answer to that is, what if I told you you could? He's my dramatic moment guy. Jubilee. There you go. So the origin, actually, I probably shouldn't let you go. You should probably read this one too. Hope you can read the tiny font. We need a web framework for Vertex, you said. But why not use Vertex in your res application? It's the most productive web framework ever created. Thank you. So, this used to be the slogan on the original Read Me page. He's since taken it down, but it's not been as spoke to me. It's like, why reinvent the wheel? We got this great framework, and of course, we need to write web apps. Well, there's one that works well. What if you could put them together? So, Jubilee originally started as a rack server with Vertex built in, but he's since converted to a Vertex module that runs Rack. So, to us, it doesn't mean that much, because it seems like it's essentially the same thing, but ultimately it's for improved performance in the interaction with the rest of the Vertex ecosystem. But the summary is, you get all the power of Vertex, and you can keep doing the rail stuff that you're doing. So, can't do that with Node. So, this brings us to, of course, the title of the talk. So, six reasons Vertex could be your new best friend as a Rubyist. Concurrency, speed, expanded ecosystem, built-in upgrade to scaling path, easy WebSocket support, and I think this is the biggest one. Reuse all this knowledge that you have. All right, so on concurrency, same reactor pattern as Node, so you use it for things like that one. Each vertical itself is single threaded. They have an interesting simple concurrency model. So, there's no threading in some things that, again, I don't wanna talk too much about, just realize that the threading model is very simple for them. And again, you can do your vertical scaling, run a vertical per CPU and other things like that. Speedwise, JVM always gets faster. We always leverage on that one. You can use CPUs and threads as needed. And I'm gonna talk about benchmarks. So, there's lies, damn lies and benchmarks. That being said, here's a vertex versus node benchmark from 2012. We can see this is kind of basically a hello world app. So, you can see Ruby sits here, relatively slow among vertex, but then you compare where node is by comparison. And then here's node with six processes. So, and I believe vertex is running off of single, because that sort of is at the top. So, here's a static file serving, again, Ruby is here, slowest of the vertex, but the best node can do is here. So, for you to believe these benchmarks, it's faster than node. On the nation of Ruby servers in general, Jubilee's the second fastest Ruby server. Have you guys seen this benchmark? The Ruby Web benchmark report came out a few months ago. It's a different one, because instead of doing average stuff, he decided what's the fastest we could possibly do. It's not the benchmark you do, but it gives you like what's the upper limit. In general conclusions, JRuby leads these across the board, and I can wave to Charlie and Tom back there. Thank these guys for that. And the fastest, since it's almost as fast as go, that's kind of like, surprise, the guy who did the benchmarks, surprise pretty much everyone who reads it. So, when we look at these server benchmarks here, so you can see TorqueBox is number one, 10,159 requests per second, TechPorkBox four, that is coming up. And Jubilee's number two at 9,500. And so, for your relative benchmark, go is 10,500. So you can see TorqueBox is almost as fast as go, and Jubilee's definitely in the ballpark, so fast. Expand the ecosystem. Being able to run rack, you get your Ruby gems. Caveat have to be able to run it with JRuby. You get access to the vertex modules. Again, their idea of Ruby gems, right? At the moment of writing 200 there, obviously they're adding it. And then also by way of JRuby, you get access to the rest of the JVM ecosystem, languages, libraries. You can call other JVM languages directly from JRuby if you want, or you can write verticals in those languages, and then it all hooks into vertex. A built-in upgrading scaling path. So, as I keep talking, it was really designed for system of system, verticals. Async verticals, worker verticals for when you need non-async stuff. Intercommunication between all these things. You have core APIs, if you can do the raw stuff, maybe you need direct web sockets. That's not a vertex thing. You can support that one. Of course, the event bus is the big glue. Share data's there when you wanna do stuff like that. They support clustering, high availability. So again, vertex is designed to build systems of systems. This is popular because of server push, Socket, IO, SoxJS is there. But again, I think in most cases, unless you have to talk to someone outside of vertex, you use the event bus. Why? Because it's easy, and I'll show you some code for that, and I realize I should warm up my app. Scott, could you? Okay, if you're on it. So it's super easy, and more importantly, it extends in the browser. So you can imagine, I'll have a diagram of stuff where you have all these server guys talking in the backend, but you can also push that in the browser and back, and that's, again, such a great, simple model. And so the most important thing is the ability to reuse your existing knowledge. I think that's what hurts. Oh, I've written this Rails app. Oh, I need concurrency. Oh, God, I have to learn Node, and I gotta re-make it okay for me to look at JavaScript and stay healthy sort of things, and all these things that just sort of bother you. You know, it's rack. So you can use Ruby, you can use rack programming, which is usually Rails, but it could be Sinatra, Padrino, et cetera. You get your gems. It's very low barrier of entry to be able to leverage this. So jubilee can make you happy. So let's look at how we use it. To install it, gem install jubilee. To use it, go into a JRuby compatible rack app. If you want the jubilee options, and you probably do, just jubilee, and you pass those options. If you don't need the options, you can do typical ways with different servers, Rails as jubilee, rack up dash as jubilee. If you're gonna run it the vertex style way, vertex run config.ru, the one you have, and then various config options that you might have for it in the config JSON. So I think many people love Heroku because it gives you a chance to deploy an app for free. And it's not, no difference here. I wrote a blog post on this one, but the summary is, here's your gem file. So you can see I set Ruby, you pick the version, and what kind of JRuby engine there. The important one, of course, is the jubilee gem there. You don't have to do the platforms JRuby, but sometimes I'll run them under both. So I need that one. That last gem you have to do to run a Rails app on Heroku. You get a proc file, this is where I called jubilee. I set the name of the event bus and typical stuff that you do in your proc file. And if you need to set any JRuby or JVM options, you just do a Heroku environment variable and pass those through. And that's pretty much it. You do a git push Heroku and your app's running. So to get the message across, everyone has slides, of course. Most people do demos. I wanted something with first-hand interaction. You can sit there and I can hand wave all the stuff, but if you can actually work with it, that's tough to beat. So I'm looking basically for an experience. Okay, so now it's sweet spot. Again, it's the chat, the sample app that everyone writes. This is kind of the equivalent of the Pet Store app for J2EE where everyone wrote that app to prove that they know how to use it. Chat app's not exciting. How do I make something a little more interesting? So my thought was I would do a game with chat characteristics. So we're looking at massive multiplayer online something. What could I write? Any ideas? All right, the answer is Rock, Paper, Scissors. Right, you look at me, yeah, yeah, yeah. No, really. Because I got four kids and demanding job. I'm not gonna write World of Warcraft or anything like that. So, and actually that's excuse why my slides are not as good as everyone else's too. So the experience is this one. I want everyone to sign in. Okay, so I did ask, know your Twitter password. I realized when I last gave the preview talk of this one, people don't know it. They put it in once and they never remember it. Know your Twitter password, play with each other, have some fun, and then we'll talk about it. So, I'm running this on one, the free Dino, intentionally, with the idea that actually, since I only have this many people, I think it should support that quite easily, but I haven't tested it past 10 people. So, conference Wi-Fi will probably be the issue and so, if you're gonna hit it from your phone, hit the Wi-Fi, there's a little bit of connection issue there. So, everyone connect your Wi-Fi. I stupidly put sound effects to make it sound cool, which of course, like triple the size of my assets. All right, so the name of the game, Rock, Paper, Scissors, Mayhem. And to make it easy for you to figure out the URL, here it is. So, it's Rock, Paper, Scissors, Mayhem on Bitly. Okay, so this is what you do. Go, hit this page. And I am running one worker there. So, go to this, do your Twitter thing, sign in with Twitter. If you're running your Android phone, press the little play sound button, because HTML5 is weird and not consistent on mobile device and you kind of need to do that to prime the sounds. And again, this is probably what would be the most challenging of the experiment. Pick opponents and play and actually, I'll step you through the thing for that one. And again, there's other parts of it that are very chat-like you should observe. So, if you get something that seems not to be working on a refresh the page, you should rejoin you into the game. So, play it. Now I'm going to try and jump into it and do my display mirroring so I can actually see what I'm doing. All right, where is my thing? Oh, you guys are already playing it. That's cool. I have no idea where any microphone windows are. Lucky, you can hear them. So, you're playing each other and I'm looking for my window. I swear I had, I have the window and I don't want to run too. But so, so I can hear you guys are playing each other and that's good. Kind of want to capture for the stuff. Okay. Be more impressed. Be more impressed with more people out there and then of course you can't hear the sound. So, here's the game. I'm signing in with Twitter. Someone find me and challenge me when I come up. So, you can see I'm getting live feed down here. Anyone who's actually in combat is in combat and this changes over time. Oh, this is great. This is the most people I've had. Here, these guys are currently playing. This changes in real time. Oh, someone's challenged me and I just swept away. So, Jonathan Che has challenged me. Round one. Yes, and now everyone can hear the awesome sound. So, he picks and you have to pick first because you can see what I'm picking. Round two, tie. Oh, tie. Round three. All right, here's the last one. I gotta wait for you and then I will play when I see, so. Anytime. We're missing. So, I don't know where Jonathan is in the audience, but oh, you gotta be picking. You lose. Okay. So, I have however many people this is. Oh, I got challenged again. Round one. Okay. So, we're bouncing around. I was hoping to hear this denim sound, which I'm not hearing, but that was the idea. So, that's the game. You can see people are engaging. They're coming out. I've got this many people. We're running on one dyno, but like I said, looking at the sides of the room, I didn't think that was gonna be a problem. And you can see stuff is going on. I'm kind of obnoxious on the things that are right over here. Like, you turk, you pour so on. So, you crush the bot, blah, blah, blah, blah. So, that's the app. And as long as I hear cool announcer guy, I know you guys are playing. All right, so that is the, actually let me jump out of mirror mode, and we'll pick up. Okay, so we played it, right? So, let's do a breakdown of the app now that we've played it. So, we start off with the very polyglot concept of right tool for the jobs. So, I'm using Rails. What do I use it for? Login. I'm using Omni-Auth and Devise that supports all that login stuff. I got views, I'm partial to Hamel myself, so I like that one. Easy database access, right? Active record migrations, who doesn't love that, right? Jubilee Vertex, what am I using that for? EventBus, this is the WebSocket supports, the concurrency, it's a sub-system communication, and I'll have a diagram of that one. Shared data, so I'm using this to make, you know, I don't want to hit database for everyone because every time I persistently save the rounds in between Vertex, I have a timer. So, if you challenge someone and someone doesn't answer, it's got like a 10-second timeout and it'll kick you out so you don't get locked in there. Any of you guys who played the robot there, the bot there is a vertical, a separate vertical, and I didn't do this yet, but I was gonna build a leaderboard, I was trying to figure out what can I do that takes time to use a worker vertical, but I could deploy a worker vertical and asynchronously use that one. So, the summary is I use Rails to get to the game, and then I use Jubilee to play the game. All right, the divvy up of work. So, let's look at screen by screen. So, you hit the main page, I got this cool picture Kendra drew for me. You know, that's Vanilla Rails. You go to the sign in, it's Twitter authentication, OmniOS makes it so easy. I would hate to have to write it myself. Then we hit the game, and so what makes a chat lag? Well, here's you, here's this live stream, it's typically a chat stream. Here's presence, except that I change the state of presence and this is where you challenge people. When you challenge someone, you can give up and it will tell their side, you give up. If you don't get an answer in time, it times out. And, God, I missed the thing. I use a, sorry, Jubilee, the vertex timer, I use a Jubilee vertex timer to say, hey, have you been accepted in threshold and if not, I cancel on both sides. So, if I put up two pages, you can see on the left, I've challenged the person I give up on the right, I get hit accept. Again, the players in the server are all connected by the event plus. So, it's backend and front end. In this case, I let it time out and then the server tells both build time out. I canceled the thing and you can see one side said, he didn't respond, the other side said, you know, you missed something. Again, all event bus connected. The game itself, you know, this various play. Again, we're connected to the server and each other by the event bus. I'm using shared data to make the speed fast. The bot is its own vertical. It plays on the event bus like everyone else. All right, so here's my architecture. So, I ran all this in one dyno. I got my Rails app. Talking over the event bus, you know, you might set up something like RabbitMQ or Rescue or something like this, depending, you know, again, duct taping stuff together. The server, the server I wrote and we'll show you, look at the code. I wrote this event bus handler. Arguably, again, for concurrency, you'd run that in another thing, a non-rails process. You know, shared data, you might use Redis or Tokyo cabinet or something like that to do the same kind of thing, more duct taping. You know, and then WebSockets. Maybe you outsource it to Pusher or, you know, any number of libraries to do that one. That's how I talk to the client. Again, that's all event bus for me. Yeah, the bot's another vertical. Again, another thing, asynchronous, another process. And then, of course, I'm using timers to enforce the timeout thing so that I don't have to do it. You might use delayed job or something like that. Again, another gem and, you know, migration and et cetera. So ultimately, system using jubilee slash vertex, it's designed to work together, right? As opposed to being duct taped together and we don't want any more duct tape. So stats, the client code for this is about, you know, 497 lines of code. It's done in Opal. I'm using Ruby on the browser because I like to be happy. This includes white space and comments. The breakdown is the actual game itself is 444 lines and then I wrap the event bus code in something that looks like the JRuby thing so that I could, of course, be happy and consistent. So that's this one, that's those lines. The server code, the initializer that sets up all the connection stuff is 50 lines of code. Naturally, I have all the server game on the back end but that's not anything vertex specific but obviously I'm playing the game and whatnot. So other code. So the real stuff, same stuff you always do so you don't want to see that. And the client game code, it's not super advanced so you don't need to see a lot of that one but I'll probably show some. But the code you really want to see is a jubilee code, right? So I set up the event bus, this is the heart of the app. I deploy another vertical and you can see what's involved in that. I'm using shared data, again for speed and I have a timer. So here's the setup on the rail side. So this is an initializer, you can see begin, I require vertex, I have a little convenience function, you don't need to know so much about it. Down here is your register handlers on the event bus. So I have a channel called logout and this is string and you can do, typically they'll do like name domain qualified things to make you name things here, right? So I get the ID from the message, I kind of print something out. I have shared data. So I'm storing all the user IDs in this set because I don't want duplication there. And so once I get this, I publish this out and this is how other people know people logged in. You get this little publish, oh Fred Thompson logged in, right? Register handle for logins. So when you log into the game, I'm sorry, jump ahead. Get the user ID, you get shared data, we saw that one because I'm gonna stick me into the thing there. I'm sorry about the highlighting here. Ultimately at some point I reply back to user. So here's a direct reply that you can do in the same place here. I have less highlights than I think I do. Okay, so last time. So I find the user and I publish this and again the clients get this one. So next here, so the bulk of the game is done here. So we have a handler here. I have come up with what I call the command hash pattern. This is how I multiplex stuff over single channels instead of having individual channels. So you can see I have a little command hash and just a case statement here to do. These are the various actions that you do in the game. So again, I just kind of send the things to the various stuff in the thingy. Down here, this line, this is how I deploy a bot. Deploy vertical, really hard, right? I've got to learn a lot of things to be able to run this one. I deploy the bot there and he's running. We'll look at the bot a couple slides down. On the client side, and again I'm using Opal so it's just Ruby, I set up Event Bus. So on the client side we have an on open because you can't use the Event Bus before it's been opened. And so to keep you out of trying to write stuff that's not open you have to do on open events. So when I first open I will log in and this is how everyone knows I'm there. I will register the handler, what to do when a user comes because I want to be able to handle. I basically just parse the data comes to me and I draw him on the screen. The game is done through this handler. So the UID, I decided to pick the unique ID as the channel for each person because it's supposed to be unique. And again, the same command hash pattern and this is how we respond to all the various things that are involved in the game. We do have activity things. Activity window, a lot of people can go to that one. That's a published sort of thing. Player state, that whole in combat, not in combat is that one. And when the user logs out I want to kind of pull them off of the state so you don't challenge him. So this is the bulk of the bot code. I left out the actual part where he plays but it's like I register the bot ID. I have the command hash pattern. You can see that he has no GUI. So half the things are GUI commands. So this is a no-wap thing down the third win there. And so that's pretty much. So he just plays like everyone else except I don't care to draw any GUI stuff there. And then when you log out, some cleanup stuff. So I have the timer code. Like if there's that unanswered challenge, I cancel it and it all ends there. So when I make the challenge, I set a timer at 10,000 milliseconds. It should be 10 seconds to run this method. Down here I will stuff that ID so that I can cancel it later. And then when the timer fires off, I grab the timer's thing, I pull the ID and then if it's there, I cancel it. And then this course, I think cancel timer delete challenge. Somewhere I have the code that goes and tells everyone at the event bus, hey, this challenge is over. So that's pretty much the heart of how that works with Jubilee. There are some considerations when you're doing Jubilee and Rails. The way you have to set up events stuff is in the Rails initializer. You can't do it in controllers because those get instantiated for each request. You need to run it for the entire app. That's what it said there. Because you run initializers all the time and Vertex only runs in the server, you kind of have to wrap it so that your rake test don't suddenly break. Oops, is that all I said? Is that all I put there? I thought I had more. Okay, so there are some drawbacks. First thing, it's, I don't know why this is the case, but JRuby's still kind of second class. There's gems that don't work or gems that are supposed to work that don't or this config is at least three Google searches away before you can figure out what it is. So you had that sometimes. Debug and asynchronous multi-agent systems is still always hard no matter how little code you have to write. If you need really fine control of stuff, so I've showed you the Jubilee Rails friendly way, that's super easy. If you need more detail, you have to switch to the Vertex a little more complicated way, but again, I was able to do this app in the easy way. And this happens, I think, in promise, a lot of things. Your error messages get swallowed inside of some of these event bus things there. I had some problem debugging some things, I didn't know where the error message went. This works for me sometimes. I auto reload and sometimes I had to restart the server and I haven't figured out the pattern yet. It's always nicer when it does the whole Rails thing and auto reloads for you. So it works if you put it in the right place. So one more thing. So of course, by now you know I'm using Opal and so I basically have an all Ruby stack. And so that big thing the node guys say about, this is awesome, it really is awesome. I just have so much more fun. That's another talk that I will propose about how I write better code when I write Ruby in their browser for all kinds of reasons. I'm so much happier in a write better code and if we have time, I'll show you all the code. It's like this big and it looks good. Whereas JavaScript looks like this. So Opal could be its own talk. I already did one, so I would recommend you go look at this one. I have a bit of a Vimeo link. So I spent a gazillion hours putting Star Wars music in sounds and pictures and videos and YouTube said, oh my God copyrighted music and it muted the entire Confreaks thing. And so Confreaks went and just blotted out the sound which I thought was the best part of it. So this is the intro music and I put a link to YouTube to pick up the rest of the talk. So watch that if you don't know about Jubilee and wanna learn about Jubilee. Oh you're my best friend. So true, so true. All right, thanks. Thanks to Matt for writing Ruby. Thanks to DHH for giving us jobs. Thanks to Charlie and Tom there for their ever non-ceasing work on Jay Ruby. Tim Fox and his team wrote Vertex. Isaiah Pung wrote Jubilee. Adam, Aleen, Matt, they're the Opal core people there and thanks for listening. So my final advice to Ruby's is you can stay happy. You can still do most of your stuff in Ruby by Jubilee. You can stay happy and you can scale. You can see now there's a lot of capability here and you can stay in Ruby if that's what you wanna do. Don't worry, be happy. This is a time where, you know, a lot of people feel we have no choice. They've gotta adopt, know, or die. I'm saying that's not true. You can choose to be happy and that's what I choose. So, I love that one. All right.