[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:18.16,0:00:24.64,Default,,0000,0000,0000,,RICHARD SCHNEEMAN: All right. OK. Hello everyone. Dialogue: 0,0:00:24.74,0:00:25.93,Default,,0000,0000,0000,,AUDIENCE: Hello. Dialogue: 0,0:00:25.93,0:00:29.18,Default,,0000,0000,0000,,R.S.: Thank you. Thank you. Welcome to, welcome,\Nlet Dialogue: 0,0:00:29.18,0:00:31.22,Default,,0000,0000,0000,,me be the first to welcome you to RailsConf. Dialogue: 0,0:00:31.22,0:00:35.81,Default,,0000,0000,0000,,So, our, our talk today is Heroku 2014: A Dialogue: 0,0:00:35.81,0:00:38.39,Default,,0000,0000,0000,,Year in Review. It is gonna be a play Dialogue: 0,0:00:38.39,0:00:43.61,Default,,0000,0000,0000,,in six acts, featuring Terrance Lee and Richard\NSchneeman. Dialogue: 0,0:00:43.61,0:00:45.93,Default,,0000,0000,0000,,So, of course this is a year in review, Dialogue: 0,0:00:45.93,0:00:49.06,Default,,0000,0000,0000,,and Heroku does measure their years by RailsConf.\NSo Dialogue: 0,0:00:49.06,0:00:53.81,Default,,0000,0000,0000,,this is from Portland to Chicago RailsConf\Nyear. The Dialogue: 0,0:00:53.81,0:00:55.34,Default,,0000,0000,0000,,Standard RailsConf Year. Dialogue: 0,0:00:55.34,0:00:57.77,Default,,0000,0000,0000,,As, as some of you might know, we are Dialogue: 0,0:00:57.77,0:01:01.06,Default,,0000,0000,0000,,on the Ruby Task Force, and, in fact, that Dialogue: 0,0:01:01.06,0:01:06.06,Default,,0000,0000,0000,,makes us Ruby Task Force members. And, of\Ncourse, Dialogue: 0,0:01:06.06,0:01:07.99,Default,,0000,0000,0000,,this was a big year. We're gonna be talking Dialogue: 0,0:01:07.99,0:01:12.31,Default,,0000,0000,0000,,a little bit about app performance, some Heroku\Nfeatures, Dialogue: 0,0:01:12.31,0:01:15.59,Default,,0000,0000,0000,,and community features. So, first up to the\Nstage, Dialogue: 0,0:01:15.59,0:01:19.02,Default,,0000,0000,0000,,I'm gonna be introducing the one, the only\NMister Dialogue: 0,0:01:19.02,0:01:23.03,Default,,0000,0000,0000,,Terrance Lee. You might have recognized him\Nin some Dialogue: 0,0:01:23.03,0:01:27.89,Default,,0000,0000,0000,,other roles. He hails from Austin, Texas,\Nwhich has, Dialogue: 0,0:01:27.89,0:01:31.80,Default,,0000,0000,0000,,undoubtedly, the best tacos in the entire\Nworld. So, Dialogue: 0,0:01:31.80,0:01:32.49,Default,,0000,0000,0000,,he- Dialogue: 0,0:01:32.49,0:01:33.86,Default,,0000,0000,0000,,AUDIENCE: [indecipherable] Dialogue: 0,0:01:33.86,0:01:38.64,Default,,0000,0000,0000,,R.S.: Them's fightin' words, friend. So that\Nhe, he's Dialogue: 0,0:01:38.64,0:01:42.36,Default,,0000,0000,0000,,also sometimes known as the Chief Taco Officer.\NOr, Dialogue: 0,0:01:42.36,0:01:45.50,Default,,0000,0000,0000,,or the CTO. And something, something very\Ninteresting about Dialogue: 0,0:01:45.50,0:01:48.94,Default,,0000,0000,0000,,Terrance is, recently, he was inducted into\NRuby Core, Dialogue: 0,0:01:48.94,0:01:52.34,Default,,0000,0000,0000,,so congratulations to, to Terrance. All right. Dialogue: 0,0:01:52.34,0:01:56.09,Default,,0000,0000,0000,,So, without further ado, Act 1: Deploy Speed. Dialogue: 0,0:01:56.09,0:02:02.48,Default,,0000,0000,0000,,TERRANCE LEE: Thank you, Richard. So, at the\Nbeginning Dialogue: 0,0:02:02.48,0:02:05.72,Default,,0000,0000,0000,,of the year Rails Standard Year, we focused\Na Dialogue: 0,0:02:05.72,0:02:08.06,Default,,0000,0000,0000,,lot on deployment speed. We got a lot of Dialogue: 0,0:02:08.06,0:02:12.06,Default,,0000,0000,0000,,feedback and realized deployment was not as\Nfast as Dialogue: 0,0:02:12.06,0:02:14.63,Default,,0000,0000,0000,,it could be. And we wanted to make it Dialogue: 0,0:02:14.63,0:02:16.25,Default,,0000,0000,0000,,faster. So, the first thing we set out to Dialogue: 0,0:02:16.25,0:02:18.25,Default,,0000,0000,0000,,do was to actually do a bunch of measurement Dialogue: 0,0:02:18.25,0:02:22.02,Default,,0000,0000,0000,,and profiling to look at where things were\Nslow, Dialogue: 0,0:02:22.02,0:02:24.16,Default,,0000,0000,0000,,and how we could make it better, and to Dialogue: 0,0:02:24.16,0:02:27.59,Default,,0000,0000,0000,,kind of gage, like, the before and after and Dialogue: 0,0:02:27.59,0:02:30.92,Default,,0000,0000,0000,,know when the good points were to kind of Dialogue: 0,0:02:30.92,0:02:34.73,Default,,0000,0000,0000,,stop and move on to other things. Cause you Dialogue: 0,0:02:34.73,0:02:37.14,Default,,0000,0000,0000,,can never make, you can never, you will never Dialogue: 0,0:02:37.14,0:02:40.23,Default,,0000,0000,0000,,be done with, like, performance improvements. Dialogue: 0,0:02:40.23,0:02:44.37,Default,,0000,0000,0000,,So, after about six months of work on this, Dialogue: 0,0:02:44.37,0:02:46.93,Default,,0000,0000,0000,,we managed to cut down the deploy speeds for, Dialogue: 0,0:02:46.93,0:02:50.78,Default,,0000,0000,0000,,across the platform for Ruby by about forty\Npercent. Dialogue: 0,0:02:50.78,0:02:54.22,Default,,0000,0000,0000,,So it's a pretty decent speed improvement.\NAnd, in Dialogue: 0,0:02:54.22,0:02:56.13,Default,,0000,0000,0000,,order to do this, we mainly looked at three Dialogue: 0,0:02:56.13,0:02:59.36,Default,,0000,0000,0000,,various ways to speed this up. Dialogue: 0,0:02:59.36,0:03:02.64,Default,,0000,0000,0000,,The first thing was running code in parallel,\Nso Dialogue: 0,0:03:02.64,0:03:07.36,Default,,0000,0000,0000,,running more things, running things, like,\Nmore than one Dialogue: 0,0:03:07.36,0:03:10.29,Default,,0000,0000,0000,,thing at one time. If you cache stuff you Dialogue: 0,0:03:10.29,0:03:12.43,Default,,0000,0000,0000,,don't have to do it again, and, in general, Dialogue: 0,0:03:12.43,0:03:14.58,Default,,0000,0000,0000,,just like, cutting out code that doesn't need\Nto Dialogue: 0,0:03:14.58,0:03:16.01,Default,,0000,0000,0000,,be there. Dialogue: 0,0:03:16.01,0:03:19.36,Default,,0000,0000,0000,,So, with the parallel code, we worked with\Nthe Dialogue: 0,0:03:19.36,0:03:23.93,Default,,0000,0000,0000,,bundler team on Bundler 1.5. There was a pull Dialogue: 0,0:03:23.93,0:03:27.01,Default,,0000,0000,0000,,request sent by CookPad that was sent in to Dialogue: 0,0:03:27.01,0:03:30.78,Default,,0000,0000,0000,,add parallel bundler install for Bundler 1.5.\NSo if Dialogue: 0,0:03:30.78,0:03:33.06,Default,,0000,0000,0000,,you actually aren't using this yet, I would\Nrecommend Dialogue: 0,0:03:33.06,0:03:37.45,Default,,0000,0000,0000,,upgrading your bundle to at least Bundler\N1.5. And Dialogue: 0,0:03:37.45,0:03:41.14,Default,,0000,0000,0000,,the bundler added this dash j option, which\Nallows Dialogue: 0,0:03:41.14,0:03:44.52,Default,,0000,0000,0000,,you to specify the number of jobs to run. Dialogue: 0,0:03:44.52,0:03:47.42,Default,,0000,0000,0000,,And this is, basically, if you're using MRI,\Nit Dialogue: 0,0:03:47.42,0:03:50.78,Default,,0000,0000,0000,,forks and does a num, these number of sub-processes, Dialogue: 0,0:03:50.78,0:03:53.87,Default,,0000,0000,0000,,and if you're on JRuby or Rubinius it actually Dialogue: 0,0:03:53.87,0:03:55.97,Default,,0000,0000,0000,,just uses threads here. Dialogue: 0,0:03:55.97,0:03:58.44,Default,,0000,0000,0000,,And the benefit of doing this is, when you Dialogue: 0,0:03:58.44,0:04:01.25,Default,,0000,0000,0000,,actually do bundle install, the dependencies\Nthat get installed Dialogue: 0,0:04:01.25,0:04:03.83,Default,,0000,0000,0000,,get downloaded in parallel, so you're not\Nwaiting on Dialogue: 0,0:04:03.83,0:04:07.15,Default,,0000,0000,0000,,network traffic sequentially anymore, and\Nin addition you're also Dialogue: 0,0:04:07.15,0:04:10.71,Default,,0000,0000,0000,,install gems in parallel. And this is mostly\Nbeneficial, Dialogue: 0,0:04:10.71,0:04:14.50,Default,,0000,0000,0000,,especially when you're running native extensions.\NSo if you Dialogue: 0,0:04:14.50,0:04:16.50,Default,,0000,0000,0000,,have something like Nokogiri, that takes a\Nlong time. Dialogue: 0,0:04:16.50,0:04:19.76,Default,,0000,0000,0000,,Oftentimes, you notice, you just like hang\Nand wait Dialogue: 0,0:04:19.76,0:04:21.23,Default,,0000,0000,0000,,for it to install and then it installs the Dialogue: 0,0:04:21.23,0:04:24.13,Default,,0000,0000,0000,,next thing, so this allows you to install\Nthat, Dialogue: 0,0:04:24.13,0:04:26.26,Default,,0000,0000,0000,,basically, in the background and then go and\Ninstall Dialogue: 0,0:04:26.26,0:04:28.92,Default,,0000,0000,0000,,other gems at the same time. Dialogue: 0,0:04:28.92,0:04:34.61,Default,,0000,0000,0000,,Also, in Bundler 1.5, Richard actually added\Nthis function Dialogue: 0,0:04:34.61,0:04:39.59,Default,,0000,0000,0000,,that allows people, allows bundler to auto-retry\Nfailed commands, Dialogue: 0,0:04:39.59,0:04:43.66,Default,,0000,0000,0000,,so initially, before this, we would, when\Nwe run Dialogue: 0,0:04:43.66,0:04:46.99,Default,,0000,0000,0000,,bundle install and something would fail because\Nof some Dialogue: 0,0:04:46.99,0:04:49.75,Default,,0000,0000,0000,,odd network timeout, like during one chance,\Nyou would Dialogue: 0,0:04:49.75,0:04:51.94,Default,,0000,0000,0000,,have to basically repush again, no matter\Nwhere you Dialogue: 0,0:04:51.94,0:04:55.62,Default,,0000,0000,0000,,were in the build process. So, by default\Nnow, Dialogue: 0,0:04:55.62,0:05:00.49,Default,,0000,0000,0000,,Bundler actually will retry clones and gem\Ninstalls for Dialogue: 0,0:05:00.49,0:05:02.09,Default,,0000,0000,0000,,up to three times by default. Dialogue: 0,0:05:02.09,0:05:06.89,Default,,0000,0000,0000,,So, it will continue going during the deploy\Nprocess. Dialogue: 0,0:05:06.89,0:05:10.35,Default,,0000,0000,0000,,And so is anyone here actually familiar with\Nthe Dialogue: 0,0:05:10.35,0:05:17.35,Default,,0000,0000,0000,,PIGz command? So, just Richard? So, PIGz is\NParallel Dialogue: 0,0:05:19.09,0:05:23.75,Default,,0000,0000,0000,,Gzip, and the build and packaging team at\NHeroku Dialogue: 0,0:05:23.75,0:05:27.03,Default,,0000,0000,0000,,worked on this feature, or worked on implementing\Nthis Dialogue: 0,0:05:27.03,0:05:31.03,Default,,0000,0000,0000,,at Heroku using the PIGz command, and in order Dialogue: 0,0:05:31.03,0:05:32.97,Default,,0000,0000,0000,,to understand the kind of benefit of using\Nsomething Dialogue: 0,0:05:32.97,0:05:35.71,Default,,0000,0000,0000,,like this, when you push an app up on Dialogue: 0,0:05:35.71,0:05:39.02,Default,,0000,0000,0000,,Heroku during the compile process, it actually\Nbuilds these Dialogue: 0,0:05:39.02,0:05:44.03,Default,,0000,0000,0000,,things at Heroku that are called slugs. And\Nbasically Dialogue: 0,0:05:44.03,0:05:47.66,Default,,0000,0000,0000,,it's just, like, a tar of your app directory Dialogue: 0,0:05:47.66,0:05:50.42,Default,,0000,0000,0000,,of everything after the compile face is run. Dialogue: 0,0:05:50.42,0:05:54.60,Default,,0000,0000,0000,,And, originally, we were just using SquashFS,\Ninitially, and Dialogue: 0,0:05:54.60,0:05:57.43,Default,,0000,0000,0000,,then we moved to kind of just tar files, Dialogue: 0,0:05:57.43,0:06:00.40,Default,,0000,0000,0000,,and we noticed that one of the slowest point Dialogue: 0,0:06:00.40,0:06:03.17,Default,,0000,0000,0000,,in the actual build process was actually just\Ngoing Dialogue: 0,0:06:03.17,0:06:06.42,Default,,0000,0000,0000,,through and compressing everything in that,\Nthat file directory, Dialogue: 0,0:06:06.42,0:06:09.08,Default,,0000,0000,0000,,and then pushing it up onto S3 after that Dialogue: 0,0:06:09.08,0:06:12.14,Default,,0000,0000,0000,,was done. And so one of the things that Dialogue: 0,0:06:12.14,0:06:14.14,Default,,0000,0000,0000,,we looked into was, is there a way we Dialogue: 0,0:06:14.14,0:06:16.81,Default,,0000,0000,0000,,can make that faster? So, if you ever push Dialogue: 0,0:06:16.81,0:06:19.36,Default,,0000,0000,0000,,a Heroku app and then you basically, like,\Nwait Dialogue: 0,0:06:19.36,0:06:21.45,Default,,0000,0000,0000,,when it says, like, compressing and then it\Ngoes Dialogue: 0,0:06:21.45,0:06:23.96,Default,,0000,0000,0000,,to done, like that's the compressing of the\Nactual Dialogue: 0,0:06:23.96,0:06:25.22,Default,,0000,0000,0000,,slug. Dialogue: 0,0:06:25.22,0:06:29.20,Default,,0000,0000,0000,,And we managed to use slug, PIGz to now Dialogue: 0,0:06:29.20,0:06:31.46,Default,,0000,0000,0000,,improve that by sniffing them out. I don't\Nremember Dialogue: 0,0:06:31.46,0:06:35.86,Default,,0000,0000,0000,,the actual performance improvement, but it\Nwas pretty significant, Dialogue: 0,0:06:35.86,0:06:39.40,Default,,0000,0000,0000,,and the only downside was in certain slugs,\Nthe Dialogue: 0,0:06:39.40,0:06:42.20,Default,,0000,0000,0000,,slug sizes are a little bit bigger. But the Dialogue: 0,0:06:42.20,0:06:46.41,Default,,0000,0000,0000,,performance trade off was worth it at that\Ntime. Dialogue: 0,0:06:46.41,0:06:48.33,Default,,0000,0000,0000,,The next thing we started doing was looking\Ninto Dialogue: 0,0:06:48.33,0:06:54.15,Default,,0000,0000,0000,,caching. So anyone here using Rails 4? So\Npretty Dialogue: 0,0:06:54.15,0:06:56.53,Default,,0000,0000,0000,,good amount of the room. So the one thing Dialogue: 0,0:06:56.53,0:07:00.72,Default,,0000,0000,0000,,is that we did which differ from Rails 3, Dialogue: 0,0:07:00.72,0:07:02.26,Default,,0000,0000,0000,,thanks to a bunch of the work that's happened Dialogue: 0,0:07:02.26,0:07:04.42,Default,,0000,0000,0000,,on the Rails Core team with us is that, Dialogue: 0,0:07:04.42,0:07:07.48,Default,,0000,0000,0000,,we can now cache assets between deploys. This\Nwasn't Dialogue: 0,0:07:07.48,0:07:10.78,Default,,0000,0000,0000,,possible in Rails 3 because the cache was,\Nyou Dialogue: 0,0:07:10.78,0:07:13.29,Default,,0000,0000,0000,,couldn't actually reuse the cache. There was\Ntimes when Dialogue: 0,0:07:13.29,0:07:15.89,Default,,0000,0000,0000,,the cache would basically be corrupted and\Nthen you Dialogue: 0,0:07:15.89,0:07:18.66,Default,,0000,0000,0000,,would get, like, assets that wouldn't work\Nbetween deploys. Dialogue: 0,0:07:18.66,0:07:20.30,Default,,0000,0000,0000,,So the fix there was you actually have to Dialogue: 0,0:07:20.30,0:07:24.33,Default,,0000,0000,0000,,remove the assets between each deploy in some\NRails Dialogue: 0,0:07:24.33,0:07:27.10,Default,,0000,0000,0000,,3 builds. But it wasn't consistent, so sometimes\Nit Dialogue: 0,0:07:27.10,0:07:29.52,Default,,0000,0000,0000,,would work and sometimes it didn't. And on\NHeroku Dialogue: 0,0:07:29.52,0:07:31.38,Default,,0000,0000,0000,,that's not something we can rely on in an Dialogue: 0,0:07:31.38,0:07:32.37,Default,,0000,0000,0000,,automated fashion. Dialogue: 0,0:07:32.37,0:07:34.57,Default,,0000,0000,0000,,But luckily a lot of that stuff has been Dialogue: 0,0:07:34.57,0:07:37.40,Default,,0000,0000,0000,,fixed for Rails 4, so now we cache assets Dialogue: 0,0:07:37.40,0:07:39.57,Default,,0000,0000,0000,,between deploys in Rails 4. And so if we Dialogue: 0,0:07:39.57,0:07:43.64,Default,,0000,0000,0000,,look at Rails 3, I guess this got cut Dialogue: 0,0:07:43.64,0:07:46.38,Default,,0000,0000,0000,,off, but this is supposed to say about, like, Dialogue: 0,0:07:46.38,0:07:50.15,Default,,0000,0000,0000,,thirty-two seconds for a Rails 3 deploy, and\Nthen Dialogue: 0,0:07:50.15,0:07:54.45,Default,,0000,0000,0000,,on Rails 4 it got, for the average we, Dialogue: 0,0:07:54.45,0:07:56.68,Default,,0000,0000,0000,,we measured the steps in the, in the build Dialogue: 0,0:07:56.68,0:07:59.95,Default,,0000,0000,0000,,process, and on Rails 4, the perk fifty was Dialogue: 0,0:07:59.95,0:08:03.45,Default,,0000,0000,0000,,about fourteen point something seconds. So\Na pretty significant Dialogue: 0,0:08:03.45,0:08:07.18,Default,,0000,0000,0000,,speed improvement there, both due to caching\Nand other Dialogue: 0,0:08:07.18,0:08:11.15,Default,,0000,0000,0000,,improvements inside of Rails 4 for the asset\Npipeline. Dialogue: 0,0:08:11.15,0:08:12.55,Default,,0000,0000,0000,,So the other thing we also looked at was Dialogue: 0,0:08:12.55,0:08:17.20,Default,,0000,0000,0000,,just, if there's code that is doing extra\Nwork, Dialogue: 0,0:08:17.20,0:08:19.05,Default,,0000,0000,0000,,if we remove that, it will speed up the Dialogue: 0,0:08:19.05,0:08:23.79,Default,,0000,0000,0000,,build process for everyone who's deploying\Nevery day. So Dialogue: 0,0:08:23.79,0:08:25.18,Default,,0000,0000,0000,,one of the first things that we did was Dialogue: 0,0:08:25.18,0:08:30.50,Default,,0000,0000,0000,,actually stop downloading bundler more than\Nonce. So, initially, Dialogue: 0,0:08:30.50,0:08:33.41,Default,,0000,0000,0000,,when you, when we do the Ruby version detection, Dialogue: 0,0:08:33.41,0:08:36.66,Default,,0000,0000,0000,,we actually have to download bundler, and\Nthen basically Dialogue: 0,0:08:36.66,0:08:39.17,Default,,0000,0000,0000,,run that to get the version of Ruby to Dialogue: 0,0:08:39.17,0:08:42.21,Default,,0000,0000,0000,,install on the application. And then again,\Nwe would Dialogue: 0,0:08:42.21,0:08:45.00,Default,,0000,0000,0000,,then download and install it again because\Nit was Dialogue: 0,0:08:45.00,0:08:49.78,Default,,0000,0000,0000,,run in a separate process for the actual,\Nlike, Dialogue: 0,0:08:49.78,0:08:52.28,Default,,0000,0000,0000,,installing of your dependencies. And one of\Nthe things Dialogue: 0,0:08:52.28,0:08:55.10,Default,,0000,0000,0000,,we did was to actually just stop doing that Dialogue: 0,0:08:55.10,0:08:57.65,Default,,0000,0000,0000,,and we would cache the Bundler gem so we Dialogue: 0,0:08:57.65,0:09:00.32,Default,,0000,0000,0000,,don't have to download that two or three times Dialogue: 0,0:09:00.32,0:09:03.30,Default,,0000,0000,0000,,during the build process. So, so cutting network\NIO Dialogue: 0,0:09:03.30,0:09:06.06,Default,,0000,0000,0000,,and other things. Dialogue: 0,0:09:06.06,0:09:09.14,Default,,0000,0000,0000,,We also started removing, there was like duplicate\Nchecks Dialogue: 0,0:09:09.14,0:09:11.25,Default,,0000,0000,0000,,between detection of what kind of app you\Nwere Dialogue: 0,0:09:11.25,0:09:14.61,Default,,0000,0000,0000,,using so, and, bin detects. We would use it Dialogue: 0,0:09:14.61,0:09:17.06,Default,,0000,0000,0000,,to figure out what kind of app you have, Dialogue: 0,0:09:17.06,0:09:18.48,Default,,0000,0000,0000,,like if it was a Ruby app, a Rack Dialogue: 0,0:09:18.48,0:09:21.07,Default,,0000,0000,0000,,app, a Rails 3 app, a Rails 4 app, Dialogue: 0,0:09:21.07,0:09:24.13,Default,,0000,0000,0000,,stuff like that. And then, again, since it\Nwas Dialogue: 0,0:09:24.13,0:09:26.19,Default,,0000,0000,0000,,a separate process in bin compile, we would\Nhave Dialogue: 0,0:09:26.19,0:09:29.74,Default,,0000,0000,0000,,to do it again. So, Richard actually did a Dialogue: 0,0:09:29.74,0:09:32.83,Default,,0000,0000,0000,,bunch of work to refactor both detect and\Nrelease, Dialogue: 0,0:09:32.83,0:09:35.59,Default,,0000,0000,0000,,and so now detect is super simple. It literally Dialogue: 0,0:09:35.59,0:09:39.03,Default,,0000,0000,0000,,just checks if you have the gemfile file there, Dialogue: 0,0:09:39.03,0:09:40.66,Default,,0000,0000,0000,,and then all the other work is now deferred Dialogue: 0,0:09:40.66,0:09:43.28,Default,,0000,0000,0000,,to bin compile. So that means we're only doing Dialogue: 0,0:09:43.28,0:09:45.59,Default,,0000,0000,0000,,a bunch of these checks once, like examine\Nyour Dialogue: 0,0:09:45.59,0:09:49.57,Default,,0000,0000,0000,,jump file, checking what gems you have. So\Nnot Dialogue: 0,0:09:49.57,0:09:52.79,Default,,0000,0000,0000,,doing that two or more times. Dialogue: 0,0:09:52.79,0:09:57.23,Default,,0000,0000,0000,,And, if you haven't watched this talk, he\Ngave Dialogue: 0,0:09:57.23,0:09:58.93,Default,,0000,0000,0000,,this talk at Ancient City Ruby. I don't actually Dialogue: 0,0:09:58.93,0:10:03.17,Default,,0000,0000,0000,,know if the videos are quite up yet. But Dialogue: 0,0:10:03.17,0:10:05.11,Default,,0000,0000,0000,,Richard does a talk about testing the untestable,\Nso Dialogue: 0,0:10:05.11,0:10:07.23,Default,,0000,0000,0000,,if you're interested in learning how we test\Nthe Dialogue: 0,0:10:07.23,0:10:11.13,Default,,0000,0000,0000,,build pack, you should go watch this talk. Dialogue: 0,0:10:11.13,0:10:15.15,Default,,0000,0000,0000,,So I'd like to introduce Richard, cause he's\Ngonna Dialogue: 0,0:10:15.15,0:10:18.79,Default,,0000,0000,0000,,present on the next section. So Richard loves\NRuby Dialogue: 0,0:10:18.79,0:10:21.83,Default,,0000,0000,0000,,so much that he got married to her. I Dialogue: 0,0:10:21.83,0:10:23.17,Default,,0000,0000,0000,,think he got married last, last year. Dialogue: 0,0:10:23.17,0:10:24.23,Default,,0000,0000,0000,,R.S.: Right before our last RailsConf. Dialogue: 0,0:10:24.23,0:10:28.30,Default,,0000,0000,0000,,T.L.: Yeah. Right before our last RailsConf.\NI remember Dialogue: 0,0:10:28.30,0:10:31.60,Default,,0000,0000,0000,,that. He's also on the Rails Issue Team, and Dialogue: 0,0:10:31.60,0:10:35.22,Default,,0000,0000,0000,,he's one of the top one hundred Rails contributors, Dialogue: 0,0:10:35.22,0:10:40.15,Default,,0000,0000,0000,,according to the Rails contributor sites.\NAnd you might Dialogue: 0,0:10:40.15,0:10:43.98,Default,,0000,0000,0000,,also know him for his, this gem called sextant Dialogue: 0,0:10:43.98,0:10:48.76,Default,,0000,0000,0000,,that he released for Rails 3. Basically, I\Nremember Dialogue: 0,0:10:48.76,0:10:50.94,Default,,0000,0000,0000,,back in the day, developing Rails apps, when\NI Dialogue: 0,0:10:50.94,0:10:52.85,Default,,0000,0000,0000,,wanted to basically verify routes, I would\Nrun the Dialogue: 0,0:10:52.85,0:10:55.13,Default,,0000,0000,0000,,rake routes command, and it would, you know,\Nboot Dialogue: 0,0:10:55.13,0:10:56.43,Default,,0000,0000,0000,,up the Rails environment and you'd have to\Nwait Dialogue: 0,0:10:56.43,0:10:58.36,Default,,0000,0000,0000,,a few seconds and then they would print out Dialogue: 0,0:10:58.36,0:11:00.36,Default,,0000,0000,0000,,all the routes. And then if you wanted to, Dialogue: 0,0:11:00.36,0:11:03.27,Default,,0000,0000,0000,,like, rerun it using grep, you would keep\Nrunning Dialogue: 0,0:11:03.27,0:11:04.39,Default,,0000,0000,0000,,it again. Dialogue: 0,0:11:04.39,0:11:07.03,Default,,0000,0000,0000,,So, a lot of us, when we're doing development, Dialogue: 0,0:11:07.03,0:11:10.64,Default,,0000,0000,0000,,already have, like, Rails running in a server\Nwhile Dialogue: 0,0:11:10.64,0:11:14.08,Default,,0000,0000,0000,,we're testing things and whatnot. And so what\Nsextant Dialogue: 0,0:11:14.08,0:11:17.75,Default,,0000,0000,0000,,does is it allows it, supports basically looking\Nat Dialogue: 0,0:11:17.75,0:11:19.94,Default,,0000,0000,0000,,the routes that are already in memory and\Njust Dialogue: 0,0:11:19.94,0:11:22.44,Default,,0000,0000,0000,,allowing you to query against the programmatically,\Nand then Dialogue: 0,0:11:22.44,0:11:24.71,Default,,0000,0000,0000,,that has a view for doing this. And this Dialogue: 0,0:11:24.71,0:11:27.96,Default,,0000,0000,0000,,was also just merged into Rails 4. So if Dialogue: 0,0:11:27.96,0:11:29.74,Default,,0000,0000,0000,,you're using Rails 4 or higher, you actually\Ndon't Dialogue: 0,0:11:29.74,0:11:33.57,Default,,0000,0000,0000,,need to sextant gem and it's now built in. Dialogue: 0,0:11:33.57,0:11:36.19,Default,,0000,0000,0000,,Richard and I both live in Austin, and so Dialogue: 0,0:11:36.19,0:11:38.19,Default,,0000,0000,0000,,when people come visit, or actually when I'm\Nin Dialogue: 0,0:11:38.19,0:11:41.23,Default,,0000,0000,0000,,town, which isn't often, we have Ruby meet\Nups Dialogue: 0,0:11:41.23,0:11:44.22,Default,,0000,0000,0000,,at Franklin's Barbecue, so if you guys are\Never Dialogue: 0,0:11:44.22,0:11:46.49,Default,,0000,0000,0000,,in town, let us know and we'd be more Dialogue: 0,0:11:46.49,0:11:49.62,Default,,0000,0000,0000,,than happy to take you to a meet up. Dialogue: 0,0:11:49.62,0:11:54.42,Default,,0000,0000,0000,,R.S.: All right. So the, for the first part Dialogue: 0,0:11:54.42,0:11:56.57,Default,,0000,0000,0000,,of this, this act, we're gonna be talking\Nabout Dialogue: 0,0:11:56.57,0:11:58.39,Default,,0000,0000,0000,,app speed, but before we talk about app speed, Dialogue: 0,0:11:58.39,0:12:03.46,Default,,0000,0000,0000,,we're actually gonna talk about dimensions.\NSo, the, the Dialogue: 0,0:12:03.46,0:12:09.27,Default,,0000,0000,0000,,document dimensions are, let me see. Here\Nwe go. Dialogue: 0,0:12:09.27,0:12:12.19,Default,,0000,0000,0000,,Were originally written in wide-screen, but\Nthe screens here Dialogue: 0,0:12:12.19,0:12:13.23,Default,,0000,0000,0000,,are standard. Dialogue: 0,0:12:13.23,0:12:17.73,Default,,0000,0000,0000,,There we go. So. You're actually gonna get\Nto Dialogue: 0,0:12:17.73,0:12:20.02,Default,,0000,0000,0000,,see all of the slides, as opposed to just Dialogue: 0,0:12:20.02,0:12:22.14,Default,,0000,0000,0000,,having some of them cut off. So, OK. Dialogue: 0,0:12:22.14,0:12:24.78,Default,,0000,0000,0000,,On, on app speed. The first thing I want Dialogue: 0,0:12:24.78,0:12:27.75,Default,,0000,0000,0000,,to talk about is, is tail latencies. Is anybody Dialogue: 0,0:12:27.75,0:12:31.20,Default,,0000,0000,0000,,familiar with tail latencies? OK. The guys\Nin the Dialogue: 0,0:12:31.20,0:12:34.27,Default,,0000,0000,0000,,Heroku t-shirts and somebody else. Dialogue: 0,0:12:34.27,0:12:38.70,Default,,0000,0000,0000,,OK. So this is, this is a normalized distribution. Dialogue: 0,0:12:38.70,0:12:41.99,Default,,0000,0000,0000,,WE have, on one side, the number of requests. Dialogue: 0,0:12:41.99,0:12:43.53,Default,,0000,0000,0000,,On the, on the other side, we have the Dialogue: 0,0:12:43.53,0:12:46.33,Default,,0000,0000,0000,,time to respond. So the further out you go, Dialogue: 0,0:12:46.33,0:12:49.07,Default,,0000,0000,0000,,the slower it's gonna be. And we can, we Dialogue: 0,0:12:49.07,0:12:50.99,Default,,0000,0000,0000,,can see this is the distribution of our requests. Dialogue: 0,0:12:50.99,0:12:54.55,Default,,0000,0000,0000,,So over here, it's super fast. Like you love Dialogue: 0,0:12:54.55,0:12:57.12,Default,,0000,0000,0000,,to be that customer. You're super happy. Dialogue: 0,0:12:57.12,0:12:59.77,Default,,0000,0000,0000,,Over here, we have a super slow request, and Dialogue: 0,0:12:59.77,0:13:01.16,Default,,0000,0000,0000,,you don't want to be that customer and you're Dialogue: 0,0:13:01.16,0:13:05.26,Default,,0000,0000,0000,,pretty unhappy. So right in the middle is\Nour Dialogue: 0,0:13:05.26,0:13:09.06,Default,,0000,0000,0000,,average, and I'm sure they talked a ton about Dialogue: 0,0:13:09.06,0:13:11.67,Default,,0000,0000,0000,,why the average is really misleading in the,\Nin Dialogue: 0,0:13:11.67,0:13:14.72,Default,,0000,0000,0000,,the last session with Skylight.IO. But, but\Nwe're basically Dialogue: 0,0:13:14.72,0:13:17.60,Default,,0000,0000,0000,,saying that, roughly fifty percent of your,\Nof your Dialogue: 0,0:13:17.60,0:13:20.14,Default,,0000,0000,0000,,customers, fifty percent of your traffic,\Nis going to Dialogue: 0,0:13:20.14,0:13:24.12,Default,,0000,0000,0000,,get a response time at this or, or lower. Dialogue: 0,0:13:24.12,0:13:26.40,Default,,0000,0000,0000,,So, like, this is, this is pretty decent.\NWe Dialogue: 0,0:13:26.40,0:13:27.75,Default,,0000,0000,0000,,can say, like, fifty percent of the people\Nwho Dialogue: 0,0:13:27.75,0:13:29.90,Default,,0000,0000,0000,,come to our web site get a response before Dialogue: 0,0:13:29.90,0:13:34.65,Default,,0000,0000,0000,,then. Moving up the distribution, to something\Nlike perk Dialogue: 0,0:13:34.65,0:13:37.36,Default,,0000,0000,0000,,ninety-five, we say ninety-five percent of\Neveryone who visits Dialogue: 0,0:13:37.36,0:13:40.50,Default,,0000,0000,0000,,our traffic will get a response by now. So Dialogue: 0,0:13:40.50,0:13:42.34,Default,,0000,0000,0000,,I'm gonna be using those terms, perk fifty,\Nperk Dialogue: 0,0:13:42.34,0:13:46.06,Default,,0000,0000,0000,,ninety-five, that refers to the percentage\Nof, of requests Dialogue: 0,0:13:46.06,0:13:48.65,Default,,0000,0000,0000,,that come in that we can respond by. Dialogue: 0,0:13:48.65,0:13:50.94,Default,,0000,0000,0000,,So this is kind of theorized. This is an Dialogue: 0,0:13:50.94,0:13:56.56,Default,,0000,0000,0000,,actual application. I, and one thing that\Nyou'll notice Dialogue: 0,0:13:56.56,0:13:59.40,Default,,0000,0000,0000,,is that it's not perfectly normalized. Like,\Nit's not, Dialogue: 0,0:13:59.40,0:14:01.80,Default,,0000,0000,0000,,like both sides are not symmetrical. We kind\Nof Dialogue: 0,0:14:01.80,0:14:04.31,Default,,0000,0000,0000,,like, steeply shoot up, and then we have this Dialogue: 0,0:14:04.31,0:14:07.73,Default,,0000,0000,0000,,really, really long tail, and, and this is\Nkind Dialogue: 0,0:14:07.73,0:14:09.58,Default,,0000,0000,0000,,of the, what I'm referring to when I'm saying Dialogue: 0,0:14:09.58,0:14:10.64,Default,,0000,0000,0000,,tail latencies. Dialogue: 0,0:14:10.64,0:14:13.95,Default,,0000,0000,0000,,So, yes, somebody actually might have gotten\Na response Dialogue: 0,0:14:13.95,0:14:17.27,Default,,0000,0000,0000,,in zero milliseconds. You know, I doubt it,\Nbut Dialogue: 0,0:14:17.27,0:14:20.27,Default,,0000,0000,0000,,somebody for sure did get a response in 3000 Dialogue: 0,0:14:20.27,0:14:23.22,Default,,0000,0000,0000,,milliseconds, and that's a really long time\Nto wait Dialogue: 0,0:14:23.22,0:14:26.16,Default,,0000,0000,0000,,for your request to actually come in and,\Nand Dialogue: 0,0:14:26.16,0:14:28.62,Default,,0000,0000,0000,,get finished. So even though somebody is getting\Nreally Dialogue: 0,0:14:28.62,0:14:31.02,Default,,0000,0000,0000,,fast responses, and your average isn't bad\N- your Dialogue: 0,0:14:31.02,0:14:34.85,Default,,0000,0000,0000,,average is under 250 milliseconds - one customer\Nmight Dialogue: 0,0:14:34.85,0:14:36.89,Default,,0000,0000,0000,,be getting a really slow response and a really Dialogue: 0,0:14:36.89,0:14:39.47,Default,,0000,0000,0000,,fast response, and, and the net is a bad Dialogue: 0,0:14:39.47,0:14:40.35,Default,,0000,0000,0000,,experience. Dialogue: 0,0:14:40.35,0:14:43.62,Default,,0000,0000,0000,,So, the net, it, it just, it's a very Dialogue: 0,0:14:43.62,0:14:47.79,Default,,0000,0000,0000,,inconsistent experience. So whenever we're\Ntalking about application speed, Dialogue: 0,0:14:47.79,0:14:50.96,Default,,0000,0000,0000,,we have to consider individual request speed\Nand average, Dialogue: 0,0:14:50.96,0:14:55.58,Default,,0000,0000,0000,,but also consistency. How consistent is each\Nrequest? Dialogue: 0,0:14:55.58,0:14:58.57,Default,,0000,0000,0000,,So, how do, how do we do this? What? Dialogue: 0,0:14:58.57,0:15:00.64,Default,,0000,0000,0000,,How can we, how can we help with this? Dialogue: 0,0:15:00.64,0:15:02.53,Default,,0000,0000,0000,,Well, one of the things that we launched this Dialogue: 0,0:15:02.53,0:15:06.25,Default,,0000,0000,0000,,year was PX dynos. So a PX dyno - Dialogue: 0,0:15:06.25,0:15:09.43,Default,,0000,0000,0000,,a typical dyno only has 512 megabytes of RAM. Dialogue: 0,0:15:09.43,0:15:12.53,Default,,0000,0000,0000,,It's a shared infrastructure. A PX Dyna has\Nsix Dialogue: 0,0:15:12.53,0:15:15.96,Default,,0000,0000,0000,,gigabytes of RAM and eight CPU cores, which\Nis Dialogue: 0,0:15:15.96,0:15:17.68,Default,,0000,0000,0000,,a little, a little nicer, a little better,\Na Dialogue: 0,0:15:17.68,0:15:19.82,Default,,0000,0000,0000,,little bit more room to play. Dialogue: 0,0:15:19.82,0:15:24.50,Default,,0000,0000,0000,,And, and it's also real hardware. So, or,\Nit's, Dialogue: 0,0:15:24.50,0:15:29.43,Default,,0000,0000,0000,,it's not on the same shared infrastructure.\NSo you Dialogue: 0,0:15:29.43,0:15:32.56,Default,,0000,0000,0000,,can, you can scale with Dynos, you, you can Dialogue: 0,0:15:32.56,0:15:34.68,Default,,0000,0000,0000,,also scale inside of Dynos. And that's kind\Nof Dialogue: 0,0:15:34.68,0:15:37.32,Default,,0000,0000,0000,,two, two important parts that we're gonna,\Ngonna have Dialogue: 0,0:15:37.32,0:15:40.38,Default,,0000,0000,0000,,to cover. So, of course, whenever you have\Nmore Dialogue: 0,0:15:40.38,0:15:42.81,Default,,0000,0000,0000,,requests that you can possibly process, you\Nwant to Dialogue: 0,0:15:42.81,0:15:45.44,Default,,0000,0000,0000,,scale up and say, I'm gonna have more Dynos. Dialogue: 0,0:15:45.44,0:15:50.43,Default,,0000,0000,0000,,But what happens if, if you're not making\Nthe Dialogue: 0,0:15:50.43,0:15:53.12,Default,,0000,0000,0000,,best use of everything inside of your dyno?\NPreviously Dialogue: 0,0:15:53.12,0:15:55.16,Default,,0000,0000,0000,,with 512 megabytes of RAM, you could just,\Nyou Dialogue: 0,0:15:55.16,0:15:56.89,Default,,0000,0000,0000,,know, throw a couple Unicorn workers in there\Nand Dialogue: 0,0:15:56.89,0:15:58.91,Default,,0000,0000,0000,,you're like, oh, I'm probably using most of\Nthis. Dialogue: 0,0:15:58.91,0:16:00.88,Default,,0000,0000,0000,,Like, if you put two unicorn workers in a Dialogue: 0,0:16:00.88,0:16:03.37,Default,,0000,0000,0000,,PX Dyno, you're not making the most use of Dialogue: 0,0:16:03.37,0:16:04.21,Default,,0000,0000,0000,,it all. Dialogue: 0,0:16:04.21,0:16:07.74,Default,,0000,0000,0000,,So, recently, I am super in love with, with Dialogue: 0,0:16:07.74,0:16:12.95,Default,,0000,0000,0000,,Puma. Evan, this is Evan Phoenix's web server\Nthat Dialogue: 0,0:16:12.95,0:16:15.06,Default,,0000,0000,0000,,was originally written at, to kind of show\Ncase Dialogue: 0,0:16:15.06,0:16:18.05,Default,,0000,0000,0000,,Rubinius. Guess what? It's really nice with\NMRI as Dialogue: 0,0:16:18.05,0:16:22.03,Default,,0000,0000,0000,,well. Recently we've gotten some Puma docs,\Nand so Dialogue: 0,0:16:22.03,0:16:23.81,Default,,0000,0000,0000,,I'm gonna talk about Puma for just, for just Dialogue: 0,0:16:23.81,0:16:24.54,Default,,0000,0000,0000,,a little bit. Dialogue: 0,0:16:24.54,0:16:29.56,Default,,0000,0000,0000,,So, if you're, if you're not familiar. I was Dialogue: 0,0:16:29.56,0:16:34.83,Default,,0000,0000,0000,,totally off on the formatting. So, Puma handles\Nrequests Dialogue: 0,0:16:34.83,0:16:38.28,Default,,0000,0000,0000,,by running multiple processes, or by multiple\Nthreads. And Dialogue: 0,0:16:38.28,0:16:40.04,Default,,0000,0000,0000,,it can actually run in something called a\Nhybrid Dialogue: 0,0:16:40.04,0:16:43.19,Default,,0000,0000,0000,,mode, where each process has multiple threads.\NWe, we Dialogue: 0,0:16:43.19,0:16:45.82,Default,,0000,0000,0000,,recommend this, or I recommend this. E- if\None Dialogue: 0,0:16:45.82,0:16:47.98,Default,,0000,0000,0000,,of your processes crash, it doesn't crash\Nyour entire Dialogue: 0,0:16:47.98,0:16:51.40,Default,,0000,0000,0000,,web server. It's kind of nice. Dialogue: 0,0:16:51.40,0:16:54.11,Default,,0000,0000,0000,,And so the multiple processes is something\Nthat we're Dialogue: 0,0:16:54.11,0:16:57.96,Default,,0000,0000,0000,,pretty familiar with. As Rubyists, we're familiar\Nwith forking Dialogue: 0,0:16:57.96,0:17:02.13,Default,,0000,0000,0000,,processes. We're familiar with Unicorn. But\Nthe, the, the Dialogue: 0,0:17:02.13,0:17:04.22,Default,,0000,0000,0000,,multiple threads is a little bit different. Dialogue: 0,0:17:04.22,0:17:07.26,Default,,0000,0000,0000,,Even with MRI, even with a, something like\Na Dialogue: 0,0:17:07.26,0:17:10.36,Default,,0000,0000,0000,,global interpreter lock, you are still doing\Nenough IO, Dialogue: 0,0:17:10.36,0:17:13.57,Default,,0000,0000,0000,,you're still hitting your database frequently\Nenough, maybe making Dialogue: 0,0:17:13.57,0:17:17.51,Default,,0000,0000,0000,,API calls to like, Facebook or GitHub status,\Nbeing Dialogue: 0,0:17:17.51,0:17:19.97,Default,,0000,0000,0000,,like, hey, are you still up? Dialogue: 0,0:17:19.97,0:17:23.10,Default,,0000,0000,0000,,And, and this will give our threads time to Dialogue: 0,0:17:23.10,0:17:25.46,Default,,0000,0000,0000,,kind of jump around and allow others to do Dialogue: 0,0:17:25.46,0:17:27.05,Default,,0000,0000,0000,,work. So you, you can get quite an extra Dialogue: 0,0:17:27.05,0:17:29.11,Default,,0000,0000,0000,,bit of performance with, there. Dialogue: 0,0:17:29.11,0:17:31.29,Default,,0000,0000,0000,,So, we're actually gonna be using Puma to\Nscale Dialogue: 0,0:17:31.29,0:17:33.47,Default,,0000,0000,0000,,up inside of our Dynos. So once we give Dialogue: 0,0:17:33.47,0:17:35.78,Default,,0000,0000,0000,,you that eight gigs of RAM, we want to Dialogue: 0,0:17:35.78,0:17:38.28,Default,,0000,0000,0000,,make sure that, that you can, you can, you Dialogue: 0,0:17:38.28,0:17:39.83,Default,,0000,0000,0000,,can make the most use out of it. Dialogue: 0,0:17:39.83,0:17:43.71,Default,,0000,0000,0000,,In general, with Puma, more processes means\Nmore RAM, Dialogue: 0,0:17:43.71,0:17:47.36,Default,,0000,0000,0000,,and more threads are gonna need more CPU consumption. Dialogue: 0,0:17:47.36,0:17:50.05,Default,,0000,0000,0000,,So, you want to, you want to maximize your Dialogue: 0,0:17:50.05,0:17:52.87,Default,,0000,0000,0000,,processes and maximize your threads, kind\Nof without going Dialogue: 0,0:17:52.87,0:17:54.37,Default,,0000,0000,0000,,over. As soon as you start swapping, as soon Dialogue: 0,0:17:54.37,0:17:56.55,Default,,0000,0000,0000,,as you go over that RAM limit, your app's Dialogue: 0,0:17:56.55,0:17:58.93,Default,,0000,0000,0000,,gonna be really slow and that kind of defeats Dialogue: 0,0:17:58.93,0:18:02.67,Default,,0000,0000,0000,,the purpose of trying to add these resources. Dialogue: 0,0:18:02.67,0:18:06.24,Default,,0000,0000,0000,,Another issue is that I had kind of never Dialogue: 0,0:18:06.24,0:18:07.94,Default,,0000,0000,0000,,heard of until I started looking into all\Nof Dialogue: 0,0:18:07.94,0:18:11.30,Default,,0000,0000,0000,,these multiple web servers, is slow-client.\NSo if somebody's Dialogue: 0,0:18:11.30,0:18:13.94,Default,,0000,0000,0000,,connecting to your web site via like, a two Dialogue: 0,0:18:13.94,0:18:17.66,Default,,0000,0000,0000,,G over like a Nokia candy bar phone, uploading Dialogue: 0,0:18:17.66,0:18:20.18,Default,,0000,0000,0000,,like photos or something like that, like that\Nis Dialogue: 0,0:18:20.18,0:18:22.33,Default,,0000,0000,0000,,a slow client, and if you're using something\Nlike Dialogue: 0,0:18:22.33,0:18:27.00,Default,,0000,0000,0000,,Unicorn, it can deDOS your, your site, because\Neach Dialogue: 0,0:18:27.00,0:18:29.67,Default,,0000,0000,0000,,one of those requests takes up an entire Unicorn Dialogue: 0,0:18:29.67,0:18:32.89,Default,,0000,0000,0000,,worker, whereas Puma has a, has a buffer,\Nand Dialogue: 0,0:18:32.89,0:18:36.39,Default,,0000,0000,0000,,it buffers those requests as similar to the\Nway Dialogue: 0,0:18:36.39,0:18:38.34,Default,,0000,0000,0000,,NginX does. Dialogue: 0,0:18:38.34,0:18:40.86,Default,,0000,0000,0000,,One other thing to consider with Puma is,\Nso Dialogue: 0,0:18:40.86,0:18:44.26,Default,,0000,0000,0000,,I'm mentioning threads, I'm talking, talking\Nabout threads. Ruby, Dialogue: 0,0:18:44.26,0:18:48.57,Default,,0000,0000,0000,,we're not necessarily known as the most thread-safe\Nculture. Dialogue: 0,0:18:48.57,0:18:52.06,Default,,0000,0000,0000,,Thread-safe community. And so a lot of apps\Njust Dialogue: 0,0:18:52.06,0:18:54.54,Default,,0000,0000,0000,,aren't thread-safe. And so some, you might\Ntake a Dialogue: 0,0:18:54.54,0:18:55.92,Default,,0000,0000,0000,,look at Puma and be like, hey, that's not Dialogue: 0,0:18:55.92,0:18:58.82,Default,,0000,0000,0000,,for me. You can always set your maximum threads Dialogue: 0,0:18:58.82,0:19:01.40,Default,,0000,0000,0000,,to one, and then now you're behaving just\Nlike Dialogue: 0,0:19:01.40,0:19:05.27,Default,,0000,0000,0000,,Unicorn, except you have the slow-client protection,\Nand whenever Dialogue: 0,0:19:05.27,0:19:08.17,Default,,0000,0000,0000,,you get that gem that's bad or you, like, Dialogue: 0,0:19:08.17,0:19:13.18,Default,,0000,0000,0000,,stop mutating your constants are runtime or\Nsomething, then Dialogue: 0,0:19:13.18,0:19:15.57,Default,,0000,0000,0000,,you can maybe bump up and try multiple threads. Dialogue: 0,0:19:15.57,0:19:18.98,Default,,0000,0000,0000,,OK. So, I'm, I'm talking about consistency\Nand I'm Dialogue: 0,0:19:18.98,0:19:20.99,Default,,0000,0000,0000,,talking a lot about Puma. How does that all Dialogue: 0,0:19:20.99,0:19:25.38,Default,,0000,0000,0000,,kind of boil down and help? So, does anybody Dialogue: 0,0:19:25.38,0:19:29.63,Default,,0000,0000,0000,,think that sharing distributed state across\Nmultiple machines is Dialogue: 0,0:19:29.63,0:19:36.63,Default,,0000,0000,0000,,like really fast? Maybe. I, OK. Good. Dialogue: 0,0:19:37.15,0:19:39.44,Default,,0000,0000,0000,,What about sharing state inside of memory\Non the Dialogue: 0,0:19:39.44,0:19:44.52,Default,,0000,0000,0000,,same machine? Is that faster? OK. All right.\NI Dialogue: 0,0:19:44.52,0:19:47.55,Default,,0000,0000,0000,,think we're in, in agreement. So, a, a little Dialogue: 0,0:19:47.55,0:19:50.12,Default,,0000,0000,0000,,bit of a point of controversy. You might have Dialogue: 0,0:19:50.12,0:19:53.75,Default,,0000,0000,0000,,heard of the, the Heroku router at some point Dialogue: 0,0:19:53.75,0:19:58.31,Default,,0000,0000,0000,,in time. And this, the router is actually\Ndesigned, Dialogue: 0,0:19:58.31,0:20:00.63,Default,,0000,0000,0000,,not randomly, but it is, it is designed to Dialogue: 0,0:20:00.63,0:20:04.30,Default,,0000,0000,0000,,use a random algorithm. And it basically will\Ntry Dialogue: 0,0:20:04.30,0:20:07.36,Default,,0000,0000,0000,,to deliver requests as fast as humanly possible,\Nor Dialogue: 0,0:20:07.36,0:20:11.21,Default,,0000,0000,0000,,computerly possible, to individual dynos.\NSo it's like, it Dialogue: 0,0:20:11.21,0:20:12.58,Default,,0000,0000,0000,,gets the request. It wants to get it to Dialogue: 0,0:20:12.58,0:20:15.28,Default,,0000,0000,0000,,your dyno as fast as it possibly can. Dialogue: 0,0:20:15.28,0:20:18.26,Default,,0000,0000,0000,,And adding any sort of additional overhead\Nof distributed Dialogue: 0,0:20:18.26,0:20:24.18,Default,,0000,0000,0000,,locks or queues is gonna be slowing that down. Dialogue: 0,0:20:24.18,0:20:26.69,Default,,0000,0000,0000,,Once inside of your, in your, your process,\NPuma Dialogue: 0,0:20:26.69,0:20:30.76,Default,,0000,0000,0000,,or Unicorn has, in memory, state of all of Dialogue: 0,0:20:30.76,0:20:33.30,Default,,0000,0000,0000,,its own processes, and is capable of saying,\Noh, Dialogue: 0,0:20:33.30,0:20:35.40,Default,,0000,0000,0000,,hey, this process is busy. This process is\Nnot Dialogue: 0,0:20:35.40,0:20:40.06,Default,,0000,0000,0000,,busy. I can do really intelligent routing\Nand, and Dialogue: 0,0:20:40.06,0:20:43.72,Default,,0000,0000,0000,,basically, for free. Dialogue: 0,0:20:43.72,0:20:45.97,Default,,0000,0000,0000,,It's really fast. It, it took a little bit Dialogue: 0,0:20:45.97,0:20:49.60,Default,,0000,0000,0000,,of convincing for me. So does anybody else\Nneed Dialogue: 0,0:20:49.60,0:20:50.46,Default,,0000,0000,0000,,to be convinced? Dialogue: 0,0:20:50.46,0:20:51.59,Default,,0000,0000,0000,,AUDIENCE: Yeah. Dialogue: 0,0:20:51.59,0:20:54.68,Default,,0000,0000,0000,,R.S.: OK. Good. Cause otherwise I could totally\Njust Dialogue: 0,0:20:54.68,0:20:57.28,Default,,0000,0000,0000,,skip over the next section of slides. Dialogue: 0,0:20:57.28,0:21:00.57,Default,,0000,0000,0000,,So, this is, this is a graph produced by Dialogue: 0,0:21:00.57,0:21:05.76,Default,,0000,0000,0000,,the fine developers over at, at RapGenius,\Nand on Dialogue: 0,0:21:05.76,0:21:07.94,Default,,0000,0000,0000,,one side we will actually see a percentage\Nof Dialogue: 0,0:21:07.94,0:21:10.74,Default,,0000,0000,0000,,requests queued, and on the bottom we are\Ngonna Dialogue: 0,0:21:10.74,0:21:13.16,Default,,0000,0000,0000,,be seeing number of dynos. So the goal is Dialogue: 0,0:21:13.16,0:21:15.93,Default,,0000,0000,0000,,actually to minimize request queuing, like\Nthis, this is Dialogue: 0,0:21:15.93,0:21:18.00,Default,,0000,0000,0000,,time that your customers are waiting that\Nyou're not Dialogue: 0,0:21:18.00,0:21:19.56,Default,,0000,0000,0000,,actually doing anything. Dialogue: 0,0:21:19.56,0:21:21.87,Default,,0000,0000,0000,,You, so you, you want to minimize that queuing Dialogue: 0,0:21:21.87,0:21:24.22,Default,,0000,0000,0000,,with the smallest number of resources, so\Nthe smallest Dialogue: 0,0:21:24.22,0:21:28.02,Default,,0000,0000,0000,,number of dynos. This top line, we actually\Nhave Dialogue: 0,0:21:28.02,0:21:30.51,Default,,0000,0000,0000,,is what we've currently got now. The random\Nrouting Dialogue: 0,0:21:30.51,0:21:34.56,Default,,0000,0000,0000,,with a, a single-threaded server. And, like,\Nthis is Dialogue: 0,0:21:34.56,0:21:36.96,Default,,0000,0000,0000,,pretty bad. It, like, starts out bad and it, Dialogue: 0,0:21:36.96,0:21:39.18,Default,,0000,0000,0000,,like, it doesn't even like trend towards zero.\NSo Dialogue: 0,0:21:39.18,0:21:41.12,Default,,0000,0000,0000,,this is probably bad. So this is using something Dialogue: 0,0:21:41.12,0:21:43.50,Default,,0000,0000,0000,,like Webrick in production. Dialogue: 0,0:21:43.50,0:21:47.89,Default,,0000,0000,0000,,So. Don't use Webrick in production. Or, or\Nlike Dialogue: 0,0:21:47.89,0:21:54.89,Default,,0000,0000,0000,,even, even thin. In single-threaded mode.\NSo, on the, Dialogue: 0,0:21:55.15,0:21:58.05,Default,,0000,0000,0000,,on the very bottom, we actually have a, like, Dialogue: 0,0:21:58.05,0:22:01.28,Default,,0000,0000,0000,,mythological, like, if, if we could do all\Nof Dialogue: 0,0:22:01.28,0:22:05.41,Default,,0000,0000,0000,,that distributed shared state without, and\Nlocks and queues, Dialogue: 0,0:22:05.41,0:22:08.25,Default,,0000,0000,0000,,without having any kind of overhead, we can\Nsee Dialogue: 0,0:22:08.25,0:22:11.39,Default,,0000,0000,0000,,that, basically, it just drops down to zero\Nat Dialogue: 0,0:22:11.39,0:22:14.38,Default,,0000,0000,0000,,about, you know, in their case, about seventy-five\Ndynos, Dialogue: 0,0:22:14.38,0:22:16.35,Default,,0000,0000,0000,,and then just, you know, it's straight zero.\NThere's Dialogue: 0,0:22:16.35,0:22:17.19,Default,,0000,0000,0000,,no queuing. Dialogue: 0,0:22:17.19,0:22:19.02,Default,,0000,0000,0000,,And it's great. And this would be amazing\Nif Dialogue: 0,0:22:19.02,0:22:22.20,Default,,0000,0000,0000,,we could have it. But unfortunately there\Nis a Dialogue: 0,0:22:22.20,0:22:24.75,Default,,0000,0000,0000,,little bit over overhead. What was really\Ninteresting to Dialogue: 0,0:22:24.75,0:22:27.57,Default,,0000,0000,0000,,me is this second one, which is not nearly Dialogue: 0,0:22:27.57,0:22:30.90,Default,,0000,0000,0000,,as nice as that mythological intelligent router,\Nbut it's Dialogue: 0,0:22:30.90,0:22:34.21,Default,,0000,0000,0000,,kind of not too far off. This is still Dialogue: 0,0:22:34.21,0:22:36.89,Default,,0000,0000,0000,,our random routing, and, and this was actually\Ndone Dialogue: 0,0:22:36.89,0:22:41.88,Default,,0000,0000,0000,,with Unicorn, and workers set to two. So basically, Dialogue: 0,0:22:41.88,0:22:44.49,Default,,0000,0000,0000,,once we get the, the request to your operating Dialogue: 0,0:22:44.49,0:22:46.26,Default,,0000,0000,0000,,system, it's like one of those two workers\Nis Dialogue: 0,0:22:46.26,0:22:48.62,Default,,0000,0000,0000,,free and can immediately start working on\Nit. Dialogue: 0,0:22:48.62,0:22:51.49,Default,,0000,0000,0000,,Some, some interesting things known about\Nthis is, for Dialogue: 0,0:22:51.49,0:22:54.22,Default,,0000,0000,0000,,the non-optimal case, for the, we basically\Ndon't have Dialogue: 0,0:22:54.22,0:22:56.46,Default,,0000,0000,0000,,enough dynos to handle this, so that might\Nhappen Dialogue: 0,0:22:56.46,0:22:58.91,Default,,0000,0000,0000,,is, you know, you got on Hacker News or Dialogue: 0,0:22:58.91,0:23:05.91,Default,,0000,0000,0000,,whatever, slash dotted, Reddited. SnapChatted.\NSecreted. I don't know. Dialogue: 0,0:23:07.62,0:23:11.99,Default,,0000,0000,0000,,And it does actually, eventually approach\Nideal state. So, Dialogue: 0,0:23:11.99,0:23:14.82,Default,,0000,0000,0000,,it, it gets even better, and unfortunately\Nthey kind Dialogue: 0,0:23:14.82,0:23:17.82,Default,,0000,0000,0000,,of stopped at, at two processes, but it gets Dialogue: 0,0:23:17.82,0:23:20.29,Default,,0000,0000,0000,,better, the more concurrency that you add.\NSo if Dialogue: 0,0:23:20.29,0:23:23.23,Default,,0000,0000,0000,,you had three or four workers or, again, if Dialogue: 0,0:23:23.23,0:23:24.83,Default,,0000,0000,0000,,you're using something like Puma, and each\None of Dialogue: 0,0:23:24.83,0:23:27.63,Default,,0000,0000,0000,,those workers is running, like, four threads,\Nnow you Dialogue: 0,0:23:27.63,0:23:29.54,Default,,0000,0000,0000,,have, like, a massive amount of concurrency\Nthat you Dialogue: 0,0:23:29.54,0:23:31.05,Default,,0000,0000,0000,,could deal with all of these requests coming\Nin. Dialogue: 0,0:23:31.05,0:23:35.64,Default,,0000,0000,0000,,So, the, the, the, if, again, and we're looking Dialogue: 0,0:23:35.64,0:23:37.92,Default,,0000,0000,0000,,for consistency. We want that request to get\Nto Dialogue: 0,0:23:37.92,0:23:40.85,Default,,0000,0000,0000,,our dyno, immediately be able to process it.\NSo, Dialogue: 0,0:23:40.85,0:23:43.61,Default,,0000,0000,0000,,you can use Puma or Unicorn to maximize that Dialogue: 0,0:23:43.61,0:23:49.70,Default,,0000,0000,0000,,worker number, and, again, distributed optimi-\Ndistributed routing is Dialogue: 0,0:23:49.70,0:23:54.14,Default,,0000,0000,0000,,slow. In memory, routing is relatively quick. Dialogue: 0,0:23:54.14,0:24:00.10,Default,,0000,0000,0000,,On, again, just in, in the whole context of Dialogue: 0,0:24:00.10,0:24:04.82,Default,,0000,0000,0000,,speed, Ruby 2.0 came out and this was awhile Dialogue: 0,0:24:04.82,0:24:07.25,Default,,0000,0000,0000,,ago. It's got GC, it's optimized for Copy\Non Dialogue: 0,0:24:07.25,0:24:12.18,Default,,0000,0000,0000,,Write. In, in Ruby, extra processes, process\Nforks actually Dialogue: 0,0:24:12.18,0:24:14.43,Default,,0000,0000,0000,,become cheaper. So the first process might\Ntake seventy Dialogue: 0,0:24:14.43,0:24:17.25,Default,,0000,0000,0000,,megabytes, the second one twenty, and ten\Nand seven Dialogue: 0,0:24:17.25,0:24:19.90,Default,,0000,0000,0000,,and six. So, if you get a larger box, Dialogue: 0,0:24:19.90,0:24:22.62,Default,,0000,0000,0000,,you can actually run more processes on them.\NIf Dialogue: 0,0:24:22.62,0:24:24.30,Default,,0000,0000,0000,,you get eight gigs on one box, you can Dialogue: 0,0:24:24.30,0:24:26.89,Default,,0000,0000,0000,,run more processes than you can if you had Dialogue: 0,0:24:26.89,0:24:28.96,Default,,0000,0000,0000,,eight gigs across eight boxes. Dialogue: 0,0:24:28.96,0:24:33.47,Default,,0000,0000,0000,,So, again, more processes mean more concurrency,\Nand more Dialogue: 0,0:24:33.47,0:24:38.90,Default,,0000,0000,0000,,concurrency means consistency. If you are\Nusing workers, you Dialogue: 0,0:24:38.90,0:24:43.40,Default,,0000,0000,0000,,can, you can also scale out with Resq pool, Dialogue: 0,0:24:43.40,0:24:46.37,Default,,0000,0000,0000,,and if your application's still slow, we rolled\Nout Dialogue: 0,0:24:46.37,0:24:48.48,Default,,0000,0000,0000,,a couple of really neat platform features.\NOne of Dialogue: 0,0:24:48.48,0:24:52.04,Default,,0000,0000,0000,,them is, is called HTTP Request ID. So as Dialogue: 0,0:24:52.04,0:24:54.86,Default,,0000,0000,0000,,a request comes into our system, we will actually Dialogue: 0,0:24:54.86,0:24:57.30,Default,,0000,0000,0000,,give it a uuid, and you can see this Dialogue: 0,0:24:57.30,0:25:00.49,Default,,0000,0000,0000,,in your router log. And then we've got documentation Dialogue: 0,0:25:00.49,0:25:02.79,Default,,0000,0000,0000,,on how to configure your Rails app so it Dialogue: 0,0:25:02.79,0:25:05.41,Default,,0000,0000,0000,,will actually pick this up and use that uuid Dialogue: 0,0:25:05.41,0:25:06.59,Default,,0000,0000,0000,,in tagged logs. Dialogue: 0,0:25:06.59,0:25:09.59,Default,,0000,0000,0000,,So, like, how is this useful? So, if you Dialogue: 0,0:25:09.59,0:25:11.74,Default,,0000,0000,0000,,are getting, like, and out of memory error,\Nor Dialogue: 0,0:25:11.74,0:25:13.87,Default,,0000,0000,0000,,if your request is taking a really long time Dialogue: 0,0:25:13.87,0:25:16.20,Default,,0000,0000,0000,,and you're like, ah, like, that request is\Ntiming Dialogue: 0,0:25:16.20,0:25:19.38,Default,,0000,0000,0000,,out and, you know, Heroku's returning a response\Nand Dialogue: 0,0:25:19.38,0:25:22.32,Default,,0000,0000,0000,,we don't even know why. Now, if the request Dialogue: 0,0:25:22.32,0:25:24.37,Default,,0000,0000,0000,,id is tagged, you can actually follow along\Nbetween Dialogue: 0,0:25:24.37,0:25:26.09,Default,,0000,0000,0000,,your two logs and be like, oh, it's hitting Dialogue: 0,0:25:26.09,0:25:28.54,Default,,0000,0000,0000,,that controller action. Maybe I should be\Nsending that Dialogue: 0,0:25:28.54,0:25:31.16,Default,,0000,0000,0000,,email in the background as opposed to having\Nto Dialogue: 0,0:25:31.16,0:25:34.14,Default,,0000,0000,0000,,actually block on it. So you can trace specific Dialogue: 0,0:25:34.14,0:25:34.96,Default,,0000,0000,0000,,errors. Dialogue: 0,0:25:34.96,0:25:38.50,Default,,0000,0000,0000,,We also launched Log Runtime Metrics awhile\Nago, and Dialogue: 0,0:25:38.50,0:25:42.95,Default,,0000,0000,0000,,this is something that we'll actually put\Nyour, your Dialogue: 0,0:25:42.95,0:25:45.24,Default,,0000,0000,0000,,runtime information directly into your logs.\NYou can check Dialogue: 0,0:25:45.24,0:25:49.87,Default,,0000,0000,0000,,it out. Liberato will automatically pick it\Nup for Dialogue: 0,0:25:49.87,0:25:52.50,Default,,0000,0000,0000,,you and make you these, these really nice\Ngraphs. Dialogue: 0,0:25:52.50,0:25:55.33,Default,,0000,0000,0000,,And, again, if you're doing something like\NUnicorn or, Dialogue: 0,0:25:55.33,0:25:57.46,Default,,0000,0000,0000,,or Puma, then you want to get as close Dialogue: 0,0:25:57.46,0:26:00.57,Default,,0000,0000,0000,,to your RAM limit without actually going over. Dialogue: 0,0:26:00.57,0:26:05.40,Default,,0000,0000,0000,,OK. So, the, the next act in, in our Dialogue: 0,0:26:05.40,0:26:09.66,Default,,0000,0000,0000,,play, again, introducing Terence, is, we'll\Nbe talking about Dialogue: 0,0:26:09.66,0:26:12.16,Default,,0000,0000,0000,,Ruby on the Heroku stack and in the community. Dialogue: 0,0:26:12.16,0:26:15.63,Default,,0000,0000,0000,,T.L.: Thank you. So I know we're at RailsConf, Dialogue: 0,0:26:15.63,0:26:17.69,Default,,0000,0000,0000,,but I've been doing a bunch of work with Dialogue: 0,0:26:17.69,0:26:20.94,Default,,0000,0000,0000,,Ruby, so I wanted to talk about some Ruby Dialogue: 0,0:26:20.94,0:26:25.42,Default,,0000,0000,0000,,stuff. So who here is actually using Ruby\N1.8.7? Dialogue: 0,0:26:25.42,0:26:31.89,Default,,0000,0000,0000,,Wow. No one. That's pretty awesome. Oh, wait.\NOne Dialogue: 0,0:26:31.89,0:26:34.94,Default,,0000,0000,0000,,person. You should probably get off of it. Dialogue: 0,0:26:34.94,0:26:35.88,Default,,0000,0000,0000,,[laughter] Dialogue: 0,0:26:35.88,0:26:41.19,Default,,0000,0000,0000,,But. Who is using Ruby 1.9.2? A few more Dialogue: 0,0:26:41.19,0:26:48.19,Default,,0000,0000,0000,,people. 1.9.3? Good amount of people here. Dialogue: 0,0:26:48.66,0:26:51.16,Default,,0000,0000,0000,,So, I don't know if you guys were following Dialogue: 0,0:26:51.16,0:26:54.98,Default,,0000,0000,0000,,along, but Ruby 1.8.7 and 1.9.2 got end-of-lifed\Nat Dialogue: 0,0:26:54.98,0:26:59.47,Default,,0000,0000,0000,,one point. And then there was a security incidence, Dialogue: 0,0:26:59.47,0:27:03.51,Default,,0000,0000,0000,,and Zachary Scott and I have volunteered to\Nmaintain Dialogue: 0,0:27:03.51,0:27:07.35,Default,,0000,0000,0000,,security patches till the end of June. So,\Nif Dialogue: 0,0:27:07.35,0:27:12.86,Default,,0000,0000,0000,,you are on 1.8.7 and 1.9.2, I would recommend Dialogue: 0,0:27:12.86,0:27:16.87,Default,,0000,0000,0000,,hopefully getting off some time soon, unless\Nyou don't Dialogue: 0,0:27:16.87,0:27:19.19,Default,,0000,0000,0000,,care about security or want to back port your Dialogue: 0,0:27:19.19,0:27:22.49,Default,,0000,0000,0000,,own patches. Dialogue: 0,0:27:22.49,0:27:25.04,Default,,0000,0000,0000,,And then Ru- we recently announced that Ruby\N1.9.3 Dialogue: 0,0:27:25.04,0:27:27.53,Default,,0000,0000,0000,,is also getting an end of life in February Dialogue: 0,0:27:27.53,0:27:32.38,Default,,0000,0000,0000,,2015, which is coming up relatively quickly.\NIt's a Dialogue: 0,0:27:32.38,0:27:34.01,Default,,0000,0000,0000,,little less than a year away now, at this Dialogue: 0,0:27:34.01,0:27:38.56,Default,,0000,0000,0000,,point. So, please upgrade to at least 2.0.0\Nor Dialogue: 0,0:27:38.56,0:27:40.13,Default,,0000,0000,0000,,later. Dialogue: 0,0:27:40.13,0:27:43.88,Default,,0000,0000,0000,,And, during this past Rails Standard Year,\Nwe also Dialogue: 0,0:27:43.88,0:27:46.20,Default,,0000,0000,0000,,moved the default Ruby on Heroku from 1.9.2\Nto Dialogue: 0,0:27:46.20,0:27:49.71,Default,,0000,0000,0000,,2 dot 0 dot 0. We believe people should Dialogue: 0,0:27:49.71,0:27:52.47,Default,,0000,0000,0000,,be at least using this version of Ruby or Dialogue: 0,0:27:52.47,0:27:53.56,Default,,0000,0000,0000,,higher. Dialogue: 0,0:27:53.56,0:27:56.53,Default,,0000,0000,0000,,And, if you don't know yet, you can declare Dialogue: 0,0:27:56.53,0:27:59.79,Default,,0000,0000,0000,,your Ruby version in the gemfile on Heroku\Nto Dialogue: 0,0:27:59.79,0:28:05.48,Default,,0000,0000,0000,,get that version. And, we've also are pretty,\Npretty Dialogue: 0,0:28:05.48,0:28:08.74,Default,,0000,0000,0000,,serious about supporting the latest versions\Nof Ruby. Basically, Dialogue: 0,0:28:08.74,0:28:10.32,Default,,0000,0000,0000,,the same day that they come out. So we Dialogue: 0,0:28:10.32,0:28:15.46,Default,,0000,0000,0000,,did this for 2.0.0, 2.1.0 and 2.1.1, and in Dialogue: 0,0:28:15.46,0:28:17.88,Default,,0000,0000,0000,,addition we also try to support any of the Dialogue: 0,0:28:17.88,0:28:21.86,Default,,0000,0000,0000,,preview releases as, whenever they get form\Nrelease, so Dialogue: 0,0:28:21.86,0:28:25.41,Default,,0000,0000,0000,,we can, as a community, help, help find bugs Dialogue: 0,0:28:25.41,0:28:27.88,Default,,0000,0000,0000,,and test things like, put your staging app\Non Dialogue: 0,0:28:27.88,0:28:30.87,Default,,0000,0000,0000,,new versions of Ruby. If you find bugs then, Dialogue: 0,0:28:30.87,0:28:32.90,Default,,0000,0000,0000,,hopefully, we can fix them before they actually\Nmake Dialogue: 0,0:28:32.90,0:28:35.72,Default,,0000,0000,0000,,it to the final release. Dialogue: 0,0:28:35.72,0:28:39.85,Default,,0000,0000,0000,,And, with regards to security patches, if\Nthere are Dialogue: 0,0:28:39.85,0:28:41.99,Default,,0000,0000,0000,,any security releases that come out, we make\Nsure Dialogue: 0,0:28:41.99,0:28:44.85,Default,,0000,0000,0000,,to release them that day as well. We take Dialogue: 0,0:28:44.85,0:28:47.28,Default,,0000,0000,0000,,security pretty seriously. Dialogue: 0,0:28:47.28,0:28:50.54,Default,,0000,0000,0000,,So, once a security patch has release and\Nwe've Dialogue: 0,0:28:50.54,0:28:54.39,Default,,0000,0000,0000,,patched those Rubies, you have to push your\Napp Dialogue: 0,0:28:54.39,0:28:57.42,Default,,0000,0000,0000,,again to get that release. And the reason\Nwe, Dialogue: 0,0:28:57.42,0:28:58.89,Default,,0000,0000,0000,,well, a lot of people ask us, like, why Dialogue: 0,0:28:58.89,0:29:01.71,Default,,0000,0000,0000,,we don't do that. Why we don't just automatically Dialogue: 0,0:29:01.71,0:29:04.64,Default,,0000,0000,0000,,upgrade peoples' Rubies in place. And the\Nreason it, Dialogue: 0,0:29:04.64,0:29:07.90,Default,,0000,0000,0000,,the reasoning here is that, not, there might\Nbe Dialogue: 0,0:29:07.90,0:29:09.79,Default,,0000,0000,0000,,a regression to the security patch, or maybe\Nthe Dialogue: 0,0:29:09.79,0:29:13.36,Default,,0000,0000,0000,,patch level is not 100% backwards compatible.\NThere's a Dialogue: 0,0:29:13.36,0:29:16.19,Default,,0000,0000,0000,,bug that slipped through. But you probably\Nwant to Dialogue: 0,0:29:16.19,0:29:18.81,Default,,0000,0000,0000,,be there when you're actually deploying your\Napplication, in Dialogue: 0,0:29:18.81,0:29:20.79,Default,,0000,0000,0000,,case something does go wrong. Dialogue: 0,0:29:20.79,0:29:22.74,Default,,0000,0000,0000,,You probably wouldn't want us to deploy something\Nand Dialogue: 0,0:29:22.74,0:29:25.27,Default,,0000,0000,0000,,then have your site go down and then you're Dialogue: 0,0:29:25.27,0:29:27.29,Default,,0000,0000,0000,,like, not at your computer at all. You're\Nat Dialogue: 0,0:29:27.29,0:29:29.35,Default,,0000,0000,0000,,dinner somewhere and it's like super inconvenient\Nto get Dialogue: 0,0:29:29.35,0:29:30.87,Default,,0000,0000,0000,,paged there. Dialogue: 0,0:29:30.87,0:29:34.80,Default,,0000,0000,0000,,So, we publish all of this information, all\Nof Dialogue: 0,0:29:34.80,0:29:37.42,Default,,0000,0000,0000,,the updates to the platform, but also all\Nof Dialogue: 0,0:29:37.42,0:29:41.23,Default,,0000,0000,0000,,the Ruby updates, including security updates\Nto the devcenter Dialogue: 0,0:29:41.23,0:29:45.15,Default,,0000,0000,0000,,changelogs. So, if you don't, this is, I think, Dialogue: 0,0:29:45.15,0:29:48.36,Default,,0000,0000,0000,,devcenter dot heroku dot com slash changelog.\NAnd if Dialogue: 0,0:29:48.36,0:29:51.49,Default,,0000,0000,0000,,you don't subscribe to it, I would recommend\Nsubscribing Dialogue: 0,0:29:51.49,0:29:53.86,Default,,0000,0000,0000,,to it just to keep up to date with Dialogue: 0,0:29:53.86,0:29:57.01,Default,,0000,0000,0000,,what is happening on Heroku for platform changes\Nin Dialogue: 0,0:29:57.01,0:30:02.51,Default,,0000,0000,0000,,addition to updates to Ruby specifically on\NHeroku. And, Dialogue: 0,0:30:02.51,0:30:04.71,Default,,0000,0000,0000,,there isn't too much traffic. Like, you won't\Nget, Dialogue: 0,0:30:04.71,0:30:07.38,Default,,0000,0000,0000,,like, a hundred emails a day. So, I highly Dialogue: 0,0:30:07.38,0:30:09.94,Default,,0000,0000,0000,,recommend subscribing to this to just keep\Nup to Dialogue: 0,0:30:09.94,0:30:14.09,Default,,0000,0000,0000,,date with things like that here. Dialogue: 0,0:30:14.09,0:30:15.11,Default,,0000,0000,0000,,So the next thing I would like to talk Dialogue: 0,0:30:15.11,0:30:18.59,Default,,0000,0000,0000,,about is Matz's Ruby team. So if you didn't Dialogue: 0,0:30:18.59,0:30:22.12,Default,,0000,0000,0000,,know, back in 2012 we hired three people from Dialogue: 0,0:30:22.12,0:30:27.41,Default,,0000,0000,0000,,Ruby core. We hired Matz himself, Koichi and\NNobu. Dialogue: 0,0:30:27.41,0:30:29.85,Default,,0000,0000,0000,,And, as I've gone around over the last years Dialogue: 0,0:30:29.85,0:30:32.31,Default,,0000,0000,0000,,talking and interacting with people, I realize\Na lot Dialogue: 0,0:30:32.31,0:30:35.60,Default,,0000,0000,0000,,of people have no idea who, besides Matz,\Nwho Dialogue: 0,0:30:35.60,0:30:37.13,Default,,0000,0000,0000,,Koichi and Nobu are. Dialogue: 0,0:30:37.13,0:30:38.40,Default,,0000,0000,0000,,So I wanted to take the time to kind Dialogue: 0,0:30:38.40,0:30:42.10,Default,,0000,0000,0000,,of update people on who these people were\Nand Dialogue: 0,0:30:42.10,0:30:44.20,Default,,0000,0000,0000,,kind of what they've actually, like, we've\Nbeen paying Dialogue: 0,0:30:44.20,0:30:46.70,Default,,0000,0000,0000,,them money, and what they've actually been\Ndoing to Dialogue: 0,0:30:46.70,0:30:50.71,Default,,0000,0000,0000,,kind of move Ruby forward in a positive direction. Dialogue: 0,0:30:50.71,0:30:54.82,Default,,0000,0000,0000,,So, if you run a git log, since 2012, Dialogue: 0,0:30:54.82,0:30:56.97,Default,,0000,0000,0000,,since we've hired them, you can see the number Dialogue: 0,0:30:56.97,0:31:01.72,Default,,0000,0000,0000,,of commits they've made to Ruby itself. So,\Nthe, Dialogue: 0,0:31:01.72,0:31:05.20,Default,,0000,0000,0000,,so Nobu here, who we've hired, has basically\Nmore Dialogue: 0,0:31:05.20,0:31:07.97,Default,,0000,0000,0000,,commits than like the second guy by many,\Nmany Dialogue: 0,0:31:07.97,0:31:13.61,Default,,0000,0000,0000,,commits. And then, Koichi's the third highest\Ncommitter as Dialogue: 0,0:31:13.61,0:31:15.68,Default,,0000,0000,0000,,well. Dialogue: 0,0:31:15.68,0:31:17.56,Default,,0000,0000,0000,,And you're probably wondering why I have six\Nnames Dialogue: 0,0:31:17.56,0:31:21.26,Default,,0000,0000,0000,,here on a list for the top five. And Dialogue: 0,0:31:21.26,0:31:23.41,Default,,0000,0000,0000,,so there is this, so there isn't actually\Non Dialogue: 0,0:31:23.41,0:31:25.65,Default,,0000,0000,0000,,the Ruby Core Team who has the handle svn. Dialogue: 0,0:31:25.65,0:31:28.59,Default,,0000,0000,0000,,It's not actually a person. So I find out, Dialogue: 0,0:31:28.59,0:31:32.87,Default,,0000,0000,0000,,the hard way, who this person was. So when Dialogue: 0,0:31:32.87,0:31:35.48,Default,,0000,0000,0000,,I made my first patch to Ruby after being Dialogue: 0,0:31:35.48,0:31:40.04,Default,,0000,0000,0000,,on core, I found out that if, all the Dialogue: 0,0:31:40.04,0:31:43.16,Default,,0000,0000,0000,,date information is done in JST, and I, of Dialogue: 0,0:31:43.16,0:31:45.84,Default,,0000,0000,0000,,course, did not know that, and but like scumbag Dialogue: 0,0:31:45.84,0:31:48.61,Default,,0000,0000,0000,,American dates. And so there's basically this\Nbot that Dialogue: 0,0:31:48.61,0:31:51.33,Default,,0000,0000,0000,,will go through and, like, fix your commits\Nfor Dialogue: 0,0:31:51.33,0:31:53.76,Default,,0000,0000,0000,,you, and like, so he does like another commit, Dialogue: 0,0:31:53.76,0:31:55.75,Default,,0000,0000,0000,,and it's like, ah, you actually put the wrong Dialogue: 0,0:31:55.75,0:31:57.36,Default,,0000,0000,0000,,date. Let me fix that for you. Dialogue: 0,0:31:57.36,0:32:00.12,Default,,0000,0000,0000,,So there's like 710 of those commits. I think Dialogue: 0,0:32:00.12,0:32:02.68,Default,,0000,0000,0000,,I did this like a month ago. So these Dialogue: 0,0:32:02.68,0:32:05.88,Default,,0000,0000,0000,,are the number of commits from a month ago. Dialogue: 0,0:32:05.88,0:32:07.63,Default,,0000,0000,0000,,So, the first person I like to talk about Dialogue: 0,0:32:07.63,0:32:13.20,Default,,0000,0000,0000,,is Nobuyoshi Nokada. Also known as Nobu. And\Nhe's Dialogue: 0,0:32:13.20,0:32:15.43,Default,,0000,0000,0000,,known, I think on Ruby Core as The Patch Dialogue: 0,0:32:15.43,0:32:21.63,Default,,0000,0000,0000,,Monster. So, we'll go into why he's known\Nby Dialogue: 0,0:32:21.63,0:32:22.32,Default,,0000,0000,0000,,this. Dialogue: 0,0:32:22.32,0:32:25.54,Default,,0000,0000,0000,,So, what do you think the result of Time Dialogue: 0,0:32:25.54,0:32:30.51,Default,,0000,0000,0000,,dot now equals empty string? I'm sure you\Nthought Dialogue: 0,0:32:30.51,0:32:35.79,Default,,0000,0000,0000,,it was an infinite loop, right. Or using the Dialogue: 0,0:32:35.79,0:32:40.46,Default,,0000,0000,0000,,rational, like, so if you're using the rational\Nnumber Dialogue: 0,0:32:40.46,0:32:42.44,Default,,0000,0000,0000,,library in standard lib, like, what do you\Nthink Dialogue: 0,0:32:42.44,0:32:44.99,Default,,0000,0000,0000,,the result of doing this operation? Dialogue: 0,0:32:44.99,0:32:45.81,Default,,0000,0000,0000,,AUDIENCE: Segfault. Dialogue: 0,0:32:45.81,0:32:48.26,Default,,0000,0000,0000,,T.L.: Yeah. So this is a segfault. Dialogue: 0,0:32:48.26,0:32:50.09,Default,,0000,0000,0000,,AUDIENCE: [indecipherable - 00:32:40] Dialogue: 0,0:32:50.09,0:32:54.76,Default,,0000,0000,0000,,T.L.: Thank you. Thank you for reporting the\Nbug. Dialogue: 0,0:32:54.76,0:32:57.23,Default,,0000,0000,0000,,So these, so Eric Hodel actually reported\Nthe other Dialogue: 0,0:32:57.23,0:32:59.35,Default,,0000,0000,0000,,bug, the time thing, and he found this in Dialogue: 0,0:32:59.35,0:33:02.05,Default,,0000,0000,0000,,RubyGems I believe. But these are real issues\Nthat Dialogue: 0,0:33:02.05,0:33:04.94,Default,,0000,0000,0000,,are in Ruby itself. So if you actually run Dialogue: 0,0:33:04.94,0:33:06.99,Default,,0000,0000,0000,,those two things now and you're using later\Npatch Dialogue: 0,0:33:06.99,0:33:10.20,Default,,0000,0000,0000,,levels, you should not see them. But, they're\Nreal Dialogue: 0,0:33:10.20,0:33:14.19,Default,,0000,0000,0000,,issues, and someone has to go and fix all Dialogue: 0,0:33:14.19,0:33:14.96,Default,,0000,0000,0000,,them. Dialogue: 0,0:33:14.96,0:33:17.76,Default,,0000,0000,0000,,And so the person who actually does this is Dialogue: 0,0:33:17.76,0:33:22.16,Default,,0000,0000,0000,,Nobu. And he actually gets paid full time\Nand, Dialogue: 0,0:33:22.16,0:33:25.04,Default,,0000,0000,0000,,to basically do bug fixes for Ruby. So all Dialogue: 0,0:33:25.04,0:33:27.33,Default,,0000,0000,0000,,those two thousand seven hundred and some\Ncommits are Dialogue: 0,0:33:27.33,0:33:30.22,Default,,0000,0000,0000,,bug fixes to Ruby trunk to make Ruby run Dialogue: 0,0:33:30.22,0:33:34.37,Default,,0000,0000,0000,,better. And, I thanked him when I was just Dialogue: 0,0:33:34.37,0:33:36.66,Default,,0000,0000,0000,,in Japan last week for all the work he's Dialogue: 0,0:33:36.66,0:33:39.73,Default,,0000,0000,0000,,done. It's pretty incredible. Like, there's\Nso many times Dialogue: 0,0:33:39.73,0:33:42.27,Default,,0000,0000,0000,,when things segfault and other things, and\Nhe's basically Dialogue: 0,0:33:42.27,0:33:44.11,Default,,0000,0000,0000,,made it better. Dialogue: 0,0:33:44.11,0:33:46.28,Default,,0000,0000,0000,,I was at Oweito, and there was actually someone Dialogue: 0,0:33:46.28,0:33:49.05,Default,,0000,0000,0000,,giving a presentation about, like, thirty\Ntips of, like, Dialogue: 0,0:33:49.05,0:33:51.57,Default,,0000,0000,0000,,how to use Ruby. And someone was talking about Dialogue: 0,0:33:51.57,0:33:55.18,Default,,0000,0000,0000,,open uri, and there was code on the screen, Dialogue: 0,0:33:55.18,0:33:57.77,Default,,0000,0000,0000,,and he found a bug during, like, the guy's Dialogue: 0,0:33:57.77,0:34:00.19,Default,,0000,0000,0000,,presentation, and during it, he committed\Na patch to Dialogue: 0,0:34:00.19,0:34:04.50,Default,,0000,0000,0000,,trunk during that guy's presentation. So,\Nhe's pretty awesome. Dialogue: 0,0:34:04.50,0:34:07.81,Default,,0000,0000,0000,,He doesn't, he doesn't do, he hasn't done\Nany Dialogue: 0,0:34:07.81,0:34:09.95,Default,,0000,0000,0000,,talks, but I think people should know about\Nthe Dialogue: 0,0:34:09.95,0:34:11.62,Default,,0000,0000,0000,,work he's been doing. Dialogue: 0,0:34:11.62,0:34:14.59,Default,,0000,0000,0000,,So, this last bug, actually, that I wanted\Nto Dialogue: 0,0:34:14.59,0:34:16.98,Default,,0000,0000,0000,,talk about, that he fixed was, are any of Dialogue: 0,0:34:16.98,0:34:20.29,Default,,0000,0000,0000,,you familiar with the regression from, in\NRuby 2.1.1, Dialogue: 0,0:34:20.29,0:34:23.48,Default,,0000,0000,0000,,which regards to hash? Dialogue: 0,0:34:23.48,0:34:26.59,Default,,0000,0000,0000,,So, I'm sure you're familiar with the fact\Nthat, Dialogue: 0,0:34:26.59,0:34:29.47,Default,,0000,0000,0000,,if you use Ruby 2.1.1 on Rails 4.0.3, it Dialogue: 0,0:34:29.47,0:34:35.01,Default,,0000,0000,0000,,just doesn't work. Like, there, in Rails,\Nwe, we Dialogue: 0,0:34:35.01,0:34:38.87,Default,,0000,0000,0000,,use this, we fetch, in hashes we use objects Dialogue: 0,0:34:38.87,0:34:41.48,Default,,0000,0000,0000,,as keys. And if you override the hash and Dialogue: 0,0:34:41.48,0:34:44.15,Default,,0000,0000,0000,,equal method, and when you fetch you won't\Nget Dialogue: 0,0:34:44.15,0:34:48.06,Default,,0000,0000,0000,,the right result back. So inside of Rails\Nin Dialogue: 0,0:34:48.06,0:34:50.74,Default,,0000,0000,0000,,4.0.4, they actually had to work around this\Nbug. Dialogue: 0,0:34:50.74,0:34:53.14,Default,,0000,0000,0000,,And, Nobu actually was the one who fixed this Dialogue: 0,0:34:53.14,0:34:55.37,Default,,0000,0000,0000,,inside of Ruby itself. Dialogue: 0,0:34:55.37,0:34:58.98,Default,,0000,0000,0000,,So, these were just, like, the three most\Ninteresting Dialogue: 0,0:34:58.98,0:35:01.72,Default,,0000,0000,0000,,bugs that I found from within the last year Dialogue: 0,0:35:01.72,0:35:05.05,Default,,0000,0000,0000,,or two of stuff he's worked on. But, if Dialogue: 0,0:35:05.05,0:35:07.72,Default,,0000,0000,0000,,you look on site Ruby Core, you can find, Dialogue: 0,0:35:07.72,0:35:09.86,Default,,0000,0000,0000,,like, hundreds and hundreds of bugs that he's\Ndone Dialogue: 0,0:35:09.86,0:35:12.96,Default,,0000,0000,0000,,within the last year of, just like, rip segfaults Dialogue: 0,0:35:12.96,0:35:16.75,Default,,0000,0000,0000,,and other things. So he's great to work with. Dialogue: 0,0:35:16.75,0:35:19.45,Default,,0000,0000,0000,,So the next person I want to talk about Dialogue: 0,0:35:19.45,0:35:26.45,Default,,0000,0000,0000,,is Koichi Sasada. He's also known as ko1,\Nko1. Dialogue: 0,0:35:26.80,0:35:30.23,Default,,0000,0000,0000,,And he doesn't have a nickname in Ruby Core, Dialogue: 0,0:35:30.23,0:35:32.56,Default,,0000,0000,0000,,so me and Richard spent a good amount of Dialogue: 0,0:35:32.56,0:35:34.90,Default,,0000,0000,0000,,our talk preparation trying to come up with\Na Dialogue: 0,0:35:34.90,0:35:36.68,Default,,0000,0000,0000,,nickname for him. So we came up with the Dialogue: 0,0:35:36.68,0:35:39.24,Default,,0000,0000,0000,,Performance Pro. And this is a picture of\Nhim Dialogue: 0,0:35:39.24,0:35:42.65,Default,,0000,0000,0000,,giving a talk in Japanese. Dialogue: 0,0:35:42.65,0:35:47.59,Default,,0000,0000,0000,,So, if you use Ruby 1.9 at all, he Dialogue: 0,0:35:47.59,0:35:52.85,Default,,0000,0000,0000,,worked on Yarv. So basically the new VM stuff Dialogue: 0,0:35:52.85,0:35:55.60,Default,,0000,0000,0000,,that made Ruby 1.9, I think it was like Dialogue: 0,0:35:55.60,0:35:59.86,Default,,0000,0000,0000,,thirty percent faster than 1.8 for like longer-running\Nprocesses. Dialogue: 0,0:35:59.86,0:36:04.83,Default,,0000,0000,0000,,More recently he's worked on the RGenGC. And\Nthis Dialogue: 0,0:36:04.83,0:36:08.40,Default,,0000,0000,0000,,was introduced in Ruby 2.1.1, and it allows\Nfaster Dialogue: 0,0:36:08.40,0:36:13.26,Default,,0000,0000,0000,,code execution by having, basically, shorter\NGC pauses. So Dialogue: 0,0:36:13.26,0:36:15.36,Default,,0000,0000,0000,,instead of doing full GC every time, like,\Nyou Dialogue: 0,0:36:15.36,0:36:17.69,Default,,0000,0000,0000,,can have these minor ones. Dialogue: 0,0:36:17.69,0:36:22.11,Default,,0000,0000,0000,,So, just, he spends all of his time thinking Dialogue: 0,0:36:22.11,0:36:25.03,Default,,0000,0000,0000,,about performance in Ruby, and that's like\Nwhat he's Dialogue: 0,0:36:25.03,0:36:28.64,Default,,0000,0000,0000,,paid to work on. So if anyone actually cares Dialogue: 0,0:36:28.64,0:36:31.65,Default,,0000,0000,0000,,about Ruby performance, you should thank this\Nguy for Dialogue: 0,0:36:31.65,0:36:33.63,Default,,0000,0000,0000,,the work he's done. If you've looked at the Dialogue: 0,0:36:33.63,0:36:37.03,Default,,0000,0000,0000,,performance of Ruby since, in the last few\Nyears, Dialogue: 0,0:36:37.03,0:36:39.96,Default,,0000,0000,0000,,like it's improved a lot. A lot due to Dialogue: 0,0:36:39.96,0:36:41.48,Default,,0000,0000,0000,,this guy's work. Dialogue: 0,0:36:41.48,0:36:43.78,Default,,0000,0000,0000,,And, I was just, I was talking to him, Dialogue: 0,0:36:43.78,0:36:46.98,Default,,0000,0000,0000,,and he was telling me that he basically, like, Dialogue: 0,0:36:46.98,0:36:49.00,Default,,0000,0000,0000,,when he was working on RGenGC, he like, he Dialogue: 0,0:36:49.00,0:36:51.20,Default,,0000,0000,0000,,was just like, walking around the park and\Nhe Dialogue: 0,0:36:51.20,0:36:53.11,Default,,0000,0000,0000,,had a breakthrough. So he like spends a lot Dialogue: 0,0:36:53.11,0:36:55.58,Default,,0000,0000,0000,,of his time, even, off of work hours, just Dialogue: 0,0:36:55.58,0:36:58.53,Default,,0000,0000,0000,,thinking about this stuff. Dialogue: 0,0:36:58.53,0:37:00.07,Default,,0000,0000,0000,,Other stuff that he's been working on as well Dialogue: 0,0:37:00.07,0:37:04.50,Default,,0000,0000,0000,,is profiling work. So, if you've used any\Nof Dialogue: 0,0:37:04.50,0:37:09.33,Default,,0000,0000,0000,,the Man stuff for 2.1.1, with the MemProfiler\Nand Dialogue: 0,0:37:09.33,0:37:12.11,Default,,0000,0000,0000,,other things, he's been working on, with him\Nto Dialogue: 0,0:37:12.11,0:37:14.93,Default,,0000,0000,0000,,introduce hooks into the internal API to make\Nstuff Dialogue: 0,0:37:14.93,0:37:17.83,Default,,0000,0000,0000,,like that work. So we, I think we understand Dialogue: 0,0:37:17.83,0:37:20.42,Default,,0000,0000,0000,,that profiling, being able to measure your\Napplication for Dialogue: 0,0:37:20.42,0:37:25.10,Default,,0000,0000,0000,,Ruby is super important. So, if you have basically Dialogue: 0,0:37:25.10,0:37:29.10,Default,,0000,0000,0000,,comments or suggestions on things that you\Nneed or Dialogue: 0,0:37:29.10,0:37:31.32,Default,,0000,0000,0000,,think that you can't improve this thing, like\Nit's Dialogue: 0,0:37:31.32,0:37:34.09,Default,,0000,0000,0000,,worth talking, reaching out and talking to\NKoichi about Dialogue: 0,0:37:34.09,0:37:35.15,Default,,0000,0000,0000,,this. Dialogue: 0,0:37:35.15,0:37:37.18,Default,,0000,0000,0000,,And some of the stuff he's been working on Dialogue: 0,0:37:37.18,0:37:40.98,Default,,0000,0000,0000,,in this vein has been, like, the gc_tracer\Ngem. Dialogue: 0,0:37:40.98,0:37:44.39,Default,,0000,0000,0000,,So, using this to basically get more information\Nabout Dialogue: 0,0:37:44.39,0:37:47.80,Default,,0000,0000,0000,,your garbage collector, an allocation_tracer\Ngem to see how Dialogue: 0,0:37:47.80,0:37:51.38,Default,,0000,0000,0000,,long live, like, objects are. And then even\Nin Dialogue: 0,0:37:51.38,0:37:54.55,Default,,0000,0000,0000,,2.2, we're, as a team, we're working on, there Dialogue: 0,0:37:54.55,0:37:58.52,Default,,0000,0000,0000,,is an incremental GC patch, and then also.\NOr, Dialogue: 0,0:37:58.52,0:38:01.06,Default,,0000,0000,0000,,he's working on making the GC better with\Nincremental Dialogue: 0,0:38:01.06,0:38:03.96,Default,,0000,0000,0000,,GC and there is symbol GC for security things, Dialogue: 0,0:38:03.96,0:38:07.13,Default,,0000,0000,0000,,which'll be super good for Rails. So we can't Dialogue: 0,0:38:07.13,0:38:09.53,Default,,0000,0000,0000,,get, like, DOS because of the symbol table\Nbeing Dialogue: 0,0:38:09.53,0:38:11.22,Default,,0000,0000,0000,,filled up. Dialogue: 0,0:38:11.22,0:38:14.24,Default,,0000,0000,0000,,Another, so one of the things, when I was Dialogue: 0,0:38:14.24,0:38:15.96,Default,,0000,0000,0000,,in Japan, we had a Ruby Core meeting, and Dialogue: 0,0:38:15.96,0:38:20.15,Default,,0000,0000,0000,,we talked about Ruby releases. And releasing\NRuby is Dialogue: 0,0:38:20.15,0:38:23.99,Default,,0000,0000,0000,,kind of a slow process, and I was, I Dialogue: 0,0:38:23.99,0:38:26.78,Default,,0000,0000,0000,,wasn't really sure why it took so long. And Dialogue: 0,0:38:26.78,0:38:29.77,Default,,0000,0000,0000,,so I kind of asked the question, and, and Dialogue: 0,0:38:29.77,0:38:34.98,Default,,0000,0000,0000,,Naruse, who's the release manager of 2.1 and\Nwas Dialogue: 0,0:38:34.98,0:38:38.00,Default,,0000,0000,0000,,telling me that it requires lots of human\Nand Dialogue: 0,0:38:38.00,0:38:41.15,Default,,0000,0000,0000,,machine resources. Basically, Ruby has to\Nwork on many Dialogue: 0,0:38:41.15,0:38:45.67,Default,,0000,0000,0000,,configurations, Linux distros, you know, on\NOS X and Dialogue: 0,0:38:45.67,0:38:48.07,Default,,0000,0000,0000,,other things. And in order to release, like,\Nthe Dialogue: 0,0:38:48.07,0:38:50.04,Default,,0000,0000,0000,,CI server has to pass and, like, you kind Dialogue: 0,0:38:50.04,0:38:52.84,Default,,0000,0000,0000,,of have to pass on like various vendors and Dialogue: 0,0:38:52.84,0:38:54.12,Default,,0000,0000,0000,,what not. And so like, there's a lot of Dialogue: 0,0:38:54.12,0:38:58.85,Default,,0000,0000,0000,,coordination and like checking to like make\Nan actual Dialogue: 0,0:38:58.85,0:39:01.55,Default,,0000,0000,0000,,release happen. Which is why things don't\Nrelease super Dialogue: 0,0:39:01.55,0:39:02.46,Default,,0000,0000,0000,,fast. Dialogue: 0,0:39:02.46,0:39:06.61,Default,,0000,0000,0000,,So, some of the stuff that Koichi and my Dialogue: 0,0:39:06.61,0:39:08.11,Default,,0000,0000,0000,,team and other people on Ruby Core have been Dialogue: 0,0:39:08.11,0:39:10.55,Default,,0000,0000,0000,,working on is, like, working on infrastructure\Nand services Dialogue: 0,0:39:10.55,0:39:13.97,Default,,0000,0000,0000,,to help with, basically, testing of Ruby,\Nto kind Dialogue: 0,0:39:13.97,0:39:16.88,Default,,0000,0000,0000,,of hopefully automate and, like, basically\Ndo that per, Dialogue: 0,0:39:16.88,0:39:19.86,Default,,0000,0000,0000,,either nightly or per commit or something\Nalong those Dialogue: 0,0:39:19.86,0:39:20.20,Default,,0000,0000,0000,,lines. Dialogue: 0,0:39:20.20,0:39:22.78,Default,,0000,0000,0000,,So hopefully we can get releases that are\Nfaster Dialogue: 0,0:39:22.78,0:39:26.72,Default,,0000,0000,0000,,and are out to users sooner. Dialogue: 0,0:39:26.72,0:39:29.69,Default,,0000,0000,0000,,If you have ideas for Ruby 2.2, like, I Dialogue: 0,0:39:29.69,0:39:32.94,Default,,0000,0000,0000,,would love to hear them. We have a meeting Dialogue: 0,0:39:32.94,0:39:36.07,Default,,0000,0000,0000,,next month in May, about what is gonna go Dialogue: 0,0:39:36.07,0:39:39.49,Default,,0000,0000,0000,,into Ruby 2.2. So I'd be more than happy Dialogue: 0,0:39:39.49,0:39:42.38,Default,,0000,0000,0000,,to talk to you about ideas that you have Dialogue: 0,0:39:42.38,0:39:45.98,Default,,0000,0000,0000,,that you would like to see there. I'm just Dialogue: 0,0:39:45.98,0:39:47.62,Default,,0000,0000,0000,,gonna skip this stuff since I talked about\Nit Dialogue: 0,0:39:47.62,0:39:49.60,Default,,0000,0000,0000,,earlier, and we're running short on time.\NSo, here's Dialogue: 0,0:39:49.60,0:39:51.29,Default,,0000,0000,0000,,Scheems to actually talk about Rails. Dialogue: 0,0:39:51.29,0:39:52.46,Default,,0000,0000,0000,,R.S.: OK. Dialogue: 0,0:39:52.46,0:39:54.97,Default,,0000,0000,0000,,Has anybody used Rails? Have we covered that\Nquestion Dialogue: 0,0:39:54.97,0:39:59.90,Default,,0000,0000,0000,,yet? OK. Welcome to RailsConf. OK, so Rails\N4.1 Dialogue: 0,0:39:59.90,0:40:00.50,Default,,0000,0000,0000,,on Heroku. Dialogue: 0,0:40:00.50,0:40:03.13,Default,,0000,0000,0000,,A lot of things in a very short amount Dialogue: 0,0:40:03.13,0:40:05.42,Default,,0000,0000,0000,,of time. We are secure by default. Have you Dialogue: 0,0:40:05.42,0:40:08.67,Default,,0000,0000,0000,,heard of the secrets dot yml file? OK. So Dialogue: 0,0:40:08.67,0:40:10.36,Default,,0000,0000,0000,,secrets dot yml file is actually reading out\Nan Dialogue: 0,0:40:10.36,0:40:13.07,Default,,0000,0000,0000,,environment variable by default, which is\Ngreat. We love Dialogue: 0,0:40:13.07,0:40:17.82,Default,,0000,0000,0000,,environment variables. It separates your config\Nfrom your source. Dialogue: 0,0:40:17.82,0:40:20.79,Default,,0000,0000,0000,,And, so whenever you push your app, we're\Ngonna Dialogue: 0,0:40:20.79,0:40:22.77,Default,,0000,0000,0000,,set this environment variable to just, like,\Nliterally a Dialogue: 0,0:40:22.77,0:40:25.85,Default,,0000,0000,0000,,random value. And if, for some reason, you\Never Dialogue: 0,0:40:25.85,0:40:28.99,Default,,0000,0000,0000,,need to like change that, you can do so Dialogue: 0,0:40:28.99,0:40:32.86,Default,,0000,0000,0000,,by just setting your, the, the secret key\Nbase Dialogue: 0,0:40:32.86,0:40:35.26,Default,,0000,0000,0000,,environment variable to, to whatever you want. Dialogue: 0,0:40:35.26,0:40:37.45,Default,,0000,0000,0000,,Maybe, you know, like another OpenSSL bug\Ncomes out Dialogue: 0,0:40:37.45,0:40:42.15,Default,,0000,0000,0000,,or something. So, another thing that was worked\Non Dialogue: 0,0:40:42.15,0:40:45.65,Default,,0000,0000,0000,,a bunch is the database_url environment variable.\NThis is Dialogue: 0,0:40:45.65,0:40:47.30,Default,,0000,0000,0000,,something that we have spent a lot of time Dialogue: 0,0:40:47.30,0:40:49.38,Default,,0000,0000,0000,,looking at. And it's actually, support has\Nbeen in Dialogue: 0,0:40:49.38,0:40:52.01,Default,,0000,0000,0000,,Rails for a surprisingly large amount of time,\Nto Dialogue: 0,0:40:52.01,0:40:54.51,Default,,0000,0000,0000,,just read from the environment variable, but\Nnever quite Dialogue: 0,0:40:54.51,0:40:58.38,Default,,0000,0000,0000,,worked due to some edge cases and random rake Dialogue: 0,0:40:58.38,0:41:01.36,Default,,0000,0000,0000,,tasks and so on and so forth. So this, Dialogue: 0,0:41:01.36,0:41:03.56,Default,,0000,0000,0000,,this December, around Christmas time, I spent\Na lot Dialogue: 0,0:41:03.56,0:41:05.26,Default,,0000,0000,0000,,of time getting that to work. Dialogue: 0,0:41:05.26,0:41:08.91,Default,,0000,0000,0000,,So I'd like to happily announce that Rails\N4, Dialogue: 0,0:41:08.91,0:41:13.49,Default,,0000,0000,0000,,4.1 actually does support the database_url\Nenvironment variable out Dialogue: 0,0:41:13.49,0:41:18.10,Default,,0000,0000,0000,,of the box. Whoo! And, so, some, to describe Dialogue: 0,0:41:18.10,0:41:22.81,Default,,0000,0000,0000,,a little, like, the behavior is, bears going\Nover. Dialogue: 0,0:41:22.81,0:41:25.25,Default,,0000,0000,0000,,If the database_url is present, we're just\Ngonna connect Dialogue: 0,0:41:25.25,0:41:28.43,Default,,0000,0000,0000,,to that database. It's, that's pretty simple.\NMakes sense. Dialogue: 0,0:41:28.43,0:41:30.80,Default,,0000,0000,0000,,If the database.yml is present but there's\Nno environment Dialogue: 0,0:41:30.80,0:41:33.23,Default,,0000,0000,0000,,variable, then we're gonna use that. That\Nalso just Dialogue: 0,0:41:33.23,0:41:35.19,Default,,0000,0000,0000,,kind of makes sense. Dialogue: 0,0:41:35.19,0:41:37.37,Default,,0000,0000,0000,,If both are present, then we're gonna merge\Nthe Dialogue: 0,0:41:37.37,0:41:41.92,Default,,0000,0000,0000,,values. Makes sense, right? OK. Dialogue: 0,0:41:41.92,0:41:46.60,Default,,0000,0000,0000,,So, we, that sounds crazy. Bear with me. But, Dialogue: 0,0:41:46.60,0:41:48.37,Default,,0000,0000,0000,,a lot of people, you, you want to put Dialogue: 0,0:41:48.37,0:41:52.44,Default,,0000,0000,0000,,your connection information in your database_url\Nenvironment variable. But, Dialogue: 0,0:41:52.44,0:41:54.84,Default,,0000,0000,0000,,there's also other values you can use inside\Nof Dialogue: 0,0:41:54.84,0:41:58.86,Default,,0000,0000,0000,,your database.yml file to configure ActiveRecord\Nitself. Not your Dialogue: 0,0:41:58.86,0:42:00.99,Default,,0000,0000,0000,,database. So you can turn off and on prepared Dialogue: 0,0:42:00.99,0:42:03.23,Default,,0000,0000,0000,,statements. You can change your pool size.\NAll this Dialogue: 0,0:42:03.23,0:42:04.79,Default,,0000,0000,0000,,kind of thing. Dialogue: 0,0:42:04.79,0:42:07.42,Default,,0000,0000,0000,,And, we wanted to still enable you to be Dialogue: 0,0:42:07.42,0:42:10.30,Default,,0000,0000,0000,,able, able to do this. So the, the results Dialogue: 0,0:42:10.30,0:42:15.37,Default,,0000,0000,0000,,are actually merged, and for, for somebody\Nlike Heroku Dialogue: 0,0:42:15.37,0:42:19.31,Default,,0000,0000,0000,,or, like, if you're using another container,\Nwe don't Dialogue: 0,0:42:19.31,0:42:21.26,Default,,0000,0000,0000,,have to have as much magic. If you, if Dialogue: 0,0:42:21.26,0:42:24.46,Default,,0000,0000,0000,,you didn't know, database_url, we actually\Nhad to over, Dialogue: 0,0:42:24.46,0:42:26.49,Default,,0000,0000,0000,,whatever your database_url was, we were just\Nwriting a Dialogue: 0,0:42:26.49,0:42:28.85,Default,,0000,0000,0000,,file over top of it. And it's like, forget Dialogue: 0,0:42:28.85,0:42:30.11,Default,,0000,0000,0000,,that. We're gonna write a custom file. Dialogue: 0,0:42:30.11,0:42:32.58,Default,,0000,0000,0000,,So people would put stuff in their database_url,\Nor Dialogue: 0,0:42:32.58,0:42:34.87,Default,,0000,0000,0000,,their database.yml file, and they'd be surprised\Nwhen it Dialogue: 0,0:42:34.87,0:42:37.07,Default,,0000,0000,0000,,wasn't there. Like, a different file was there.\NSo, Dialogue: 0,0:42:37.07,0:42:39.39,Default,,0000,0000,0000,,we no longer, we no longer have to do Dialogue: 0,0:42:39.39,0:42:41.38,Default,,0000,0000,0000,,that. And Rails plays a little bit nicer with, Dialogue: 0,0:42:41.38,0:42:45.11,Default,,0000,0000,0000,,with this containerized style environment. Dialogue: 0,0:42:45.11,0:42:47.90,Default,,0000,0000,0000,,It also means that, you could actually start\Nputting Dialogue: 0,0:42:47.90,0:42:52.26,Default,,0000,0000,0000,,your ActiveRecord configuration in that file.\NAnother note, if Dialogue: 0,0:42:52.26,0:42:55.50,Default,,0000,0000,0000,,you were manually setting that, your pool\Nsize or Dialogue: 0,0:42:55.50,0:42:59.15,Default,,0000,0000,0000,,any of those things via a, after reading an Dialogue: 0,0:42:59.15,0:43:01.84,Default,,0000,0000,0000,,article on our devcenter, go back and revisit\Nthat Dialogue: 0,0:43:01.84,0:43:04.56,Default,,0000,0000,0000,,please, before upgrading to Rails 4.1. Some\Nof the Dialogue: 0,0:43:04.56,0:43:08.06,Default,,0000,0000,0000,,syntax did change between Rails 4.0 and 4.1.\NSo, Dialogue: 0,0:43:08.06,0:43:10.62,Default,,0000,0000,0000,,if you can't connect to a database, then maybe, Dialogue: 0,0:43:10.62,0:43:12.93,Default,,0000,0000,0000,,just like, email Schneemz and be like, I hate Dialogue: 0,0:43:12.93,0:43:14.46,Default,,0000,0000,0000,,you. What's the link to that thing? And I'll, Dialogue: 0,0:43:14.46,0:43:16.48,Default,,0000,0000,0000,,I'll help you out. Dialogue: 0,0:43:16.48,0:43:20.52,Default,,0000,0000,0000,,OK. I think, probably, actually, the last\Nthing that Dialogue: 0,0:43:20.52,0:43:25.11,Default,,0000,0000,0000,,we have time for, is asset pipeline. Who,\Nlike, Dialogue: 0,0:43:25.11,0:43:29.04,Default,,0000,0000,0000,,if asked in an interview, would say that their Dialogue: 0,0:43:29.04,0:43:31.51,Default,,0000,0000,0000,,favorite thing in the whole world is Rails\Nasset Dialogue: 0,0:43:31.51,0:43:35.46,Default,,0000,0000,0000,,pipeline? Oh. Oh. Dialogue: 0,0:43:35.46,0:43:37.21,Default,,0000,0000,0000,,AUDIENCE: Just Raphael. Dialogue: 0,0:43:37.21,0:43:38.88,Default,,0000,0000,0000,,R.S.: Just Raphael. We have a bunch of, like, Dialogue: 0,0:43:38.88,0:43:41.51,Default,,0000,0000,0000,,Rails Core here, by the way. So you should, Dialogue: 0,0:43:41.51,0:43:44.38,Default,,0000,0000,0000,,you should come and thank them afterwards.\NFor, for Dialogue: 0,0:43:44.38,0:43:46.26,Default,,0000,0000,0000,,other things. Not for the asset pipeline. Dialogue: 0,0:43:46.26,0:43:47.14,Default,,0000,0000,0000,,[laughter] Dialogue: 0,0:43:47.14,0:43:49.65,Default,,0000,0000,0000,,So, the asset pipeline is the number one source Dialogue: 0,0:43:49.65,0:43:52.86,Default,,0000,0000,0000,,of, of Ruby support tickets at Heroku. Just\Npeople Dialogue: 0,0:43:52.86,0:43:55.22,Default,,0000,0000,0000,,being like, hey, this worked locally, and\Nlike, didn't Dialogue: 0,0:43:55.22,0:43:58.02,Default,,0000,0000,0000,,work in production. And we're like, yeah,\Nthat's just Dialogue: 0,0:43:58.02,0:44:00.97,Default,,0000,0000,0000,,how asset pipeline works. That's not Heroku. Dialogue: 0,0:44:00.97,0:44:04.80,Default,,0000,0000,0000,,So, so Rails 4.1 added, added a couple things. Dialogue: 0,0:44:04.80,0:44:07.86,Default,,0000,0000,0000,,It's gonna warn you in development if you're\Ndoing Dialogue: 0,0:44:07.86,0:44:10.55,Default,,0000,0000,0000,,something that's gonna break production. Like,\Nif you've ever Dialogue: 0,0:44:10.55,0:44:13.53,Default,,0000,0000,0000,,forgotten to add something to your precompile\Nlist, well Dialogue: 0,0:44:13.53,0:44:16.60,Default,,0000,0000,0000,,now, guess what, you get an error. If you Dialogue: 0,0:44:16.60,0:44:19.62,Default,,0000,0000,0000,,are not properly declaring your asset dependencies,\Nthen you're Dialogue: 0,0:44:19.62,0:44:21.73,Default,,0000,0000,0000,,gonna get an error. Dialogue: 0,0:44:21.73,0:44:26.44,Default,,0000,0000,0000,,And this is even better, actually, in Rails\N4.2. Dialogue: 0,0:44:26.44,0:44:28.26,Default,,0000,0000,0000,,As some of these checks aren't even needed\Nanymore, Dialogue: 0,0:44:28.26,0:44:30.49,Default,,0000,0000,0000,,we can just automatically do them for you.\NBut, Dialogue: 0,0:44:30.49,0:44:34.22,Default,,0000,0000,0000,,unfortunately, those have, are not in Rails\N4.1 yet. Dialogue: 0,0:44:34.22,0:44:37.34,Default,,0000,0000,0000,,So, in general, I have a, a personal belief Dialogue: 0,0:44:37.34,0:44:40.20,Default,,0000,0000,0000,,that, in programming, or, really in life,\Nthe only Dialogue: 0,0:44:40.20,0:44:47.20,Default,,0000,0000,0000,,thing that should fail silently is. This.\NThis joke. Dialogue: 0,0:44:48.37,0:44:54.37,Default,,0000,0000,0000,,So. Thank you all very much for, for coming. Dialogue: 0,0:44:54.37,0:44:59.76,Default,,0000,0000,0000,,We, we have a booth, and later on, what. Dialogue: 0,0:44:59.76,0:45:00.99,Default,,0000,0000,0000,,What time, three o' clock? Dialogue: 0,0:45:00.99,0:45:02.02,Default,,0000,0000,0000,,T.L.: Between 3:00 and 4:30. Dialogue: 0,0:45:02.02,0:45:03.48,Default,,0000,0000,0000,,R.S.: Yeah. From 3:00 to 4:30, we'll actually\Nhave Dialogue: 0,0:45:03.48,0:45:09.51,Default,,0000,0000,0000,,a bunch of Rails contributors coming to, to\Ntalk Dialogue: 0,0:45:09.51,0:45:14.33,Default,,0000,0000,0000,,about. Oh yeah, the slides. Yeah. Yeah. Dialogue: 0,0:45:14.33,0:45:16.75,Default,,0000,0000,0000,,T.L.: Yeah. 3:00 to 4:30, we'll have community\Noffice Dialogue: 0,0:45:16.75,0:45:20.72,Default,,0000,0000,0000,,hours with some nice people from Rails Core,\Ncontrib. Dialogue: 0,0:45:20.72,0:45:22.87,Default,,0000,0000,0000,,R.S.: Yeah. So come ask. Dialogue: 0,0:45:22.87,0:45:26.59,Default,,0000,0000,0000,,T.L.: Basically any Rails questions or anything\Nyou want. Dialogue: 0,0:45:26.59,0:45:28.01,Default,,0000,0000,0000,,And then Schneeman will actually be doing\Na book Dialogue: 0,0:45:28.01,0:45:30.99,Default,,0000,0000,0000,,signing of his Heroku Up & Running book today Dialogue: 0,0:45:30.99,0:45:33.85,Default,,0000,0000,0000,,and tomorrow at 2:30. So if you want that. Dialogue: 0,0:45:33.85,0:45:36.01,Default,,0000,0000,0000,,R.S.: Yeah. So get a, get a free book, Dialogue: 0,0:45:36.01,0:45:38.16,Default,,0000,0000,0000,,and then come and ask questions and just,\Nlike, Dialogue: 0,0:45:38.16,0:45:41.58,Default,,0000,0000,0000,,hang out. And, any time you stop by the Dialogue: 0,0:45:41.58,0:45:44.16,Default,,0000,0000,0000,,booth, feel free to ask Heroku questions.\NAnd thank Dialogue: 0,0:45:44.16,0:45:45.88,Default,,0000,0000,0000,,you all very much for coming.