[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:18.64,0:00:20.26,Default,,0000,0000,0000,,ABHISHEK PILLAI: Thanks for coming. I know\Nthere's Dialogue: 0,0:00:20.26,0:00:22.80,Default,,0000,0000,0000,,some other cool talks right now, but you're\Nhere so Dialogue: 0,0:00:22.80,0:00:25.81,Default,,0000,0000,0000,,that's awesome. Let's get started. You're\Nhere to Dialogue: 0,0:00:25.81,0:00:28.94,Default,,0000,0000,0000,,learn about how to tame COBRAs. Dialogue: 0,0:00:28.94,0:00:33.96,Default,,0000,0000,0000,,JASON SISK: My name is Jason Sisk. I work Dialogue: 0,0:00:33.96,0:00:37.45,Default,,0000,0000,0000,,at Groupon. I've been here for a couple of Dialogue: 0,0:00:37.45,0:00:41.65,Default,,0000,0000,0000,,years. I work on predominantly Ruby/Rails\Nsystems, backend development, Dialogue: 0,0:00:41.65,0:00:44.46,Default,,0000,0000,0000,,et cetera, and I do not like onions. Dialogue: 0,0:00:44.46,0:00:47.63,Default,,0000,0000,0000,,A.P.: My name is Abi, and I'm at, I've Dialogue: 0,0:00:47.63,0:00:51.16,Default,,0000,0000,0000,,been at Groupon for about two years, too.\NAnd Dialogue: 0,0:00:51.16,0:00:52.63,Default,,0000,0000,0000,,Jason and I work on a team that does Dialogue: 0,0:00:52.63,0:00:58.27,Default,,0000,0000,0000,,backend service, basically managing inventory.\NAnd I don't like Dialogue: 0,0:00:58.27,0:00:58.84,Default,,0000,0000,0000,,fruits. Dialogue: 0,0:00:58.84,0:01:00.76,Default,,0000,0000,0000,,J.S.: So part of what we're gonna tell you Dialogue: 0,0:01:00.76,0:01:03.64,Default,,0000,0000,0000,,today is a little bit of a history lesson Dialogue: 0,0:01:03.64,0:01:06.55,Default,,0000,0000,0000,,about the early pain of Groupon having site\Noutages, Dialogue: 0,0:01:06.55,0:01:10.53,Default,,0000,0000,0000,,et cetera, due to Rails scaling. We want to Dialogue: 0,0:01:10.53,0:01:13.39,Default,,0000,0000,0000,,tell you about the story of the developers\Nthat Dialogue: 0,0:01:13.39,0:01:15.53,Default,,0000,0000,0000,,actually handled those problems and some of\Nthe decisions Dialogue: 0,0:01:15.53,0:01:19.81,Default,,0000,0000,0000,,that they made. So that's that. Dialogue: 0,0:01:19.81,0:01:22.73,Default,,0000,0000,0000,,But we want to lead off with one important Dialogue: 0,0:01:22.73,0:01:23.42,Default,,0000,0000,0000,,point. Dialogue: 0,0:01:23.42,0:01:29.68,Default,,0000,0000,0000,,A.P.: Boom! Pause. You don't have to pause\Nfor Dialogue: 0,0:01:29.68,0:01:32.46,Default,,0000,0000,0000,,that long. And, yeah. Dialogue: 0,0:01:32.46,0:01:37.10,Default,,0000,0000,0000,,J.S.: So. Back, back around 2007, we were\Ndoing Dialogue: 0,0:01:37.10,0:01:39.48,Default,,0000,0000,0000,,what all the other cool kids were doing. We Dialogue: 0,0:01:39.48,0:01:43.21,Default,,0000,0000,0000,,were using a Rails monolith, and to some degree Dialogue: 0,0:01:43.21,0:01:45.91,Default,,0000,0000,0000,,still are. Rails 2 is a great framework. Who Dialogue: 0,0:01:45.91,0:01:48.17,Default,,0000,0000,0000,,is using Rails 2? Anyone? Dialogue: 0,0:01:48.17,0:01:49.08,Default,,0000,0000,0000,,AUDIENCE: Yeah! Dialogue: 0,0:01:49.08,0:01:50.44,Default,,0000,0000,0000,,J.S.: All right. Dialogue: 0,0:01:50.44,0:01:51.34,Default,,0000,0000,0000,,A.P.: Awesome. Dialogue: 0,0:01:51.34,0:01:54.88,Default,,0000,0000,0000,,J.S.: You and us. Rails is a great framework. Dialogue: 0,0:01:54.88,0:01:57.92,Default,,0000,0000,0000,,We all love Rails. That's why we're here.\NWe Dialogue: 0,0:01:57.92,0:02:03.49,Default,,0000,0000,0000,,still love Rails and that's why we're here.\NBut Dialogue: 0,0:02:03.49,0:02:04.94,Default,,0000,0000,0000,,what's great about it is that it's great for Dialogue: 0,0:02:04.94,0:02:07.70,Default,,0000,0000,0000,,Agile teams. It's, and for us it was really Dialogue: 0,0:02:07.70,0:02:12.07,Default,,0000,0000,0000,,simple. We could make some really quick decisions.\NWe Dialogue: 0,0:02:12.07,0:02:15.95,Default,,0000,0000,0000,,could iterate product very quickly. We could\Niterate new Dialogue: 0,0:02:15.95,0:02:17.54,Default,,0000,0000,0000,,features. And we could do it with a small Dialogue: 0,0:02:17.54,0:02:19.89,Default,,0000,0000,0000,,team of five to ten devs. Dialogue: 0,0:02:19.89,0:02:23.16,Default,,0000,0000,0000,,We had a single repository. We had a single Dialogue: 0,0:02:23.16,0:02:25.19,Default,,0000,0000,0000,,test suite. And we had a single deploy process. Dialogue: 0,0:02:25.19,0:02:26.17,Default,,0000,0000,0000,,Very simple. Dialogue: 0,0:02:26.17,0:02:29.27,Default,,0000,0000,0000,,A.P.: And, most importantly, you, we had like\None Dialogue: 0,0:02:29.27,0:02:31.67,Default,,0000,0000,0000,,shared, conceptual understanding of the code\Nbase. When we Dialogue: 0,0:02:31.67,0:02:33.13,Default,,0000,0000,0000,,wanted to make a change, we knew where to Dialogue: 0,0:02:33.13,0:02:36.51,Default,,0000,0000,0000,,put it. And things were simple that way. Dialogue: 0,0:02:36.51,0:02:39.65,Default,,0000,0000,0000,,J.S.: Also what was great was, and still is, Dialogue: 0,0:02:39.65,0:02:44.26,Default,,0000,0000,0000,,about Rails, that integrating components is\Nreally easy. The Dialogue: 0,0:02:44.26,0:02:47.83,Default,,0000,0000,0000,,convention over configuration, model associations\N- all of that Dialogue: 0,0:02:47.83,0:02:50.11,Default,,0000,0000,0000,,business you can put together things very\Nquickly and Dialogue: 0,0:02:50.11,0:02:53.20,Default,,0000,0000,0000,,very easily. But we didn't come here to talk Dialogue: 0,0:02:53.20,0:02:55.42,Default,,0000,0000,0000,,to you about Rails. Dialogue: 0,0:02:55.42,0:02:58.86,Default,,0000,0000,0000,,A.P.: We came here to tell you about cobras, Dialogue: 0,0:02:58.86,0:03:02.53,Default,,0000,0000,0000,,and how to tame them. At Groupon, we actually Dialogue: 0,0:03:02.53,0:03:04.65,Default,,0000,0000,0000,,have a mo- monolith, and we call it the Dialogue: 0,0:03:04.65,0:03:07.50,Default,,0000,0000,0000,,primary web app. But Jason had a thought for Dialogue: 0,0:03:07.50,0:03:09.55,Default,,0000,0000,0000,,the purposes of this talk, we'd come up with Dialogue: 0,0:03:09.55,0:03:13.26,Default,,0000,0000,0000,,a more scientifically accurate name for it. Dialogue: 0,0:03:13.26,0:03:19.54,Default,,0000,0000,0000,,Yeah. So. Centralized Omnipotent Big-ass Rails\NApplication. Dialogue: 0,0:03:19.54,0:03:22.03,Default,,0000,0000,0000,,J.S.: Big-ass. So we want to take you back Dialogue: 0,0:03:22.03,0:03:26.91,Default,,0000,0000,0000,,to 2009 for just a minute. So Groupon was Dialogue: 0,0:03:26.91,0:03:28.78,Default,,0000,0000,0000,,about two years old, give or take, and we Dialogue: 0,0:03:28.78,0:03:31.30,Default,,0000,0000,0000,,were still kind of kicking into gear. People\Nwould Dialogue: 0,0:03:31.30,0:03:34.22,Default,,0000,0000,0000,,come into the office in Chicago we've got,\Nopen Dialogue: 0,0:03:34.22,0:03:36.75,Default,,0000,0000,0000,,up New Relic, and they'd see stuff like this. Dialogue: 0,0:03:36.75,0:03:38.71,Default,,0000,0000,0000,,A.P.: So as you can see, like, in the Dialogue: 0,0:03:38.71,0:03:41.63,Default,,0000,0000,0000,,middle of the night, it's great. Everything's\Nworking really Dialogue: 0,0:03:41.63,0:03:43.78,Default,,0000,0000,0000,,well. Soon as people woke up and started using Dialogue: 0,0:03:43.78,0:03:47.71,Default,,0000,0000,0000,,it - damn people - our performance immediately\Nstarted Dialogue: 0,0:03:47.71,0:03:52.15,Default,,0000,0000,0000,,to drop. Dialogue: 0,0:03:52.15,0:03:55.34,Default,,0000,0000,0000,,And then eight months later, we had about\Nthirty Dialogue: 0,0:03:55.34,0:04:00.32,Default,,0000,0000,0000,,thousand requests per minute and everything\Nwas on fire. Dialogue: 0,0:04:00.32,0:04:01.95,Default,,0000,0000,0000,,J.S.: We blame Oprah. Dialogue: 0,0:04:01.95,0:04:03.54,Default,,0000,0000,0000,,A.P.: As you do. Dialogue: 0,0:04:03.54,0:04:07.60,Default,,0000,0000,0000,,J.S.: It's Oprah's fault. Oprah crashed Groupon.\NOprah crashed Dialogue: 0,0:04:07.60,0:04:12.58,Default,,0000,0000,0000,,Groupon not once, but at least twice. And\Nalso Dialogue: 0,0:04:12.58,0:04:16.13,Default,,0000,0000,0000,,the Gap crashed Groupon too. Actually, the\Ntruth is, Dialogue: 0,0:04:16.13,0:04:20.27,Default,,0000,0000,0000,,Groupon crashed Groupon. We were not scaling\Nproperly. Bad. Dialogue: 0,0:04:20.27,0:04:22.44,Default,,0000,0000,0000,,Bad Groupon. Dialogue: 0,0:04:22.44,0:04:27.94,Default,,0000,0000,0000,,The Cobra was getting fatter and fatter. We\Nwere Dialogue: 0,0:04:27.94,0:04:29.24,Default,,0000,0000,0000,,up to- Dialogue: 0,0:04:29.24,0:04:33.78,Default,,0000,0000,0000,,A.P.: Yeah. So. We were up to, we started, Dialogue: 0,0:04:33.78,0:04:35.99,Default,,0000,0000,0000,,we had, like, five to fifty devs. We started Dialogue: 0,0:04:35.99,0:04:37.94,Default,,0000,0000,0000,,with about three to five hundred commits per\Nmonth. Dialogue: 0,0:04:37.94,0:04:40.23,Default,,0000,0000,0000,,Slowly, and in a couple of years, as you Dialogue: 0,0:04:40.23,0:04:42.91,Default,,0000,0000,0000,,can see, we were averaging about two thousand\Ncommits Dialogue: 0,0:04:42.91,0:04:45.14,Default,,0000,0000,0000,,in a single month. We had a lot of Dialogue: 0,0:04:45.14,0:04:46.69,Default,,0000,0000,0000,,developers developing a lot of things. Dialogue: 0,0:04:46.69,0:04:49.90,Default,,0000,0000,0000,,J.S.: This is all one cobra. Dialogue: 0,0:04:49.90,0:04:54.00,Default,,0000,0000,0000,,A.P.: And you know, we started thinking about\NSOA Dialogue: 0,0:04:54.00,0:04:57.20,Default,,0000,0000,0000,,at that point. It was already becoming really\Npainful. Dialogue: 0,0:04:57.20,0:05:01.43,Default,,0000,0000,0000,,But we looked at the cobra, directly in the Dialogue: 0,0:05:01.43,0:05:03.14,Default,,0000,0000,0000,,eyes, and it scared the shit out of us. Dialogue: 0,0:05:03.14,0:05:05.60,Default,,0000,0000,0000,,J.S.: We had a lot of scoping problems. And Dialogue: 0,0:05:05.60,0:05:09.77,Default,,0000,0000,0000,,a lot of that had to do with model Dialogue: 0,0:05:09.77,0:05:12.31,Default,,0000,0000,0000,,coupling. So, one of the biggest things that\Nwas Dialogue: 0,0:05:12.31,0:05:16.81,Default,,0000,0000,0000,,keeping us from extracting services early\Nwas as the, Dialogue: 0,0:05:16.81,0:05:18.86,Default,,0000,0000,0000,,as the code grew, you had a lot of Dialogue: 0,0:05:18.86,0:05:21.70,Default,,0000,0000,0000,,sort of natural convention coupling that was\Nhappening in Dialogue: 0,0:05:21.70,0:05:22.87,Default,,0000,0000,0000,,the models. Dialogue: 0,0:05:22.87,0:05:26.38,Default,,0000,0000,0000,,So a little bit of a over-simplified example\Nhere. Dialogue: 0,0:05:26.38,0:05:29.90,Default,,0000,0000,0000,,But you have a, let's say you have, you're Dialogue: 0,0:05:29.90,0:05:31.76,Default,,0000,0000,0000,,on the MyGroupon's page. You want to look\Nat Dialogue: 0,0:05:31.76,0:05:33.96,Default,,0000,0000,0000,,all of the Groupons that you've bought. And\Nyou Dialogue: 0,0:05:33.96,0:05:35.65,Default,,0000,0000,0000,,want to see all the titles for all of Dialogue: 0,0:05:35.65,0:05:37.37,Default,,0000,0000,0000,,those. So when we go to render the interface Dialogue: 0,0:05:37.37,0:05:39.88,Default,,0000,0000,0000,,we want to display all these deal titles.\NIn Dialogue: 0,0:05:39.88,0:05:41.93,Default,,0000,0000,0000,,the cobra, you might find a set of dependent Dialogue: 0,0:05:41.93,0:05:44.49,Default,,0000,0000,0000,,relationships that are somewhat like this,\Nwhere you can Dialogue: 0,0:05:44.49,0:05:47.54,Default,,0000,0000,0000,,see the cyclical dependencies. Dialogue: 0,0:05:47.54,0:05:51.20,Default,,0000,0000,0000,,But building these types of associations was\Nfairly common Dialogue: 0,0:05:51.20,0:05:56.35,Default,,0000,0000,0000,,place, which was kind of bad in some ways. Dialogue: 0,0:05:56.35,0:05:59.09,Default,,0000,0000,0000,,So in this case, you would instantiate a user, Dialogue: 0,0:05:59.09,0:06:01.36,Default,,0000,0000,0000,,which would require a database lookup to the\NUsers Dialogue: 0,0:06:01.36,0:06:05.47,Default,,0000,0000,0000,,table, select star, and, and you would map\Nover Dialogue: 0,0:06:05.47,0:06:07.93,Default,,0000,0000,0000,,that, that user's orders to get all of the Dialogue: 0,0:06:07.93,0:06:09.70,Default,,0000,0000,0000,,deal titles. Dialogue: 0,0:06:09.70,0:06:12.87,Default,,0000,0000,0000,,In this, in this case, there is a Demeter Dialogue: 0,0:06:12.87,0:06:16.83,Default,,0000,0000,0000,,violation. Demeter violations are bad. Dialogue: 0,0:06:16.83,0:06:20.06,Default,,0000,0000,0000,,A.P.: And it looks clean. I mean, it looks Dialogue: 0,0:06:20.06,0:06:23.31,Default,,0000,0000,0000,,good. But, what it does is couples our components. Dialogue: 0,0:06:23.31,0:06:26.18,Default,,0000,0000,0000,,J.S.: Here is an example of what I was Dialogue: 0,0:06:26.18,0:06:30.28,Default,,0000,0000,0000,,talking about. You, you have a basically unnecessarily-\Nunnecessary Dialogue: 0,0:06:30.28,0:06:33.93,Default,,0000,0000,0000,,table lookup to Users. Now, if you're designing\Nyour Dialogue: 0,0:06:33.93,0:06:37.40,Default,,0000,0000,0000,,applications well, you can avoid this right\Nout of Dialogue: 0,0:06:37.40,0:06:39.80,Default,,0000,0000,0000,,the gate. But Rails conventions don't, don't\Nencourage you Dialogue: 0,0:06:39.80,0:06:42.20,Default,,0000,0000,0000,,to avoid this right out of the gate. And Dialogue: 0,0:06:42.20,0:06:46.16,Default,,0000,0000,0000,,ActiveRecord DSL for, for advanced queries\Naren't something that Dialogue: 0,0:06:46.16,0:06:48.59,Default,,0000,0000,0000,,people just tend to do by default. Or at Dialogue: 0,0:06:48.59,0:06:50.35,Default,,0000,0000,0000,,least they didn't in 2009. Dialogue: 0,0:06:50.35,0:06:55.09,Default,,0000,0000,0000,,A.P.: Yeah. And, I mean. Things got a lot Dialogue: 0,0:06:55.09,0:06:59.44,Default,,0000,0000,0000,,worse, because our code base and cobra was\Njust Dialogue: 0,0:06:59.44,0:07:01.74,Default,,0000,0000,0000,,getting bigger and bigger. You can see here\Nit's Dialogue: 0,0:07:01.74,0:07:07.52,Default,,0000,0000,0000,,almost two million lines of code at this point. Dialogue: 0,0:07:07.52,0:07:09.40,Default,,0000,0000,0000,,And, oh yeah, we have to stay up 100% Dialogue: 0,0:07:09.40,0:07:13.54,Default,,0000,0000,0000,,of the time. So that's a problem. All right. Dialogue: 0,0:07:13.54,0:07:16.60,Default,,0000,0000,0000,,J.S.: Also, the database is completely on\Nfire. Dialogue: 0,0:07:16.60,0:07:22.31,Default,,0000,0000,0000,,A.P.: So yeah. We were in quite a pickle. Dialogue: 0,0:07:22.31,0:07:29.31,Default,,0000,0000,0000,,It was painful. Testing sucked. I mean, we\Nhad Dialogue: 0,0:07:30.65,0:07:32.77,Default,,0000,0000,0000,,to wait like forty-five minutes for a build\Nto Dialogue: 0,0:07:32.77,0:07:36.34,Default,,0000,0000,0000,,run. You basically ran your tests and then\Nfigure Dialogue: 0,0:07:36.34,0:07:37.69,Default,,0000,0000,0000,,out something else to do, because you had\Nto Dialogue: 0,0:07:37.69,0:07:41.37,Default,,0000,0000,0000,,wait while your tests ran. And a lot of Dialogue: 0,0:07:41.37,0:07:43.88,Default,,0000,0000,0000,,our release engineer devoted a lot of effort\Nto Dialogue: 0,0:07:43.88,0:07:45.59,Default,,0000,0000,0000,,make those tests run faster. Dialogue: 0,0:07:45.59,0:07:49.72,Default,,0000,0000,0000,,J.S.: Deploys were terrible. Deploy, deploy\Nprocess was somewhere Dialogue: 0,0:07:49.72,0:07:52.09,Default,,0000,0000,0000,,on the, on the scale of three hours to Dialogue: 0,0:07:52.09,0:07:56.15,Default,,0000,0000,0000,,deploy the, the application. Just a really\Nbad development Dialogue: 0,0:07:56.15,0:07:58.37,Default,,0000,0000,0000,,experience, especially as you start to have\Nteams that, Dialogue: 0,0:07:58.37,0:08:01.60,Default,,0000,0000,0000,,that split, split ownership. They want to\Niterate on Dialogue: 0,0:08:01.60,0:08:03.65,Default,,0000,0000,0000,,features that matter to their team, and they\Ndon't Dialogue: 0,0:08:03.65,0:08:06.65,Default,,0000,0000,0000,,want to be held up by this gigantic monolithic Dialogue: 0,0:08:06.65,0:08:07.05,Default,,0000,0000,0000,,application. Dialogue: 0,0:08:07.05,0:08:09.98,Default,,0000,0000,0000,,And, and it's, you know, the, the deploy's\Nonly Dialogue: 0,0:08:09.98,0:08:12.09,Default,,0000,0000,0000,,happening once a week. That really hurts the\Nteam's Dialogue: 0,0:08:12.09,0:08:14.44,Default,,0000,0000,0000,,ability to set, that maybe wants to do continuous Dialogue: 0,0:08:14.44,0:08:16.29,Default,,0000,0000,0000,,deployment. So, it sucked. Dialogue: 0,0:08:16.29,0:08:20.59,Default,,0000,0000,0000,,A.P.: Yeah. I mean, and development pace was\Nincreasing, Dialogue: 0,0:08:20.59,0:08:23.46,Default,,0000,0000,0000,,as you saw, and, I mean, what's the best Dialogue: 0,0:08:23.46,0:08:24.95,Default,,0000,0000,0000,,place to put the next line of code, as Dialogue: 0,0:08:24.95,0:08:26.53,Default,,0000,0000,0000,,I heard in a talk earlier. It's the place Dialogue: 0,0:08:26.53,0:08:29.74,Default,,0000,0000,0000,,that you're changes. Models got bloated, and\Nthere's a Dialogue: 0,0:08:29.74,0:08:30.65,Default,,0000,0000,0000,,lot of cruft. Dialogue: 0,0:08:30.65,0:08:32.74,Default,,0000,0000,0000,,J.S.: So all of these things were terrible.\NIt Dialogue: 0,0:08:32.74,0:08:37.69,Default,,0000,0000,0000,,was very painful. So, we decided to move towards Dialogue: 0,0:08:37.69,0:08:41.07,Default,,0000,0000,0000,,service extraction a little bit more seriously. Dialogue: 0,0:08:41.07,0:08:44.69,Default,,0000,0000,0000,,If there's a big take away from this first Dialogue: 0,0:08:44.69,0:08:47.22,Default,,0000,0000,0000,,section, we just want you to remember that\Ncobras Dialogue: 0,0:08:47.22,0:08:54.22,Default,,0000,0000,0000,,are great. They are great. Until they aren't. Dialogue: 0,0:08:55.27,0:08:58.44,Default,,0000,0000,0000,,A.P.: So we needed to alleviate this pain\Nimmediately. Dialogue: 0,0:08:58.44,0:09:00.37,Default,,0000,0000,0000,,We needed to get that code out of there. Dialogue: 0,0:09:00.37,0:09:04.18,Default,,0000,0000,0000,,We needed a quick extraction. So we decided\Nto Dialogue: 0,0:09:04.18,0:09:06.78,Default,,0000,0000,0000,,extract a new service and build it on top Dialogue: 0,0:09:06.78,0:09:09.61,Default,,0000,0000,0000,,of our current schema. We decided to start\Nwith Dialogue: 0,0:09:09.61,0:09:13.89,Default,,0000,0000,0000,,the order service, because. I mean. It was\Ncausing Dialogue: 0,0:09:13.89,0:09:16.59,Default,,0000,0000,0000,,a lot of database contention. We had a lot Dialogue: 0,0:09:16.59,0:09:18.96,Default,,0000,0000,0000,,of people buying a lot of Groupons, and, a Dialogue: 0,0:09:18.96,0:09:20.60,Default,,0000,0000,0000,,good problem to have, but it was bringing\Nour Dialogue: 0,0:09:20.60,0:09:21.47,Default,,0000,0000,0000,,database down. Dialogue: 0,0:09:21.47,0:09:23.37,Default,,0000,0000,0000,,So we needed to get that code out of Dialogue: 0,0:09:23.37,0:09:27.80,Default,,0000,0000,0000,,it, and also another thing behind the, behind\Nchoosing Dialogue: 0,0:09:27.80,0:09:30.01,Default,,0000,0000,0000,,orders to start is that, you know, it's gonna Dialogue: 0,0:09:30.01,0:09:32.06,Default,,0000,0000,0000,,be a long-lived model, a long living model\Nin Dialogue: 0,0:09:32.06,0:09:35.12,Default,,0000,0000,0000,,our domain. We know that for sure. Dialogue: 0,0:09:35.12,0:09:38.19,Default,,0000,0000,0000,,So, to illustrate, this is what it looks like Dialogue: 0,0:09:38.19,0:09:40.66,Default,,0000,0000,0000,,in the beginning. And this is what we're trying Dialogue: 0,0:09:40.66,0:09:44.25,Default,,0000,0000,0000,,to accomplish. You have an orders, you have\Nthe Dialogue: 0,0:09:44.25,0:09:45.92,Default,,0000,0000,0000,,cobra, and then we're trying to have a separate Dialogue: 0,0:09:45.92,0:09:49.45,Default,,0000,0000,0000,,orders codebase, which will have its own database.\NBut Dialogue: 0,0:09:49.45,0:09:53.07,Default,,0000,0000,0000,,it continues to have re- a read-only access\Nto Dialogue: 0,0:09:53.07,0:09:56.18,Default,,0000,0000,0000,,the cobra's database, because we didn't focus\Non completely Dialogue: 0,0:09:56.18,0:10:01.04,Default,,0000,0000,0000,,making the cobra, the order service, re, stopping,\Nstopping Dialogue: 0,0:10:01.04,0:10:03.50,Default,,0000,0000,0000,,it from reaching back into the cobra's database. Dialogue: 0,0:10:03.50,0:10:08.23,Default,,0000,0000,0000,,And, I mean, the cobra was really sneaky.\NIt Dialogue: 0,0:10:08.23,0:10:11.00,Default,,0000,0000,0000,,was really tough to find all the ways that, Dialogue: 0,0:10:11.00,0:10:14.27,Default,,0000,0000,0000,,with Rails callbacks and model associations,\Nall the ways Dialogue: 0,0:10:14.27,0:10:18.77,Default,,0000,0000,0000,,that the components were coupled. Dialogue: 0,0:10:18.77,0:10:21.51,Default,,0000,0000,0000,,So we built some tools to make that easier. Dialogue: 0,0:10:21.51,0:10:23.31,Default,,0000,0000,0000,,This is one of them. The service wall, as Dialogue: 0,0:10:23.31,0:10:25.36,Default,,0000,0000,0000,,call it. We're trying to, the main goal here Dialogue: 0,0:10:25.36,0:10:29.60,Default,,0000,0000,0000,,is separating the concerns of orders within\Nthe application. Dialogue: 0,0:10:29.60,0:10:33.24,Default,,0000,0000,0000,,So, you start with having your services in\Na Dialogue: 0,0:10:33.24,0:10:37.59,Default,,0000,0000,0000,,separate directory. Let's see a closer look\Nof it. Dialogue: 0,0:10:37.59,0:10:40.24,Default,,0000,0000,0000,,You have the order service in its own directory, Dialogue: 0,0:10:40.24,0:10:42.60,Default,,0000,0000,0000,,and you have its own app, its own lib, Dialogue: 0,0:10:42.60,0:10:45.16,Default,,0000,0000,0000,,its own specs. The way that works is that Dialogue: 0,0:10:45.16,0:10:48.26,Default,,0000,0000,0000,,in environment dot rb file, we iterated through\Nthese Dialogue: 0,0:10:48.26,0:10:50.50,Default,,0000,0000,0000,,services and added them to the load path.\NSo Dialogue: 0,0:10:50.50,0:10:53.26,Default,,0000,0000,0000,,the application to the application looks like\Nit's just Dialogue: 0,0:10:53.26,0:10:57.34,Default,,0000,0000,0000,,one big application, but for our purposes,\Nthe code Dialogue: 0,0:10:57.34,0:10:59.00,Default,,0000,0000,0000,,was separate. Dialogue: 0,0:10:59.00,0:11:03.06,Default,,0000,0000,0000,,So, this is like, a small example of how Dialogue: 0,0:11:03.06,0:11:06.11,Default,,0000,0000,0000,,service wall works. You have this disable\Nmodel access Dialogue: 0,0:11:06.11,0:11:11.58,Default,,0000,0000,0000,,method that basically, if, if you specify\Nthe models Dialogue: 0,0:11:11.58,0:11:14.51,Default,,0000,0000,0000,,that you want to, if you specify the service Dialogue: 0,0:11:14.51,0:11:18.82,Default,,0000,0000,0000,,that you want to disable or deprecate, and\Nit'll Dialogue: 0,0:11:18.82,0:11:22.56,Default,,0000,0000,0000,,figure out the models of that service and\Nadd Dialogue: 0,0:11:22.56,0:11:28.71,Default,,0000,0000,0000,,it to this do-not-touch list. And basically\Nraise these Dialogue: 0,0:11:28.71,0:11:31.44,Default,,0000,0000,0000,,kinds of violations. So if you use the disable Dialogue: 0,0:11:31.44,0:11:34.44,Default,,0000,0000,0000,,model access model, when you run your tests,\Nit Dialogue: 0,0:11:34.44,0:11:37.19,Default,,0000,0000,0000,,will put up this message saying, you don't\Nhave Dialogue: 0,0:11:37.19,0:11:38.70,Default,,0000,0000,0000,,access to this method. Dialogue: 0,0:11:38.70,0:11:41.38,Default,,0000,0000,0000,,When a deal is trying to access an order, Dialogue: 0,0:11:41.38,0:11:43.37,Default,,0000,0000,0000,,we can figure that out just by running our Dialogue: 0,0:11:43.37,0:11:46.72,Default,,0000,0000,0000,,tests. If you use the more friendlier, deprecate\Nservice Dialogue: 0,0:11:46.72,0:11:50.27,Default,,0000,0000,0000,,mo- deprecate model access method, then you\Ncan be Dialogue: 0,0:11:50.27,0:11:52.66,Default,,0000,0000,0000,,more permissive and it'll just log it to a Dialogue: 0,0:11:52.66,0:11:54.90,Default,,0000,0000,0000,,file. You can see that in development mode\Nor Dialogue: 0,0:11:54.90,0:11:57.63,Default,,0000,0000,0000,,you can have it on staging, and that'll basically, Dialogue: 0,0:11:57.63,0:11:59.46,Default,,0000,0000,0000,,that'll allow you to find all the places where Dialogue: 0,0:11:59.46,0:12:02.93,Default,,0000,0000,0000,,you're having service infractions. Dialogue: 0,0:12:02.93,0:12:04.80,Default,,0000,0000,0000,,You can't do this in production though, because\Nit Dialogue: 0,0:12:04.80,0:12:09.24,Default,,0000,0000,0000,,causes a serious produ- performance hit. Dialogue: 0,0:12:09.24,0:12:14.36,Default,,0000,0000,0000,,Oh yeah. So this is how, so this is Dialogue: 0,0:12:14.36,0:12:18.34,Default,,0000,0000,0000,,how you actually use the service wall. Use,\Nyou, Dialogue: 0,0:12:18.34,0:12:21.64,Default,,0000,0000,0000,,at the top of your controller, you disable,\Nuse Dialogue: 0,0:12:21.64,0:12:24.77,Default,,0000,0000,0000,,the method disable_model_access or deprecate_model_access,\Ndepending on what you Dialogue: 0,0:12:24.77,0:12:27.03,Default,,0000,0000,0000,,want to do. You tell it what service, and Dialogue: 0,0:12:27.03,0:12:29.57,Default,,0000,0000,0000,,it even lets you exempt some actions that\Nyou Dialogue: 0,0:12:29.57,0:12:31.48,Default,,0000,0000,0000,,don't want to raise violations on yet. Dialogue: 0,0:12:31.48,0:12:35.65,Default,,0000,0000,0000,,That way you can comment out that action and Dialogue: 0,0:12:35.65,0:12:38.27,Default,,0000,0000,0000,,tackle one action at a time. Which endpoints\Nare Dialogue: 0,0:12:38.27,0:12:41.02,Default,,0000,0000,0000,,actually reaching over and causing the service\Nwall infraction. Dialogue: 0,0:12:41.02,0:12:45.68,Default,,0000,0000,0000,,J.S.: So, in addition to the service wall,\None, Dialogue: 0,0:12:45.68,0:12:48.42,Default,,0000,0000,0000,,one other problem with this approach, this\Nextraction approach Dialogue: 0,0:12:48.42,0:12:51.76,Default,,0000,0000,0000,,is that, because you necessarily fork the\Ncode, you Dialogue: 0,0:12:51.76,0:12:53.83,Default,,0000,0000,0000,,get a lot of cruft left over from the Dialogue: 0,0:12:53.83,0:12:59.74,Default,,0000,0000,0000,,old, the old domain. So you find yourself\Nasking, Dialogue: 0,0:12:59.74,0:13:02.34,Default,,0000,0000,0000,,teams find themselves asking, very often,\Nis this endpoint Dialogue: 0,0:13:02.34,0:13:04.36,Default,,0000,0000,0000,,even used? Do we even care about this code Dialogue: 0,0:13:04.36,0:13:04.99,Default,,0000,0000,0000,,anymore? Dialogue: 0,0:13:04.99,0:13:09.74,Default,,0000,0000,0000,,So, a small team of Groupon developers hacked\Ntogether Dialogue: 0,0:13:09.74,0:13:13.14,Default,,0000,0000,0000,,something called Route 66 that we use internally\Nto Dialogue: 0,0:13:13.14,0:13:17.08,Default,,0000,0000,0000,,track down cruft in both our old cobra and Dialogue: 0,0:13:17.08,0:13:20.61,Default,,0000,0000,0000,,our new cobra. So it basically answers the\Nquestion, Dialogue: 0,0:13:20.61,0:13:22.75,Default,,0000,0000,0000,,are these endpoints used? I don't know if\Nyou Dialogue: 0,0:13:22.75,0:13:23.99,Default,,0000,0000,0000,,can see this very well, but this is a Dialogue: 0,0:13:23.99,0:13:24.90,Default,,0000,0000,0000,,little bit of a UI. Dialogue: 0,0:13:24.90,0:13:25.75,Default,,0000,0000,0000,,A.P.: Yeah. Dialogue: 0,0:13:25.75,0:13:30.43,Default,,0000,0000,0000,,J.S.: But what we do is, we analyze log Dialogue: 0,0:13:30.43,0:13:33.62,Default,,0000,0000,0000,,files, we analyze, spelunk logs to come up\Nwith Dialogue: 0,0:13:33.62,0:13:37.06,Default,,0000,0000,0000,,which controller actions are being hit, what's\Nthe frequency. Dialogue: 0,0:13:37.06,0:13:39.37,Default,,0000,0000,0000,,Is this a route that is hit once a Dialogue: 0,0:13:39.37,0:13:42.45,Default,,0000,0000,0000,,week, you know. Once a, once a month? And Dialogue: 0,0:13:42.45,0:13:45.49,Default,,0000,0000,0000,,we can very aggressively decruft using this\Ntool as Dialogue: 0,0:13:45.49,0:13:46.79,Default,,0000,0000,0000,,well. Dialogue: 0,0:13:46.79,0:13:52.77,Default,,0000,0000,0000,,A.P.: All right. So there's definitely pros\Nto this Dialogue: 0,0:13:52.77,0:13:56.57,Default,,0000,0000,0000,,approach. Because you're focusing on just\Nseparating the models, Dialogue: 0,0:13:56.57,0:14:00.21,Default,,0000,0000,0000,,I mean, just separating the code, you can\Nquickly Dialogue: 0,0:14:00.21,0:14:02.73,Default,,0000,0000,0000,,and not worry about spinning up a separate\Ndatabase Dialogue: 0,0:14:02.73,0:14:04.84,Default,,0000,0000,0000,,schema, separate naming, all of that. You\Njust worry Dialogue: 0,0:14:04.84,0:14:08.23,Default,,0000,0000,0000,,about separating the code, and that focuses\Nthe abstraction. Dialogue: 0,0:14:08.23,0:14:11.84,Default,,0000,0000,0000,,It makes it easier to spin up endpoints. But Dialogue: 0,0:14:11.84,0:14:13.41,Default,,0000,0000,0000,,the cons are, you're stilled tied to that\Nlegac, Dialogue: 0,0:14:13.41,0:14:15.54,Default,,0000,0000,0000,,to that legacy database. Not such a bad thing Dialogue: 0,0:14:15.54,0:14:16.93,Default,,0000,0000,0000,,if you really need to get it out of Dialogue: 0,0:14:16.93,0:14:20.86,Default,,0000,0000,0000,,there. But, because you're forking this code\Nnow, and Dialogue: 0,0:14:20.86,0:14:23.46,Default,,0000,0000,0000,,now it's being hit through endpoints, there\Nis still Dialogue: 0,0:14:23.46,0:14:26.08,Default,,0000,0000,0000,,a lot of cruft in the, in the, in Dialogue: 0,0:14:26.08,0:14:28.08,Default,,0000,0000,0000,,the code base. Because a lot of these endpoints Dialogue: 0,0:14:28.08,0:14:29.57,Default,,0000,0000,0000,,are now not being used. Dialogue: 0,0:14:29.57,0:14:32.22,Default,,0000,0000,0000,,J.S.: So this was the first extraction pattern\Nthat Dialogue: 0,0:14:32.22,0:14:34.32,Default,,0000,0000,0000,,we used at Groupon to get out of the Dialogue: 0,0:14:34.32,0:14:39.48,Default,,0000,0000,0000,,original cobra, the original Groupon cobra.\NBut teams sort Dialogue: 0,0:14:39.48,0:14:41.15,Default,,0000,0000,0000,,of own their own tactics, and there are other Dialogue: 0,0:14:41.15,0:14:44.04,Default,,0000,0000,0000,,ways that they're doing it as well. One way Dialogue: 0,0:14:44.04,0:14:47.01,Default,,0000,0000,0000,,that, one way that service extraction is also\Nhappening Dialogue: 0,0:14:47.01,0:14:49.94,Default,,0000,0000,0000,,is by using greenfield services that use a\Nmessage Dialogue: 0,0:14:49.94,0:14:53.73,Default,,0000,0000,0000,,bus. Sometimes you just need to keep that\Nlegacy Dialogue: 0,0:14:53.73,0:14:56.11,Default,,0000,0000,0000,,API running, because there are a lot of client Dialogue: 0,0:14:56.11,0:14:58.12,Default,,0000,0000,0000,,dependencies on it. There's a lot of dependencies\Non Dialogue: 0,0:14:58.12,0:15:00.70,Default,,0000,0000,0000,,the structure of the data. Dialogue: 0,0:15:00.70,0:15:03.31,Default,,0000,0000,0000,,But who likes doing greenfield work in here?\NRaise Dialogue: 0,0:15:03.31,0:15:05.86,Default,,0000,0000,0000,,your hand if you like greenfield work. Right.\NThat Dialogue: 0,0:15:05.86,0:15:10.00,Default,,0000,0000,0000,,should be all of you. Whatever. Dialogue: 0,0:15:10.00,0:15:13.17,Default,,0000,0000,0000,,So, it is possible to do greenfield service\Nextraction, Dialogue: 0,0:15:13.17,0:15:16.62,Default,,0000,0000,0000,,and we're doing this as well. So, again, we Dialogue: 0,0:15:16.62,0:15:21.72,Default,,0000,0000,0000,,have a similar. Whoops. Juggling between power\Npoint and Dialogue: 0,0:15:21.72,0:15:26.94,Default,,0000,0000,0000,,preview. Similar type of situation. You have\Nthis cobra, Dialogue: 0,0:15:26.94,0:15:29.64,Default,,0000,0000,0000,,and then we get to the scenario that we're, Dialogue: 0,0:15:29.64,0:15:31.61,Default,,0000,0000,0000,,we're trying to reach with the greenfield\Nextraction, where Dialogue: 0,0:15:31.61,0:15:34.68,Default,,0000,0000,0000,,you have, in this case the red, the red Dialogue: 0,0:15:34.68,0:15:37.73,Default,,0000,0000,0000,,box represents all new code. There's a gem,\Na Dialogue: 0,0:15:37.73,0:15:40.81,Default,,0000,0000,0000,,client gem that interact, that runs in the\Noriginal Dialogue: 0,0:15:40.81,0:15:42.85,Default,,0000,0000,0000,,cobra, that runs in the green cobra. And when Dialogue: 0,0:15:42.85,0:15:46.29,Default,,0000,0000,0000,,this service writes data to its db, a message Dialogue: 0,0:15:46.29,0:15:49.90,Default,,0000,0000,0000,,is sent that the green cobra consumes and\Nsends Dialogue: 0,0:15:49.90,0:15:53.19,Default,,0000,0000,0000,,over to its own data store, thus satisfying\Nall Dialogue: 0,0:15:53.19,0:15:56.55,Default,,0000,0000,0000,,of the legacy API requirements. Dialogue: 0,0:15:56.55,0:15:58.40,Default,,0000,0000,0000,,And then what's notable about this is to keep Dialogue: 0,0:15:58.40,0:16:02.90,Default,,0000,0000,0000,,everything in sync for service cut-overs,\Nrollouts, et cetera, Dialogue: 0,0:16:02.90,0:16:05.59,Default,,0000,0000,0000,,there is a background sync worker that runs,\Nthat Dialogue: 0,0:16:05.59,0:16:08.92,Default,,0000,0000,0000,,syncs it one way from the old database to Dialogue: 0,0:16:08.92,0:16:12.62,Default,,0000,0000,0000,,the new database. Dialogue: 0,0:16:12.62,0:16:16.08,Default,,0000,0000,0000,,There are pros and cons to this approach as Dialogue: 0,0:16:16.08,0:16:19.23,Default,,0000,0000,0000,,well. Some of the better parts are that you Dialogue: 0,0:16:19.23,0:16:21.88,Default,,0000,0000,0000,,can get rid of your legacy data quickly, again. Dialogue: 0,0:16:21.88,0:16:23.87,Default,,0000,0000,0000,,Devs like greenfield stuff. You like to design\Nyour Dialogue: 0,0:16:23.87,0:16:29.02,Default,,0000,0000,0000,,own systems. You also get to minimize the\Ncut-over Dialogue: 0,0:16:29.02,0:16:32.20,Default,,0000,0000,0000,,risk with your data sync. So you're not splitting Dialogue: 0,0:16:32.20,0:16:34.32,Default,,0000,0000,0000,,the table and you have to have all of Dialogue: 0,0:16:34.32,0:16:38.50,Default,,0000,0000,0000,,these API dependencies written on one hand\Nso that Dialogue: 0,0:16:38.50,0:16:41.65,Default,,0000,0000,0000,,when you break your database you don't have,\Nyou Dialogue: 0,0:16:41.65,0:16:43.26,Default,,0000,0000,0000,,don't have failures. Dialogue: 0,0:16:43.26,0:16:45.12,Default,,0000,0000,0000,,So you can phase the, you can phase out Dialogue: 0,0:16:45.12,0:16:48.09,Default,,0000,0000,0000,,your new, your new endpoints, and you can\Nown Dialogue: 0,0:16:48.09,0:16:50.58,Default,,0000,0000,0000,,the timing of when you build out new endpoint Dialogue: 0,0:16:50.58,0:16:53.50,Default,,0000,0000,0000,,features. Again. Some of the, or some of the Dialogue: 0,0:16:53.50,0:16:56.38,Default,,0000,0000,0000,,cons are that, it is not trivial to build Dialogue: 0,0:16:56.38,0:17:00.40,Default,,0000,0000,0000,,synchronization worker, and it is less trivial\Nto build Dialogue: 0,0:17:00.40,0:17:03.67,Default,,0000,0000,0000,,a validation engine for the data to make sure Dialogue: 0,0:17:03.67,0:17:05.18,Default,,0000,0000,0000,,that you don't get it out of sync when Dialogue: 0,0:17:05.18,0:17:07.49,Default,,0000,0000,0000,,you're pulling from the original source. And\Nthen there Dialogue: 0,0:17:07.49,0:17:12.49,Default,,0000,0000,0000,,are race conditions involved in this as well. Dialogue: 0,0:17:12.49,0:17:14.54,Default,,0000,0000,0000,,A.P.: So Jason and I work on a team Dialogue: 0,0:17:14.54,0:17:18.95,Default,,0000,0000,0000,,that manages inventory, as I said earlier.\NOne of Dialogue: 0,0:17:18.95,0:17:21.66,Default,,0000,0000,0000,,the, looking a little further down the road,\None Dialogue: 0,0:17:21.66,0:17:23.57,Default,,0000,0000,0000,,of the things we needed to do was get, Dialogue: 0,0:17:23.57,0:17:25.53,Default,,0000,0000,0000,,now we needed to get vouchers out of the Dialogue: 0,0:17:25.53,0:17:30.12,Default,,0000,0000,0000,,orders service. Another service extraction.\NAnd vouchers are actually Dialogue: 0,0:17:30.12,0:17:33.16,Default,,0000,0000,0000,,the things that customers redeem. Dialogue: 0,0:17:33.16,0:17:37.68,Default,,0000,0000,0000,,So, a simplified example of what a voucher\Nactually Dialogue: 0,0:17:37.68,0:17:41.48,Default,,0000,0000,0000,,like would look like, except that now we have Dialogue: 0,0:17:41.48,0:17:44.65,Default,,0000,0000,0000,,an id, which is stored in our database. We Dialogue: 0,0:17:44.65,0:17:47.00,Default,,0000,0000,0000,,have the price, which is stored in a legacy Dialogue: 0,0:17:47.00,0:17:51.48,Default,,0000,0000,0000,,database, and now, Groupon's grown since orders.\NWe now Dialogue: 0,0:17:51.48,0:17:55.26,Default,,0000,0000,0000,,have an international platform codebase that\Nserves many different Dialogue: 0,0:17:55.26,0:17:59.56,Default,,0000,0000,0000,,countries. We have offices in Berlin, London,\NChinai, Korea, Dialogue: 0,0:17:59.56,0:18:02.63,Default,,0000,0000,0000,,and many more places. But yeah. Now we've\Ngot Dialogue: 0,0:18:02.63,0:18:05.59,Default,,0000,0000,0000,,to make it, but our service's responsibility\Nis to Dialogue: 0,0:18:05.59,0:18:07.48,Default,,0000,0000,0000,,make it seem like none of that matters. Anyone Dialogue: 0,0:18:07.48,0:18:10.11,Default,,0000,0000,0000,,asking for voucher data needs to know about\Nall Dialogue: 0,0:18:10.11,0:18:11.02,Default,,0000,0000,0000,,voucher data. Dialogue: 0,0:18:11.02,0:18:13.49,Default,,0000,0000,0000,,Our services need to be global as well. So, Dialogue: 0,0:18:13.49,0:18:16.83,Default,,0000,0000,0000,,this is what our world looks like. And this Dialogue: 0,0:18:16.83,0:18:18.32,Default,,0000,0000,0000,,is how our service needs to be built on Dialogue: 0,0:18:18.32,0:18:23.58,Default,,0000,0000,0000,,top of that. What helped, in managing these\Ndifferent Dialogue: 0,0:18:23.58,0:18:26.78,Default,,0000,0000,0000,,sources of truth, was this manager accessor\Npattern in Dialogue: 0,0:18:26.78,0:18:31.69,Default,,0000,0000,0000,,our code base. Specifically, oh. Let me check\Nif Dialogue: 0,0:18:31.69,0:18:37.19,Default,,0000,0000,0000,,I need to- yeah. Specifically, next slide\Nplease, this Dialogue: 0,0:18:37.19,0:18:38.85,Default,,0000,0000,0000,,is what, this is how it helped our code Dialogue: 0,0:18:38.85,0:18:41.29,Default,,0000,0000,0000,,base. Because in the controller, you could\Njust specify, Dialogue: 0,0:18:41.29,0:18:44.27,Default,,0000,0000,0000,,you could talk, talk to this manager object,\Nand Dialogue: 0,0:18:44.27,0:18:46.09,Default,,0000,0000,0000,,you'd say, find me this voucher. Dialogue: 0,0:18:46.09,0:18:48.62,Default,,0000,0000,0000,,And the manager, can you jump to that? All Dialogue: 0,0:18:48.62,0:18:50.30,Default,,0000,0000,0000,,right, it's gonna look like a lot of code, Dialogue: 0,0:18:50.30,0:18:53.26,Default,,0000,0000,0000,,but let's go step-by-step. In the manager,\Nthat's where Dialogue: 0,0:18:53.26,0:18:55.76,Default,,0000,0000,0000,,all the complexity lies. You have the accessor\Nthat Dialogue: 0,0:18:55.76,0:18:58.33,Default,,0000,0000,0000,,accesses local data. You have an accessor,\Na separate Dialogue: 0,0:18:58.33,0:19:01.19,Default,,0000,0000,0000,,accessor - and accessors are just simply,\Nall they Dialogue: 0,0:19:01.19,0:19:06.05,Default,,0000,0000,0000,,do is persistence and finding, and finding\Ndata - Dialogue: 0,0:19:06.05,0:19:09.45,Default,,0000,0000,0000,,so the accessors for the legacy database here,\Nthe Dialogue: 0,0:19:09.45,0:19:12.29,Default,,0000,0000,0000,,cobra accessor, you get that price information,\Nand then Dialogue: 0,0:19:12.29,0:19:15.50,Default,,0000,0000,0000,,you have an international accessor that goes,\Nit could Dialogue: 0,0:19:15.50,0:19:18.58,Default,,0000,0000,0000,,be a database call or, in our case, that's Dialogue: 0,0:19:18.58,0:19:23.02,Default,,0000,0000,0000,,a HTTP call across the ocean. Dialogue: 0,0:19:23.02,0:19:24.84,Default,,0000,0000,0000,,And then you bring all that together, wrap\Nit Dialogue: 0,0:19:24.84,0:19:27.48,Default,,0000,0000,0000,,in a model and have it return that back Dialogue: 0,0:19:27.48,0:19:30.94,Default,,0000,0000,0000,,to your controller. Hang on. Dialogue: 0,0:19:30.94,0:19:35.23,Default,,0000,0000,0000,,All right. So, definitely pros and cons to\Nthis Dialogue: 0,0:19:35.23,0:19:37.16,Default,,0000,0000,0000,,approach. One of the things was, it's easy\Nto Dialogue: 0,0:19:37.16,0:19:40.09,Default,,0000,0000,0000,,incorporate many different data sources. We\Ncall that a Dialogue: 0,0:19:40.09,0:19:42.91,Default,,0000,0000,0000,,facade because it kind of hides all of that. Dialogue: 0,0:19:42.91,0:19:45.84,Default,,0000,0000,0000,,But the, behind the backend of it is really Dialogue: 0,0:19:45.84,0:19:47.15,Default,,0000,0000,0000,,more complex. Dialogue: 0,0:19:47.15,0:19:51.71,Default,,0000,0000,0000,,And, but you hide that complexity. That your\Naccessors Dialogue: 0,0:19:51.71,0:19:54.02,Default,,0000,0000,0000,,are bound to the schema changes. So, our cobra Dialogue: 0,0:19:54.02,0:19:57.18,Default,,0000,0000,0000,,accessor still has to know about the legacy\Nschema. Dialogue: 0,0:19:57.18,0:20:00.39,Default,,0000,0000,0000,,And you're, you, you can't really, making\Nchanges there Dialogue: 0,0:20:00.39,0:20:02.35,Default,,0000,0000,0000,,is not trivial. Dialogue: 0,0:20:02.35,0:20:05.31,Default,,0000,0000,0000,,And, sometimes you can use that as a crutch. Dialogue: 0,0:20:05.31,0:20:07.19,Default,,0000,0000,0000,,So if someone asks you, can you give me Dialogue: 0,0:20:07.19,0:20:08.98,Default,,0000,0000,0000,,this piece of data about a voucher, I really Dialogue: 0,0:20:08.98,0:20:10.51,Default,,0000,0000,0000,,need it, and you want to expose it to Dialogue: 0,0:20:10.51,0:20:12.90,Default,,0000,0000,0000,,the endpoints, you're like, well, I do have\Naccess Dialogue: 0,0:20:12.90,0:20:15.19,Default,,0000,0000,0000,,to the database or I could just make a Dialogue: 0,0:20:15.19,0:20:16.81,Default,,0000,0000,0000,,call. And now you, now you're serving the\Nend- Dialogue: 0,0:20:16.81,0:20:20.04,Default,,0000,0000,0000,,that data, and you're tied to serving that\Ndata Dialogue: 0,0:20:20.04,0:20:21.04,Default,,0000,0000,0000,,in your API. Dialogue: 0,0:20:21.04,0:20:23.90,Default,,0000,0000,0000,,But the important thing there is to be diligent, Dialogue: 0,0:20:23.90,0:20:25.92,Default,,0000,0000,0000,,and as soon as you start serving that, they'll Dialogue: 0,0:20:25.92,0:20:31.08,Default,,0000,0000,0000,,put a strategy together to, actually on that\Ndata. Dialogue: 0,0:20:31.08,0:20:34.22,Default,,0000,0000,0000,,Otherwise you're, the complexity in the manager,\Nwhich is Dialogue: 0,0:20:34.22,0:20:37.27,Default,,0000,0000,0000,,both a pro and a con, will always be Dialogue: 0,0:20:37.27,0:20:40.11,Default,,0000,0000,0000,,there. The purpose of the manager is that\Nit Dialogue: 0,0:20:40.11,0:20:43.06,Default,,0000,0000,0000,,hides that complexity, but as you start owning\Nmore Dialogue: 0,0:20:43.06,0:20:45.56,Default,,0000,0000,0000,,data, it should become simpler. Dialogue: 0,0:20:45.56,0:20:50.50,Default,,0000,0000,0000,,J.S.: So, these, these three extraction patterns\Nthat we've Dialogue: 0,0:20:50.50,0:20:54.78,Default,,0000,0000,0000,,gone through are just a little bit of, a Dialogue: 0,0:20:54.78,0:20:57.41,Default,,0000,0000,0000,,little bit of what's going on. There are different Dialogue: 0,0:20:57.41,0:21:00.73,Default,,0000,0000,0000,,service extraction patterns going on, both\Nat Groupon and Dialogue: 0,0:21:00.73,0:21:05.64,Default,,0000,0000,0000,,probably in your worlds too. So, again, this\Nis Dialogue: 0,0:21:05.64,0:21:07.60,Default,,0000,0000,0000,,just a example of some of the ways that Dialogue: 0,0:21:07.60,0:21:11.00,Default,,0000,0000,0000,,we've chosen to do things. There are other\Ninteresting Dialogue: 0,0:21:11.00,0:21:13.45,Default,,0000,0000,0000,,talks about this this week at RailsConf going\Non, Dialogue: 0,0:21:13.45,0:21:15.64,Default,,0000,0000,0000,,so be, it'd be neat to check those out, Dialogue: 0,0:21:15.64,0:21:17.41,Default,,0000,0000,0000,,too, if you want to talk to us about Dialogue: 0,0:21:17.41,0:21:18.35,Default,,0000,0000,0000,,them. Dialogue: 0,0:21:18.35,0:21:21.40,Default,,0000,0000,0000,,But, you should definitely consider letting\Nyour teams own Dialogue: 0,0:21:21.40,0:21:23.29,Default,,0000,0000,0000,,their tactics if you're trying to make decisions\Nabout Dialogue: 0,0:21:23.29,0:21:26.84,Default,,0000,0000,0000,,doing SOA, because you might find some neat\Nthings Dialogue: 0,0:21:26.84,0:21:27.68,Default,,0000,0000,0000,,that you didn't know about. Dialogue: 0,0:21:27.68,0:21:30.41,Default,,0000,0000,0000,,A.P.: Yeah. So I'm gonna stand over here cause Dialogue: 0,0:21:30.41,0:21:33.14,Default,,0000,0000,0000,,I feel like I'm just talking to these guys. Dialogue: 0,0:21:33.14,0:21:35.00,Default,,0000,0000,0000,,But yeah. So, there's definitely a lot of\Nthings Dialogue: 0,0:21:35.00,0:21:37.63,Default,,0000,0000,0000,,that we learned from doing these different\Nservice extractions. Dialogue: 0,0:21:37.63,0:21:39.17,Default,,0000,0000,0000,,Like Jason said, there are a lot of other Dialogue: 0,0:21:39.17,0:21:43.16,Default,,0000,0000,0000,,service extractions that happened at Groupon\Nand continue to Dialogue: 0,0:21:43.16,0:21:45.25,Default,,0000,0000,0000,,happen today. Dialogue: 0,0:21:45.25,0:21:48.81,Default,,0000,0000,0000,,But, taming a cobra is serious business. I\Nmean, Dialogue: 0,0:21:48.81,0:21:51.98,Default,,0000,0000,0000,,like I always say, YPAGNIRN. You probably\Nain't gonna Dialogue: 0,0:21:51.98,0:21:56.78,Default,,0000,0000,0000,,need it right now. But, but the, but, like, Dialogue: 0,0:21:56.78,0:21:59.38,Default,,0000,0000,0000,,the tipping point on which you need to start Dialogue: 0,0:21:59.38,0:22:03.80,Default,,0000,0000,0000,,going towards service-oriented architecture\Nisn't just black or white. Dialogue: 0,0:22:03.80,0:22:06.53,Default,,0000,0000,0000,,It's, it's more of an art than a science. Dialogue: 0,0:22:06.53,0:22:08.46,Default,,0000,0000,0000,,But as soon as you start talking about service-oriented Dialogue: 0,0:22:08.46,0:22:11.06,Default,,0000,0000,0000,,architecture, once you start feeling the pains,\Nyou need Dialogue: 0,0:22:11.06,0:22:13.58,Default,,0000,0000,0000,,to put, put together a strategy to accomplish\Nthat. Dialogue: 0,0:22:13.58,0:22:15.31,Default,,0000,0000,0000,,J.S.: Yeah. You don't want to sit around and Dialogue: 0,0:22:15.31,0:22:16.66,Default,,0000,0000,0000,,wait for Oprah to blow your site up. Dialogue: 0,0:22:16.66,0:22:20.75,Default,,0000,0000,0000,,A.P. But there's also the importance of allowing\Nyour Dialogue: 0,0:22:20.75,0:22:24.87,Default,,0000,0000,0000,,domain to actually evolve. Models that you\Nthink are Dialogue: 0,0:22:24.87,0:22:27.00,Default,,0000,0000,0000,,important in the beginning aren't gonna be\Nimportant later Dialogue: 0,0:22:27.00,0:22:30.76,Default,,0000,0000,0000,,on. And it, that's the big benefit of a Dialogue: 0,0:22:30.76,0:22:33.83,Default,,0000,0000,0000,,cobra, is that it allows you to iterate quickly. Dialogue: 0,0:22:33.83,0:22:36.36,Default,,0000,0000,0000,,J.S.: Something else that we have also learned\Nis Dialogue: 0,0:22:36.36,0:22:38.47,Default,,0000,0000,0000,,that when you go into service extraction,\Nit's really Dialogue: 0,0:22:38.47,0:22:42.39,Default,,0000,0000,0000,,important that you actually have a strategy.\NKnow what Dialogue: 0,0:22:42.39,0:22:45.40,Default,,0000,0000,0000,,you need to break apart. Know what you need Dialogue: 0,0:22:45.40,0:22:48.27,Default,,0000,0000,0000,,to leave in the monolith. These are important\Nthings Dialogue: 0,0:22:48.27,0:22:50.78,Default,,0000,0000,0000,,to consider. Know what the priorities are\Nbetween those Dialogue: 0,0:22:50.78,0:22:54.18,Default,,0000,0000,0000,,things. It's very, it's very tricky to just\Ngo Dialogue: 0,0:22:54.18,0:22:58.48,Default,,0000,0000,0000,,about service extraction very scattershot\Nand not really understanding Dialogue: 0,0:22:58.48,0:23:00.81,Default,,0000,0000,0000,,your business model or what benefits you derive\Nfrom Dialogue: 0,0:23:00.81,0:23:03.65,Default,,0000,0000,0000,,extracting certain pieces over others. Dialogue: 0,0:23:03.65,0:23:05.46,Default,,0000,0000,0000,,You should prefer the things that are clearly\Nlike Dialogue: 0,0:23:05.46,0:23:08.83,Default,,0000,0000,0000,,their own thing, their own components, or\Nthings that Dialogue: 0,0:23:08.83,0:23:13.03,Default,,0000,0000,0000,,are particular maintenance problems or represent\Nsome sort of Dialogue: 0,0:23:13.03,0:23:17.49,Default,,0000,0000,0000,,legacy design or, or strange behavior. But\Nthe other Dialogue: 0,0:23:17.49,0:23:19.53,Default,,0000,0000,0000,,important part of having a strategy is that\Nyou Dialogue: 0,0:23:19.53,0:23:24.36,Default,,0000,0000,0000,,should expect the unexpected. Scope creep\Nwill bite you, Dialogue: 0,0:23:24.36,0:23:26.49,Default,,0000,0000,0000,,and you know, as these, as these code bases Dialogue: 0,0:23:26.49,0:23:29.01,Default,,0000,0000,0000,,get bigger, pulling out of them becomes a\Nlot Dialogue: 0,0:23:29.01,0:23:33.91,Default,,0000,0000,0000,,more of a tricky process than you might envision. Dialogue: 0,0:23:33.91,0:23:35.86,Default,,0000,0000,0000,,Another thing that's important is that you,\Nyou think Dialogue: 0,0:23:35.86,0:23:39.47,Default,,0000,0000,0000,,about your entire service stack. And you should\Nknow Dialogue: 0,0:23:39.47,0:23:42.09,Default,,0000,0000,0000,,your business, and so you should know, or\Nyou Dialogue: 0,0:23:42.09,0:23:44.86,Default,,0000,0000,0000,,should at least conceptualize how all of those\Nparts Dialogue: 0,0:23:44.86,0:23:47.33,Default,,0000,0000,0000,,of your business are gonna fit together. Dialogue: 0,0:23:47.33,0:23:48.89,Default,,0000,0000,0000,,How does the data flow between them? What\Nare Dialogue: 0,0:23:48.89,0:23:52.97,Default,,0000,0000,0000,,the service agreements between those, those\Ncompartments? That's all Dialogue: 0,0:23:52.97,0:23:55.07,Default,,0000,0000,0000,,important to know. You're gonna need to be\Ncaching Dialogue: 0,0:23:55.07,0:23:59.29,Default,,0000,0000,0000,,between services for, for load. You're gonna\Nneed to Dialogue: 0,0:23:59.29,0:24:05.57,Default,,0000,0000,0000,,be caching services for, for latency requirements.\NSo you Dialogue: 0,0:24:05.57,0:24:07.59,Default,,0000,0000,0000,,have to serve upstream to some kind of complex Dialogue: 0,0:24:07.59,0:24:10.69,Default,,0000,0000,0000,,algorithm. That algorithm is gonna need zero\Nlatency return Dialogue: 0,0:24:10.69,0:24:12.03,Default,,0000,0000,0000,,from your service. Dialogue: 0,0:24:12.03,0:24:13.41,Default,,0000,0000,0000,,You need to be thinking about all of these Dialogue: 0,0:24:13.41,0:24:16.54,Default,,0000,0000,0000,,kinds of things when you're doing service\Nextraction. Dialogue: 0,0:24:16.54,0:24:20.25,Default,,0000,0000,0000,,A.P.: And the way Jason's saying it is, is Dialogue: 0,0:24:20.25,0:24:23.12,Default,,0000,0000,0000,,definitely makes it seem like, oh, it's one\Nslide Dialogue: 0,0:24:23.12,0:24:24.92,Default,,0000,0000,0000,,on our deck. But each of those topics could Dialogue: 0,0:24:24.92,0:24:29.16,Default,,0000,0000,0000,,be a separate talk. And they are. So, definitely, Dialogue: 0,0:24:29.16,0:24:30.26,Default,,0000,0000,0000,,there's a lot of learn in that, in that Dialogue: 0,0:24:30.26,0:24:30.99,Default,,0000,0000,0000,,domain. Dialogue: 0,0:24:30.99,0:24:34.73,Default,,0000,0000,0000,,J.S.: Right. Just in terms of actual topics\Nin Dialogue: 0,0:24:34.73,0:24:37.04,Default,,0000,0000,0000,,it, another thing you want to think about\Nis Dialogue: 0,0:24:37.04,0:24:40.49,Default,,0000,0000,0000,,messaging. Inter-service messaging, when you're\Npulling these services apart, Dialogue: 0,0:24:40.49,0:24:42.29,Default,,0000,0000,0000,,they do need to talk to each other. You Dialogue: 0,0:24:42.29,0:24:45.40,Default,,0000,0000,0000,,should definitely think about what do those\Nmessages look Dialogue: 0,0:24:45.40,0:24:49.79,Default,,0000,0000,0000,,like. What are their delivery SOAs? Do you\Nguarantee Dialogue: 0,0:24:49.79,0:24:52.06,Default,,0000,0000,0000,,that they're delivered? Do you guarantee the\Norder that Dialogue: 0,0:24:52.06,0:24:54.88,Default,,0000,0000,0000,,they're delivered in? What are the payloads\Nlook like? Dialogue: 0,0:24:54.88,0:24:57.83,Default,,0000,0000,0000,,Think about all of this stuff. Dialogue: 0,0:24:57.83,0:25:01.62,Default,,0000,0000,0000,,And, you also need to consider your, concern\Nyourself Dialogue: 0,0:25:01.62,0:25:05.75,Default,,0000,0000,0000,,with authentication and authorization. These\Nare, these are important Dialogue: 0,0:25:05.75,0:25:08.47,Default,,0000,0000,0000,,topics. I think like, there was a talk about Dialogue: 0,0:25:08.47,0:25:09.33,Default,,0000,0000,0000,,this yesterday- Dialogue: 0,0:25:09.33,0:25:09.88,Default,,0000,0000,0000,,A.P.: There were two. Dialogue: 0,0:25:09.88,0:25:12.30,Default,,0000,0000,0000,,J.S.: Oh, there were two talks about this\Nyesterday. Dialogue: 0,0:25:12.30,0:25:13.68,Default,,0000,0000,0000,,But you should know what you're, know what\Nyou're Dialogue: 0,0:25:13.68,0:25:16.73,Default,,0000,0000,0000,,users are doing. Your sites getting bigger.\NYour users Dialogue: 0,0:25:16.73,0:25:19.64,Default,,0000,0000,0000,,are getting more complicated. Know, know what\Nthey need Dialogue: 0,0:25:19.64,0:25:21.68,Default,,0000,0000,0000,,access to. Know how they get into your, how Dialogue: 0,0:25:21.68,0:25:23.23,Default,,0000,0000,0000,,they get into your services, how they get\Nthrough Dialogue: 0,0:25:23.23,0:25:26.42,Default,,0000,0000,0000,,your services. And know what they can do at Dialogue: 0,0:25:26.42,0:25:28.86,Default,,0000,0000,0000,,each step of the way. Dialogue: 0,0:25:28.86,0:25:31.66,Default,,0000,0000,0000,,A.P.: And you need to create like a supportive, Dialogue: 0,0:25:31.66,0:25:36.18,Default,,0000,0000,0000,,supporting environment for services. We were\Nlucky, we had Dialogue: 0,0:25:36.18,0:25:40.32,Default,,0000,0000,0000,,entire teams devoted to building tools, to,\Nthat make Dialogue: 0,0:25:40.32,0:25:43.13,Default,,0000,0000,0000,,it easier to spin up services easily. And\Na Dialogue: 0,0:25:43.13,0:25:48.09,Default,,0000,0000,0000,,release engineering team that made it easier\Nto re, Dialogue: 0,0:25:48.09,0:25:52.08,Default,,0000,0000,0000,,deploy these services. All those became really\Neasy for Dialogue: 0,0:25:52.08,0:25:54.79,Default,,0000,0000,0000,,us, but if, in your company, you need to Dialogue: 0,0:25:54.79,0:25:56.83,Default,,0000,0000,0000,,make sure that, or in your application, you\Nneed Dialogue: 0,0:25:56.83,0:25:58.27,Default,,0000,0000,0000,,to make sure that you think about these things Dialogue: 0,0:25:58.27,0:26:01.61,Default,,0000,0000,0000,,and devote tools and time to making those\Nthings Dialogue: 0,0:26:01.61,0:26:02.28,Default,,0000,0000,0000,,simpler. Dialogue: 0,0:26:02.28,0:26:06.24,Default,,0000,0000,0000,,Also, now is the time to start considering\Nuuids. Dialogue: 0,0:26:06.24,0:26:09.71,Default,,0000,0000,0000,,As soon as you start talking about service-oriented\Narchitecture, Dialogue: 0,0:26:09.71,0:26:15.47,Default,,0000,0000,0000,,go to uuids from the start. This will immediately Dialogue: 0,0:26:15.47,0:26:17.89,Default,,0000,0000,0000,,separate you from your database, and that's\Ngonna be Dialogue: 0,0:26:17.89,0:26:20.43,Default,,0000,0000,0000,,really important, because you're gonna be\Nmoving data from Dialogue: 0,0:26:20.43,0:26:23.20,Default,,0000,0000,0000,,one source to another. Dialogue: 0,0:26:23.20,0:26:26.38,Default,,0000,0000,0000,,And, you need to write code good. You know, Dialogue: 0,0:26:26.38,0:26:28.90,Default,,0000,0000,0000,,like, it's hard to. I mean, it's easy to Dialogue: 0,0:26:28.90,0:26:31.01,Default,,0000,0000,0000,,say, say that, but it's hard to do. Think Dialogue: 0,0:26:31.01,0:26:34.15,Default,,0000,0000,0000,,about the solid principles. Think about where\Nthings belong. Dialogue: 0,0:26:34.15,0:26:37.00,Default,,0000,0000,0000,,Ask yourself, am I coupling these two components\Ntogether Dialogue: 0,0:26:37.00,0:26:40.97,Default,,0000,0000,0000,,for the fu- and is that useful enough that Dialogue: 0,0:26:40.97,0:26:42.72,Default,,0000,0000,0000,,it's gonna cause me a lot of pain later Dialogue: 0,0:26:42.72,0:26:43.35,Default,,0000,0000,0000,,in the future? Dialogue: 0,0:26:43.35,0:26:45.82,Default,,0000,0000,0000,,J.S.: So when you're writing your code good,\Nyou Dialogue: 0,0:26:45.82,0:26:48.99,Default,,0000,0000,0000,,should be thinking about your models. Those\Nmodels are Dialogue: 0,0:26:48.99,0:26:51.52,Default,,0000,0000,0000,,gonna become your APIs. They're gonna become\Nyour service Dialogue: 0,0:26:51.52,0:26:55.68,Default,,0000,0000,0000,,APIs. So consider your public methods. What\Nare you Dialogue: 0,0:26:55.68,0:26:58.65,Default,,0000,0000,0000,,putting in the public space of that model?\NIs Dialogue: 0,0:26:58.65,0:27:00.76,Default,,0000,0000,0000,,it named well? Does it represent what your\Nservice Dialogue: 0,0:27:00.76,0:27:03.11,Default,,0000,0000,0000,,should be doing? Dialogue: 0,0:27:03.11,0:27:05.95,Default,,0000,0000,0000,,Make sure that, while you're building up your\Ncobras, Dialogue: 0,0:27:05.95,0:27:08.95,Default,,0000,0000,0000,,that your models are reflective of the way\Nyou Dialogue: 0,0:27:08.95,0:27:11.80,Default,,0000,0000,0000,,intend for your service APIs to look like,\Nshould Dialogue: 0,0:27:11.80,0:27:15.09,Default,,0000,0000,0000,,you ever need to go down that road. Dialogue: 0,0:27:15.09,0:27:19.15,Default,,0000,0000,0000,,A.P.: And, like I said earlier, avoid tangling\Nthose Dialogue: 0,0:27:19.15,0:27:23.85,Default,,0000,0000,0000,,components together. Specifically in Rails,\Nwhen you introduce associations, Dialogue: 0,0:27:23.85,0:27:26.29,Default,,0000,0000,0000,,you're kind of expanding that API that Jason\Nwas Dialogue: 0,0:27:26.29,0:27:29.62,Default,,0000,0000,0000,,talking about. All those, now you're creating\Nways for Dialogue: 0,0:27:29.62,0:27:33.63,Default,,0000,0000,0000,,developers to reach through these models and\Nget data, Dialogue: 0,0:27:33.63,0:27:36.46,Default,,0000,0000,0000,,and that'll couple them together and make\Nit harder Dialogue: 0,0:27:36.46,0:27:38.64,Default,,0000,0000,0000,,for you to separate them. Dialogue: 0,0:27:38.64,0:27:42.58,Default,,0000,0000,0000,,J.S.: Test. Who's here, who here tests? Anyone\Ntest? Dialogue: 0,0:27:42.58,0:27:43.89,Default,,0000,0000,0000,,A.P.: Not DHH. Dialogue: 0,0:27:43.89,0:27:46.77,Default,,0000,0000,0000,,J.S.: Nope. You don't test anymore. You should\Nbe Dialogue: 0,0:27:46.77,0:27:50.49,Default,,0000,0000,0000,,testing. You should be testing at high levels.\NAvoid Dialogue: 0,0:27:50.49,0:27:54.00,Default,,0000,0000,0000,,the unit tests. If you can avoid the unit Dialogue: 0,0:27:54.00,0:27:56.96,Default,,0000,0000,0000,,tests. Especially because once you start doing\Nservice extraction, Dialogue: 0,0:27:56.96,0:28:00.83,Default,,0000,0000,0000,,you will break assloads of unit tests. Dialogue: 0,0:28:00.83,0:28:02.45,Default,,0000,0000,0000,,Make sure you write your high-level tests\Nfirst. Make Dialogue: 0,0:28:02.45,0:28:05.05,Default,,0000,0000,0000,,sure you've got solid coverage on those high-level\Nend Dialogue: 0,0:28:05.05,0:28:09.75,Default,,0000,0000,0000,,to end tests. Secondly, as you are doing service Dialogue: 0,0:28:09.75,0:28:12.26,Default,,0000,0000,0000,,extraction, it is not trivial to be spinning\Nup Dialogue: 0,0:28:12.26,0:28:15.33,Default,,0000,0000,0000,,other services quickly in order to test end\Nto Dialogue: 0,0:28:15.33,0:28:17.55,Default,,0000,0000,0000,,end, but you should be thinking about how\Nyou Dialogue: 0,0:28:17.55,0:28:20.37,Default,,0000,0000,0000,,might be doing that. Because otherwise you're\Ngoing to Dialogue: 0,0:28:20.37,0:28:22.61,Default,,0000,0000,0000,,be doing a lot of stubbing, and that gets Dialogue: 0,0:28:22.61,0:28:24.74,Default,,0000,0000,0000,,very painful and gets error-prone. Dialogue: 0,0:28:24.74,0:28:28.52,Default,,0000,0000,0000,,A.P.: I mean, when we talked to the developers Dialogue: 0,0:28:28.52,0:28:29.89,Default,,0000,0000,0000,,who had to do some of the tougher service Dialogue: 0,0:28:29.89,0:28:33.50,Default,,0000,0000,0000,,extractions, they were like, I wish we had\Nmore Dialogue: 0,0:28:33.50,0:28:36.01,Default,,0000,0000,0000,,integration specs. Because we're gonna be\Nchanging a lot Dialogue: 0,0:28:36.01,0:28:37.92,Default,,0000,0000,0000,,of this stuff, and we need to know if Dialogue: 0,0:28:37.92,0:28:40.35,Default,,0000,0000,0000,,it works. If you've got a good set of Dialogue: 0,0:28:40.35,0:28:43.17,Default,,0000,0000,0000,,integrations, integration tests, you can be\Na lot more Dialogue: 0,0:28:43.17,0:28:45.88,Default,,0000,0000,0000,,confident about making those changes. Dialogue: 0,0:28:46.84,0:28:48.54,Default,,0000,0000,0000,,Next, over there? Dialogue: 0,0:28:48.54,0:28:49.04,Default,,0000,0000,0000,,J.S.: Yup. Dialogue: 0,0:28:50.22,0:28:53.42,Default,,0000,0000,0000,,A.P.: Yeah. So, you need to communicate. I\Nmean, Dialogue: 0,0:28:53.42,0:28:56.75,Default,,0000,0000,0000,,everyone always says this, but like, when\Nyou solve Dialogue: 0,0:28:56.75,0:28:59.75,Default,,0000,0000,0000,,a problem, when you're spinning up a service,\Nyou're Dialogue: 0,0:28:59.75,0:29:02.46,Default,,0000,0000,0000,,gonna, and as more teams are spinning up services, Dialogue: 0,0:29:02.46,0:29:04.37,Default,,0000,0000,0000,,a lot of you are gonna be encountering the Dialogue: 0,0:29:04.37,0:29:07.26,Default,,0000,0000,0000,,same problems. So when you solve a problem,\Nshare Dialogue: 0,0:29:07.26,0:29:09.04,Default,,0000,0000,0000,,it. Make it a gem, write it down, put Dialogue: 0,0:29:09.04,0:29:11.23,Default,,0000,0000,0000,,it in a wiki, and tell people about it. Dialogue: 0,0:29:11.23,0:29:14.94,Default,,0000,0000,0000,,Give talks. Because it's gonna be hard to,\NI Dialogue: 0,0:29:14.94,0:29:17.57,Default,,0000,0000,0000,,mean, you don't want people solving the same\Nproblems. Dialogue: 0,0:29:17.57,0:29:21.70,Default,,0000,0000,0000,,At Groupon, we have this, Core Architecture\NForum, it's Dialogue: 0,0:29:21.70,0:29:24.22,Default,,0000,0000,0000,,called, and basically it's got a bunch of\Npeople Dialogue: 0,0:29:24.22,0:29:27.05,Default,,0000,0000,0000,,who meet, and you can say, I'm gonna spin Dialogue: 0,0:29:27.05,0:29:28.97,Default,,0000,0000,0000,,up a new service, or I'm gonna solve this Dialogue: 0,0:29:28.97,0:29:31.95,Default,,0000,0000,0000,,problem. Have you seen this before? They're\Ngonna help Dialogue: 0,0:29:31.95,0:29:35.37,Default,,0000,0000,0000,,you answer questions like, what's, has someone\Nelse solved Dialogue: 0,0:29:35.37,0:29:38.20,Default,,0000,0000,0000,,this already? Is there a similar problem?\NIs there Dialogue: 0,0:29:38.20,0:29:40.39,Default,,0000,0000,0000,,a particular technology that would help you\Nsolve that Dialogue: 0,0:29:40.39,0:29:43.69,Default,,0000,0000,0000,,problem better? All those questions are really\Nimportant to Dialogue: 0,0:29:43.69,0:29:48.60,Default,,0000,0000,0000,,ask so that you don't reinvent the wheel over Dialogue: 0,0:29:48.60,0:29:50.74,Default,,0000,0000,0000,,and over again. Dialogue: 0,0:29:50.74,0:29:54.54,Default,,0000,0000,0000,,What else? Oh yeah. One more thing. One more Dialogue: 0,0:29:54.54,0:29:55.06,Default,,0000,0000,0000,,thing. That sounds like Steve Jobs. One more\Nthing. Dialogue: 0,0:29:55.06,0:29:57.74,Default,,0000,0000,0000,,We have the interest, we have interest leagues\Nat Dialogue: 0,0:29:57.74,0:30:01.90,Default,,0000,0000,0000,,Groupon, which are just internal user groups\Nfor Clojure, Dialogue: 0,0:30:01.90,0:30:04.76,Default,,0000,0000,0000,,Java. We even have one for onboarding. You\Nknow, Dialogue: 0,0:30:04.76,0:30:06.93,Default,,0000,0000,0000,,there's are really cool. And that's another\Nway to Dialogue: 0,0:30:06.93,0:30:09.64,Default,,0000,0000,0000,,help communicate, like, what's happening.\NOnce your company gets Dialogue: 0,0:30:09.64,0:30:14.73,Default,,0000,0000,0000,,big enough, that's really important. Dialogue: 0,0:30:14.73,0:30:20.52,Default,,0000,0000,0000,,J.S.: So. In conclusion, cobras are great. Dialogue: 0,0:30:20.52,0:30:21.24,Default,,0000,0000,0000,,A.P.: Yeah. They're awesome. Dialogue: 0,0:30:21.24,0:30:24.00,Default,,0000,0000,0000,,J.S.: Rails is great. And cobras do serve\Na Dialogue: 0,0:30:24.00,0:30:25.84,Default,,0000,0000,0000,,useful purpose. Dialogue: 0,0:30:25.84,0:30:32.15,Default,,0000,0000,0000,,A.P.: Oh. But beware. It's not so simple. Dialogue: 0,0:30:32.15,0:30:35.77,Default,,0000,0000,0000,,J.S.: Once you decide that you're gonna start\Nraising Dialogue: 0,0:30:35.77,0:30:40.59,Default,,0000,0000,0000,,up a baby cobra, be ready for what comes Dialogue: 0,0:30:40.59,0:30:41.22,Default,,0000,0000,0000,,next. Dialogue: 0,0:30:41.22,0:30:46.89,Default,,0000,0000,0000,,A.P.: Oh. Yeah. And. OK, so. Got his part. Dialogue: 0,0:30:46.89,0:30:50.82,Default,,0000,0000,0000,,We're hiring. I mean, if you want to come Dialogue: 0,0:30:50.82,0:30:53.67,Default,,0000,0000,0000,,help us solve some of these problems, come\Ntalk Dialogue: 0,0:30:53.67,0:30:56.04,Default,,0000,0000,0000,,to us after the talk. There's a booth downstairs. Dialogue: 0,0:30:56.04,0:31:00.71,Default,,0000,0000,0000,,You can go to this website. Tweet at us. Dialogue: 0,0:31:00.71,0:31:04.34,Default,,0000,0000,0000,,I'd like that. But yeah. Join us. Dialogue: 0,0:31:04.34,0:31:06.82,Default,,0000,0000,0000,,J.S.: And we are standing on other people's\Nshoulders Dialogue: 0,0:31:06.82,0:31:06.89,Default,,0000,0000,0000,,here. Dialogue: 0,0:31:06.89,0:31:07.05,Default,,0000,0000,0000,,A.P.: Yeah. Dialogue: 0,0:31:07.05,0:31:09.57,Default,,0000,0000,0000,,J.S.: A lot of these folks are people who Dialogue: 0,0:31:09.57,0:31:12.21,Default,,0000,0000,0000,,helped with the talk or who helped actually\Ndo Dialogue: 0,0:31:12.21,0:31:14.91,Default,,0000,0000,0000,,a lot of this service extraction work. This\Ndoes Dialogue: 0,0:31:14.91,0:31:18.76,Default,,0000,0000,0000,,not comprise the total list, but we definitely\Nwanted Dialogue: 0,0:31:18.76,0:31:20.25,Default,,0000,0000,0000,,to bring attention to these people. Dialogue: 0,0:31:20.25,0:31:22.06,Default,,0000,0000,0000,,A.P.: Yeah, and I mean. People like these\Nguys, Dialogue: 0,0:31:22.06,0:31:24.42,Default,,0000,0000,0000,,they gave us a lot of feedback when we Dialogue: 0,0:31:24.42,0:31:27.96,Default,,0000,0000,0000,,did the talk at, at Groupon. And having people Dialogue: 0,0:31:27.96,0:31:31.42,Default,,0000,0000,0000,,who will mentor and, like, spend time to help Dialogue: 0,0:31:31.42,0:31:34.47,Default,,0000,0000,0000,,you understand things, I mean, that's the\Nreason I Dialogue: 0,0:31:34.47,0:31:35.52,Default,,0000,0000,0000,,work at Groupon. Dialogue: 0,0:31:35.52,0:31:36.34,Default,,0000,0000,0000,,J.S.: Thank you all. Dialogue: 0,0:31:39.24,0:31:42.44,Default,,0000,0000,0000,,A.P.: [drowned out by applause]