[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:17.04,0:00:18.77,Default,,0000,0000,0000,,ERIC SAXBY: Thanks for coming. Dialogue: 0,0:00:18.77,0:00:21.28,Default,,0000,0000,0000,,So, I am Eric Saxby. Today I'm gonna be talking Dialogue: 0,0:00:21.28,0:00:24.61,Default,,0000,0000,0000,,about iterating towards service-oriented Dialogue: 0,0:00:24.61,0:00:28.87,Default,,0000,0000,0000,,architecture. I may have time for questions Dialogue: 0,0:00:28.87,0:00:30.45,Default,,0000,0000,0000,,at the end, but I may not. Dialogue: 0,0:00:30.45,0:00:31.38,Default,,0000,0000,0000,,This might go forty minutes, Dialogue: 0,0:00:31.38,0:00:32.60,Default,,0000,0000,0000,,so I'm just gonna get started. Dialogue: 0,0:00:32.60,0:00:35.83,Default,,0000,0000,0000,,So, if you're like me, you can't really pay Dialogue: 0,0:00:35.83,0:00:38.50,Default,,0000,0000,0000,,attention in talking about programming Dialogue: 0,0:00:38.50,0:00:39.25,Default,,0000,0000,0000,,unless there are pictures Dialogue: 0,0:00:39.25,0:00:44.56,Default,,0000,0000,0000,,of cats. So really, we're going from this\Nto Dialogue: 0,0:00:44.56,0:00:48.58,Default,,0000,0000,0000,,something a little bit more like this. But\Nworking Dialogue: 0,0:00:48.58,0:00:50.73,Default,,0000,0000,0000,,together, as a family. Dialogue: 0,0:00:50.73,0:00:53.23,Default,,0000,0000,0000,,So why should you care? Why should you listen Dialogue: 0,0:00:53.23,0:00:57.87,Default,,0000,0000,0000,,to me? So you may not know this, but Dialogue: 0,0:00:57.87,0:01:01.80,Default,,0000,0000,0000,,I'm kind of a big deal. But, but really, Dialogue: 0,0:01:01.80,0:01:04.52,Default,,0000,0000,0000,,I've, I've actually not been doing this for\Nthat Dialogue: 0,0:01:04.52,0:01:07.49,Default,,0000,0000,0000,,long. I've been doing Rails for about six\Nyears. Dialogue: 0,0:01:07.49,0:01:11.49,Default,,0000,0000,0000,,Before and after that, I had been using various Dialogue: 0,0:01:11.49,0:01:17.15,Default,,0000,0000,0000,,different technologies. And I have been fortunate\Nto work Dialogue: 0,0:01:17.15,0:01:19.54,Default,,0000,0000,0000,,with some very smart people and be able to Dialogue: 0,0:01:19.54,0:01:21.75,Default,,0000,0000,0000,,learn from them and to break a lot of Dialogue: 0,0:01:21.75,0:01:24.90,Default,,0000,0000,0000,,things really quickly. And right now I work\Nat Dialogue: 0,0:01:24.90,0:01:28.03,Default,,0000,0000,0000,,Wanelo. Also, I'm trying to collect all of\Nthe Dialogue: 0,0:01:28.03,0:01:30.77,Default,,0000,0000,0000,,buzzwords on my resume. I have more. I have Dialogue: 0,0:01:30.77,0:01:32.07,Default,,0000,0000,0000,,more than just this. Dialogue: 0,0:01:32.07,0:01:37.04,Default,,0000,0000,0000,,But, so, why is Wanelo important? We're like\Na Dialogue: 0,0:01:37.04,0:01:40.94,Default,,0000,0000,0000,,social network for shopping, but really it's\Nbecause we Dialogue: 0,0:01:40.94,0:01:44.67,Default,,0000,0000,0000,,have many millions of users, active users,\Nand databases Dialogue: 0,0:01:44.67,0:01:46.84,Default,,0000,0000,0000,,with billions of records. And we've gone through\Nthe Dialogue: 0,0:01:46.84,0:01:50.04,Default,,0000,0000,0000,,pain of getting there and keeping the site\Nactually Dialogue: 0,0:01:50.04,0:01:54.39,Default,,0000,0000,0000,,running. So, you can save any product from\Nany Dialogue: 0,0:01:54.39,0:01:56.75,Default,,0000,0000,0000,,store on the internet into your own collections\Nand Dialogue: 0,0:01:56.75,0:01:59.89,Default,,0000,0000,0000,,have your own wishlist. That's what we do. Dialogue: 0,0:01:59.89,0:02:04.26,Default,,0000,0000,0000,,More importantly, we've gone from having this\Nas one Dialogue: 0,0:02:04.26,0:02:08.20,Default,,0000,0000,0000,,main Rails application, doing all of this,\Nto a Dialogue: 0,0:02:08.20,0:02:11.87,Default,,0000,0000,0000,,central Rails application that's still fairly\Nlarge, but supported Dialogue: 0,0:02:11.87,0:02:15.20,Default,,0000,0000,0000,,by a lot of services. We've done as much Dialogue: 0,0:02:15.20,0:02:17.34,Default,,0000,0000,0000,,as we could open source. Some of the, the Dialogue: 0,0:02:17.34,0:02:20.12,Default,,0000,0000,0000,,business domain logic, it's really hard to\Nopen source. Dialogue: 0,0:02:20.12,0:02:23.08,Default,,0000,0000,0000,,But, but we try as much as possible. Dialogue: 0,0:02:23.08,0:02:26.29,Default,,0000,0000,0000,,We've done almost all of this in Ruby, including Dialogue: 0,0:02:26.29,0:02:29.100,Default,,0000,0000,0000,,some things that people who prefer other languages\Nsay Dialogue: 0,0:02:29.100,0:02:32.55,Default,,0000,0000,0000,,can't be done in Ruby. And we've done this Dialogue: 0,0:02:32.55,0:02:36.44,Default,,0000,0000,0000,,with a very, very small team very quickly. Dialogue: 0,0:02:36.44,0:02:39.45,Default,,0000,0000,0000,,If you're like me, though, you're really not\Nso Dialogue: 0,0:02:39.45,0:02:42.47,Default,,0000,0000,0000,,interested in the success story as you're\Ninterested in, Dialogue: 0,0:02:42.47,0:02:45.66,Default,,0000,0000,0000,,how did you screw up, how did you, how Dialogue: 0,0:02:45.66,0:02:50.10,Default,,0000,0000,0000,,did you break. So, let me take you on Dialogue: 0,0:02:50.10,0:02:56.26,Default,,0000,0000,0000,,a journey to another company that a friend\Nof Dialogue: 0,0:02:56.26,0:03:03.26,Default,,0000,0000,0000,,mine once, recently, called "The Anti-Pattern\NGoldmine." Completely hypothetical Dialogue: 0,0:03:03.74,0:03:06.40,Default,,0000,0000,0000,,company. Not naming any names. That I may\Nor Dialogue: 0,0:03:06.40,0:03:07.91,Default,,0000,0000,0000,,may not have worked for. Some of you in Dialogue: 0,0:03:07.91,0:03:12.36,Default,,0000,0000,0000,,the audience may or may not have worked for. Dialogue: 0,0:03:12.36,0:03:13.62,Default,,0000,0000,0000,,After some of this story, you might think\Nyou Dialogue: 0,0:03:13.62,0:03:18.17,Default,,0000,0000,0000,,did. Come in, it's a startup. It's new. Small Dialogue: 0,0:03:18.17,0:03:20.23,Default,,0000,0000,0000,,team. And come in and say, wow. For a Dialogue: 0,0:03:20.23,0:03:26.73,Default,,0000,0000,0000,,startup, you have a lot of code that's really, Dialogue: 0,0:03:26.73,0:03:31.10,Default,,0000,0000,0000,,really tangled. It's all Rails 2 code base.\NYou Dialogue: 0,0:03:31.10,0:03:33.52,Default,,0000,0000,0000,,know, if you remember vendoring Rails, we,\Nwe did Dialogue: 0,0:03:33.52,0:03:36.38,Default,,0000,0000,0000,,that. If you remember how vendoring Rails\Ncan go Dialogue: 0,0:03:36.38,0:03:38.52,Default,,0000,0000,0000,,wrong? Yeah, yeah. Yeah, that was there. That\Nwas Dialogue: 0,0:03:38.52,0:03:40.16,Default,,0000,0000,0000,,there. Dialogue: 0,0:03:40.16,0:03:41.60,Default,,0000,0000,0000,,And I think a lot of this might have Dialogue: 0,0:03:41.60,0:03:45.71,Default,,0000,0000,0000,,come down to the fact that at least early Dialogue: 0,0:03:45.71,0:03:50.57,Default,,0000,0000,0000,,on, success of a product, success of a feature, Dialogue: 0,0:03:50.57,0:03:53.69,Default,,0000,0000,0000,,really was launching it as quickly as possible.\NAnd Dialogue: 0,0:03:53.69,0:03:56.22,Default,,0000,0000,0000,,no, no, no, no. Don't worry about that stuff. Dialogue: 0,0:03:56.22,0:03:59.85,Default,,0000,0000,0000,,Don't worry about design. And we have thirty\Nengineers Dialogue: 0,0:03:59.85,0:04:03.28,Default,,0000,0000,0000,,doing that as rapidly as possible. Like, five\Nor Dialogue: 0,0:04:03.28,0:04:06.81,Default,,0000,0000,0000,,six teams all doing that as rapidly as possible, Dialogue: 0,0:04:06.81,0:04:10.06,Default,,0000,0000,0000,,trying to get it into production. And releases\Nwere Dialogue: 0,0:04:10.06,0:04:12.100,Default,,0000,0000,0000,,a mess, you know. I'm sure a lot of Dialogue: 0,0:04:12.100,0:04:19.03,Default,,0000,0000,0000,,you can relate to this. Deployments. Multiple\Nhours with Dialogue: 0,0:04:19.03,0:04:21.45,Default,,0000,0000,0000,,all of this engineer, all these engineers\Ntrying to Dialogue: 0,0:04:21.45,0:04:23.45,Default,,0000,0000,0000,,put all of this code in as quickly as Dialogue: 0,0:04:23.45,0:04:29.41,Default,,0000,0000,0000,,possible. Invariably, deployments went wrong. Dialogue: 0,0:04:29.41,0:04:34.32,Default,,0000,0000,0000,,And eventually this got a little bit faster\Nfrom, Dialogue: 0,0:04:34.32,0:04:39.05,Default,,0000,0000,0000,,from monthly releases to weekly releases.\NBut then we Dialogue: 0,0:04:39.05,0:04:42.90,Default,,0000,0000,0000,,would have code freezes, where for three months,\Neveryone's Dialogue: 0,0:04:42.90,0:04:44.96,Default,,0000,0000,0000,,trying to cram in all the features without\Ndeploying, Dialogue: 0,0:04:44.96,0:04:46.51,Default,,0000,0000,0000,,and you can imagine where that goes. Dialogue: 0,0:04:46.51,0:04:50.14,Default,,0000,0000,0000,,And, over time, really, things are just getting\Nworse. Dialogue: 0,0:04:50.14,0:04:54.07,Default,,0000,0000,0000,,We, our rough estimates that we're trying\Nto give Dialogue: 0,0:04:54.07,0:04:57.38,Default,,0000,0000,0000,,to see how long things are gonna last come Dialogue: 0,0:04:57.38,0:04:59.00,Default,,0000,0000,0000,,back, and we say, oh, that means we were Dialogue: 0,0:04:59.00,0:05:00.68,Default,,0000,0000,0000,,deploying on this date. You know, hey, we\Ntold Dialogue: 0,0:05:00.68,0:05:02.93,Default,,0000,0000,0000,,the board, great. That's awesome. You're gonna\Ndeploy on Dialogue: 0,0:05:02.93,0:05:06.94,Default,,0000,0000,0000,,this date. Ah. Whoo. With a deadline like\Nthat, Dialogue: 0,0:05:06.94,0:05:09.45,Default,,0000,0000,0000,,the only really way to meet it is to Dialogue: 0,0:05:09.45,0:05:13.23,Default,,0000,0000,0000,,make serious shortcuts. And then as soon as\Na Dialogue: 0,0:05:13.23,0:05:18.41,Default,,0000,0000,0000,,product finishes, because we're invariably\Nmissing those deadlines, and Dialogue: 0,0:05:18.41,0:05:20.58,Default,,0000,0000,0000,,there's the next project that is supposed\Nto be Dialogue: 0,0:05:20.58,0:05:22.93,Default,,0000,0000,0000,,out in, in a week, based on the estimates Dialogue: 0,0:05:22.93,0:05:26.62,Default,,0000,0000,0000,,that you were supposed to do. Team gets dispersed. Dialogue: 0,0:05:26.62,0:05:30.58,Default,,0000,0000,0000,,Finish these new projects. And no matter how\Nworse Dialogue: 0,0:05:30.58,0:05:32.31,Default,,0000,0000,0000,,case we are in our estimates, it's just never Dialogue: 0,0:05:32.31,0:05:35.38,Default,,0000,0000,0000,,worst case enough. It just, it just keeps\Ngetting Dialogue: 0,0:05:35.38,0:05:36.51,Default,,0000,0000,0000,,worse. Dialogue: 0,0:05:36.51,0:05:39.91,Default,,0000,0000,0000,,So some of you might, might be familiar with Dialogue: 0,0:05:39.91,0:05:44.34,Default,,0000,0000,0000,,this story. So, during the course of this,\NI, Dialogue: 0,0:05:44.34,0:05:47.50,Default,,0000,0000,0000,,I, I, I think I've learned a lot. You Dialogue: 0,0:05:47.50,0:05:49.58,Default,,0000,0000,0000,,know, programming is one of the most fun careers Dialogue: 0,0:05:49.58,0:05:51.96,Default,,0000,0000,0000,,that I've, that I've had, and when it's not Dialogue: 0,0:05:51.96,0:05:55.71,Default,,0000,0000,0000,,fun, you know, you know something's wrong.\NAnd keep Dialogue: 0,0:05:55.71,0:05:58.86,Default,,0000,0000,0000,,reading about service-oriented architecture,\Nand, you know, a lot Dialogue: 0,0:05:58.86,0:06:01.97,Default,,0000,0000,0000,,of us latch onto this. This is the solution Dialogue: 0,0:06:01.97,0:06:03.69,Default,,0000,0000,0000,,to all of our problems. And you know at Dialogue: 0,0:06:03.69,0:06:06.42,Default,,0000,0000,0000,,dev ops, that's pretty cool over there. You\Nknow, Dialogue: 0,0:06:06.42,0:06:07.53,Default,,0000,0000,0000,,dev ops is the answer. That's how we're gonna Dialogue: 0,0:06:07.53,0:06:10.31,Default,,0000,0000,0000,,do services. It's just gonna, it's a done\Ndeal. Dialogue: 0,0:06:10.31,0:06:12.37,Default,,0000,0000,0000,,All we have to do is do services, dev Dialogue: 0,0:06:12.37,0:06:15.11,Default,,0000,0000,0000,,opsy, and like, we're done. Dialogue: 0,0:06:15.11,0:06:19.15,Default,,0000,0000,0000,,So around this time, I move into the operations, Dialogue: 0,0:06:19.15,0:06:22.67,Default,,0000,0000,0000,,not, not the operations team, cause dev ops.\NNot Dialogue: 0,0:06:22.67,0:06:25.22,Default,,0000,0000,0000,,the operations team. Not the team over there\Nthat Dialogue: 0,0:06:25.22,0:06:27.16,Default,,0000,0000,0000,,you just throw the things over the wall and Dialogue: 0,0:06:27.16,0:06:29.17,Default,,0000,0000,0000,,they just make it work. No, no, no. Not, Dialogue: 0,0:06:29.17,0:06:32.60,Default,,0000,0000,0000,,not the operations team at all. Dialogue: 0,0:06:32.60,0:06:36.01,Default,,0000,0000,0000,,And certainly me, a number of other people\Nin Dialogue: 0,0:06:36.01,0:06:40.60,Default,,0000,0000,0000,,the engineering team, I, I could say, really\Ndecided Dialogue: 0,0:06:40.60,0:06:44.49,Default,,0000,0000,0000,,services are the only way forward. And really\Nquickly, Dialogue: 0,0:06:44.49,0:06:47.51,Default,,0000,0000,0000,,product, and, and I don't mean an individual\Nproject Dialogue: 0,0:06:47.51,0:06:49.46,Default,,0000,0000,0000,,manager or anything like that. By product,\NI mean Dialogue: 0,0:06:49.46,0:06:52.12,Default,,0000,0000,0000,,really, all of the people, all of the teams Dialogue: 0,0:06:52.12,0:06:56.08,Default,,0000,0000,0000,,going into designing the product, planning\Nthe product, really Dialogue: 0,0:06:56.08,0:06:59.56,Default,,0000,0000,0000,,how it was going forward, they quickly come\Nto Dialogue: 0,0:06:59.56,0:07:01.72,Default,,0000,0000,0000,,the conclusion that services are really just\Nthat, just Dialogue: 0,0:07:01.72,0:07:03.94,Default,,0000,0000,0000,,that, that thing getting in the way of us Dialogue: 0,0:07:03.94,0:07:08.04,Default,,0000,0000,0000,,cranking out these features. Cause features\Nis success. Dialogue: 0,0:07:08.04,0:07:10.13,Default,,0000,0000,0000,,But at first, if at first you can't succeed, Dialogue: 0,0:07:10.13,0:07:13.22,Default,,0000,0000,0000,,I have, I have, I have learned, you know, Dialogue: 0,0:07:13.22,0:07:15.18,Default,,0000,0000,0000,,there's, there's a few things. You can take\Na Dialogue: 0,0:07:15.18,0:07:21.93,Default,,0000,0000,0000,,firm stance, breathe deeply, and become the\Nloudest person Dialogue: 0,0:07:21.93,0:07:27.33,Default,,0000,0000,0000,,in the room. Really, really helps. Also, if\Nthere's Dialogue: 0,0:07:27.33,0:07:29.74,Default,,0000,0000,0000,,anything that I've learned from my cats, it's\Nthrow Dialogue: 0,0:07:29.74,0:07:34.49,Default,,0000,0000,0000,,shit, you know. Done. It really, really helps\Nin Dialogue: 0,0:07:34.49,0:07:36.34,Default,,0000,0000,0000,,situations like this. Dialogue: 0,0:07:36.34,0:07:39.10,Default,,0000,0000,0000,,So, we, we have a few things coming up. Dialogue: 0,0:07:39.10,0:07:43.85,Default,,0000,0000,0000,,A few products. These, these aren't necessarily\Nconcurrent, these, Dialogue: 0,0:07:43.85,0:07:46.86,Default,,0000,0000,0000,,these features. These projects. But we have\Na new Dialogue: 0,0:07:46.86,0:07:51.53,Default,,0000,0000,0000,,login feature and login, in this application,\Nis as Dialogue: 0,0:07:51.53,0:07:55.40,Default,,0000,0000,0000,,homegrown as you could possibly imagine it\Ncould go Dialogue: 0,0:07:55.40,0:07:59.75,Default,,0000,0000,0000,,wrong. And it's this core, core login functionality,\Nand Dialogue: 0,0:07:59.75,0:08:01.81,Default,,0000,0000,0000,,we're like, no, no, no, no, no, no. No, Dialogue: 0,0:08:01.81,0:08:03.43,Default,,0000,0000,0000,,no, no, no, no, no. That's not going in Dialogue: 0,0:08:03.43,0:08:06.71,Default,,0000,0000,0000,,this code base. That's gonna be a new application, Dialogue: 0,0:08:06.71,0:08:10.52,Default,,0000,0000,0000,,we're. That's the only way we're gonna do\Nthis. Dialogue: 0,0:08:10.52,0:08:12.93,Default,,0000,0000,0000,,Otherwise we're just not gonna do this. It's\Ngonna Dialogue: 0,0:08:12.93,0:08:14.98,Default,,0000,0000,0000,,fail. We know it's gonna fail. So let's just Dialogue: 0,0:08:14.98,0:08:16.93,Default,,0000,0000,0000,,skip to not doing it. Dialogue: 0,0:08:16.93,0:08:22.23,Default,,0000,0000,0000,,And, also, we have this enterprise software\Nover here, Dialogue: 0,0:08:22.23,0:08:24.89,Default,,0000,0000,0000,,and we have this homegrown Rails application,\Nand all Dialogue: 0,0:08:24.89,0:08:28.08,Default,,0000,0000,0000,,the data really needs to kind of be synced Dialogue: 0,0:08:28.08,0:08:30.83,Default,,0000,0000,0000,,between it in order for the company to actually Dialogue: 0,0:08:30.83,0:08:35.70,Default,,0000,0000,0000,,work. So a lot of iterations on this, but Dialogue: 0,0:08:35.70,0:08:37.88,Default,,0000,0000,0000,,really this time, we're gonna do it right,\Nand Dialogue: 0,0:08:37.88,0:08:40.87,Default,,0000,0000,0000,,it's gonna be a, a data service. We're gonna Dialogue: 0,0:08:40.87,0:08:43.18,Default,,0000,0000,0000,,have our Enterprise software in our Rails\Napp and Dialogue: 0,0:08:43.18,0:08:45.59,Default,,0000,0000,0000,,that is totally just gonna make this an Enterprise-Rails Dialogue: 0,0:08:45.59,0:08:46.19,Default,,0000,0000,0000,,app. It's gonna be amazing. Dialogue: 0,0:08:46.19,0:08:49.93,Default,,0000,0000,0000,,And I remember saying this a lot to a Dialogue: 0,0:08:49.93,0:08:52.13,Default,,0000,0000,0000,,lot of different people. Like, we're gonna\Nscrew this Dialogue: 0,0:08:52.13,0:08:55.15,Default,,0000,0000,0000,,up. We're gonna fail. I know we're gonna fail. Dialogue: 0,0:08:55.15,0:08:56.93,Default,,0000,0000,0000,,But it's the only option that we have. It's Dialogue: 0,0:08:56.93,0:08:59.23,Default,,0000,0000,0000,,the only way that we're actually gonna be\Nable Dialogue: 0,0:08:59.23,0:09:01.47,Default,,0000,0000,0000,,to get to be able to do this and Dialogue: 0,0:09:01.47,0:09:05.36,Default,,0000,0000,0000,,succeed at some point in the future. Dialogue: 0,0:09:05.36,0:09:10.31,Default,,0000,0000,0000,,OK, so on, on a side track, hopefully this Dialogue: 0,0:09:10.31,0:09:13.75,Default,,0000,0000,0000,,is not new to very many of you, but Dialogue: 0,0:09:13.75,0:09:15.61,Default,,0000,0000,0000,,really there's a lot of different ways to\Ndo Dialogue: 0,0:09:15.61,0:09:17.96,Default,,0000,0000,0000,,service-oriented architecture. It can mean\Na lot of different Dialogue: 0,0:09:17.96,0:09:21.78,Default,,0000,0000,0000,,things. Read blog posts. You get a lot of Dialogue: 0,0:09:21.78,0:09:24.55,Default,,0000,0000,0000,,different ideas. It can be synchronous, asynchronous.\NUse a Dialogue: 0,0:09:24.55,0:09:28.28,Default,,0000,0000,0000,,message bus. Maybe some services require actually\Nhitting them Dialogue: 0,0:09:28.28,0:09:31.68,Default,,0000,0000,0000,,over HTTP, TCP sockets. You know, there's\Na lot Dialogue: 0,0:09:31.68,0:09:34.59,Default,,0000,0000,0000,,of ways of different doing, of doing this\Nkind Dialogue: 0,0:09:34.59,0:09:35.67,Default,,0000,0000,0000,,of thing. Dialogue: 0,0:09:35.67,0:09:37.68,Default,,0000,0000,0000,,But why would you really want to? So, you Dialogue: 0,0:09:37.68,0:09:39.14,Default,,0000,0000,0000,,know, scale the organization. You have a lot\Nof Dialogue: 0,0:09:39.14,0:09:41.77,Default,,0000,0000,0000,,different teams. A lot of different engineers.\NMaybe you Dialogue: 0,0:09:41.77,0:09:43.74,Default,,0000,0000,0000,,really want this team over here to just have Dialogue: 0,0:09:43.74,0:09:47.24,Default,,0000,0000,0000,,their own code base that they deploy separately.\NAlso, Dialogue: 0,0:09:47.24,0:09:48.96,Default,,0000,0000,0000,,maybe you want to outsource this to a different Dialogue: 0,0:09:48.96,0:09:50.74,Default,,0000,0000,0000,,team, and you really don't want to give all Dialogue: 0,0:09:50.74,0:09:53.05,Default,,0000,0000,0000,,of the code to the other team. You really Dialogue: 0,0:09:53.05,0:09:55.70,Default,,0000,0000,0000,,just want to isolate this and say, you know, Dialogue: 0,0:09:55.70,0:10:00.94,Default,,0000,0000,0000,,you guys over here, you know, just, here,\Nhere's Dialogue: 0,0:10:00.94,0:10:03.89,Default,,0000,0000,0000,,this. Sorry. I'm, I'm actually trying to explain\Nit Dialogue: 0,0:10:03.89,0:10:09.46,Default,,0000,0000,0000,,all gendered pronounce from my vocabulary\Nbut it's really Dialogue: 0,0:10:09.46,0:10:11.86,Default,,0000,0000,0000,,hard. Sorry. Dialogue: 0,0:10:11.86,0:10:15.54,Default,,0000,0000,0000,,So, you can also scale the code base, you Dialogue: 0,0:10:15.54,0:10:20.02,Default,,0000,0000,0000,,know. Performance of this thing over here\Nmight be Dialogue: 0,0:10:20.02,0:10:23.81,Default,,0000,0000,0000,,completely different than this thing over\Nhere, and that Dialogue: 0,0:10:23.81,0:10:25.71,Default,,0000,0000,0000,,might actually be easier in a service. You\Ncan Dialogue: 0,0:10:25.71,0:10:28.44,Default,,0000,0000,0000,,really tune the code to the work load. You Dialogue: 0,0:10:28.44,0:10:31.37,Default,,0000,0000,0000,,might have this really complicated code that,\Nfor various Dialogue: 0,0:10:31.37,0:10:33.44,Default,,0000,0000,0000,,reasons, needs to be complicated. It might\Nbe really Dialogue: 0,0:10:33.44,0:10:36.03,Default,,0000,0000,0000,,complicated functionality. But you can, you\Nmight be able Dialogue: 0,0:10:36.03,0:10:40.98,Default,,0000,0000,0000,,to hide that behind a, a clean interface.\NAn Dialogue: 0,0:10:40.98,0:10:41.56,Default,,0000,0000,0000,,API. Dialogue: 0,0:10:41.56,0:10:46.02,Default,,0000,0000,0000,,And tests, usually, not always, but a small\Ncode Dialogue: 0,0:10:46.02,0:10:49.47,Default,,0000,0000,0000,,base can mean fast tests. And if you're sitting Dialogue: 0,0:10:49.47,0:10:52.11,Default,,0000,0000,0000,,around for hours waiting for tests to complete,\Nyou Dialogue: 0,0:10:52.11,0:10:54.01,Default,,0000,0000,0000,,know, that can be, that can really eat into Dialogue: 0,0:10:54.01,0:10:56.46,Default,,0000,0000,0000,,your productivity. But it, but it comes at\Na Dialogue: 0,0:10:56.46,0:10:58.50,Default,,0000,0000,0000,,cost. All of this comes at a cost. Dialogue: 0,0:10:58.50,0:11:00.72,Default,,0000,0000,0000,,And I think one of the things that, that Dialogue: 0,0:11:00.72,0:11:04.18,Default,,0000,0000,0000,,I've been learning is that sometimes the cost\Nof Dialogue: 0,0:11:04.18,0:11:06.78,Default,,0000,0000,0000,,not doing this is greater than the cost of Dialogue: 0,0:11:06.78,0:11:10.15,Default,,0000,0000,0000,,doing. The cost of the infrastructure, new\Nservers, how Dialogue: 0,0:11:10.15,0:11:12.74,Default,,0000,0000,0000,,they talk together. It's really complicated.\NThings will go Dialogue: 0,0:11:12.74,0:11:15.13,Default,,0000,0000,0000,,wrong. But sometimes not doing this is gonna,\Nis Dialogue: 0,0:11:15.13,0:11:17.27,Default,,0000,0000,0000,,gonna mean that your productivity is going\Ndown and Dialogue: 0,0:11:17.27,0:11:20.44,Default,,0000,0000,0000,,down and down and, and it actually is more Dialogue: 0,0:11:20.44,0:11:21.15,Default,,0000,0000,0000,,costly. Dialogue: 0,0:11:21.15,0:11:24.27,Default,,0000,0000,0000,,OK, so back to these projects. We have this Dialogue: 0,0:11:24.27,0:11:27.92,Default,,0000,0000,0000,,data service. It's sometimes, I think six\Nengineers, sometimes Dialogue: 0,0:11:27.92,0:11:31.90,Default,,0000,0000,0000,,eight. I don't, I don't really remember. And\Nnine Dialogue: 0,0:11:31.90,0:11:35.75,Default,,0000,0000,0000,,months of, of work. It's really complicated,\Nlike state Dialogue: 0,0:11:35.75,0:11:38.74,Default,,0000,0000,0000,,transactions, and this is really critical\Ndata that really Dialogue: 0,0:11:38.74,0:11:43.92,Default,,0000,0000,0000,,needs to be done right. And there are, so, Dialogue: 0,0:11:43.92,0:11:46.37,Default,,0000,0000,0000,,there, there might have been, when deploying\Nit, some, Dialogue: 0,0:11:46.37,0:11:48.37,Default,,0000,0000,0000,,some slight data things. But they were fixable.\NReally Dialogue: 0,0:11:48.37,0:11:50.19,Default,,0000,0000,0000,,quickly. It was fine. There were actually\Nno major Dialogue: 0,0:11:50.19,0:11:52.45,Default,,0000,0000,0000,,data problems. Dialogue: 0,0:11:52.45,0:11:53.96,Default,,0000,0000,0000,,And there were some applications that were\Nbuilt on Dialogue: 0,0:11:53.96,0:11:57.49,Default,,0000,0000,0000,,top of this data service. And depending on\Nwho Dialogue: 0,0:11:57.49,0:12:00.52,Default,,0000,0000,0000,,you talk to, they, they were more or less Dialogue: 0,0:12:00.52,0:12:02.78,Default,,0000,0000,0000,,successful. Some people using that, these\Napplications are like, Dialogue: 0,0:12:02.78,0:12:05.74,Default,,0000,0000,0000,,oh, thank you, this did exactly what, what\NI Dialogue: 0,0:12:05.74,0:12:07.27,Default,,0000,0000,0000,,need. It's actually helping me with my workflow.\NSome Dialogue: 0,0:12:07.27,0:12:11.45,Default,,0000,0000,0000,,people are like, oh, OK. Dialogue: 0,0:12:11.45,0:12:13.33,Default,,0000,0000,0000,,But engineering, you know what, this was really\Ncritical Dialogue: 0,0:12:13.33,0:12:16.64,Default,,0000,0000,0000,,data. It was really hard. Totally new for\Nus. Dialogue: 0,0:12:16.64,0:12:19.91,Default,,0000,0000,0000,,This was a success. We did not break anything. Dialogue: 0,0:12:19.91,0:12:26.41,Default,,0000,0000,0000,,Product is like nine months? Nine months.\NEight engineers, Dialogue: 0,0:12:26.41,0:12:29.71,Default,,0000,0000,0000,,nine months. How could you possibly call that\Na Dialogue: 0,0:12:29.71,0:12:30.74,Default,,0000,0000,0000,,success? Dialogue: 0,0:12:30.74,0:12:37.02,Default,,0000,0000,0000,,OK. So different application. Login flow.\NDepending on the Dialogue: 0,0:12:37.02,0:12:39.51,Default,,0000,0000,0000,,time period, two engineers, four engineers,\Nplus the dev Dialogue: 0,0:12:39.51,0:12:46.41,Default,,0000,0000,0000,,ops team. Dev ops. Three months, you know.\NYou Dialogue: 0,0:12:46.41,0:12:50.40,Default,,0000,0000,0000,,know, we were figuring out, like, the system's\Nautomation Dialogue: 0,0:12:50.40,0:12:55.21,Default,,0000,0000,0000,,was really tangled and in, in a few weeks Dialogue: 0,0:12:55.21,0:12:59.79,Default,,0000,0000,0000,,we had some staging servers. And about two\Nmonths Dialogue: 0,0:12:59.79,0:13:02.98,Default,,0000,0000,0000,,later, someone comes up to me and says, hey, Dialogue: 0,0:13:02.98,0:13:05.29,Default,,0000,0000,0000,,where, where, where are the servers gonna,\Ngonna be? Dialogue: 0,0:13:05.29,0:13:08.18,Default,,0000,0000,0000,,Can we get those? And I'm like, deep breath. Dialogue: 0,0:13:08.18,0:13:12.27,Default,,0000,0000,0000,,Deep breath. Which servers? Oh, this, those\Nstaging servers. Dialogue: 0,0:13:12.27,0:13:16.65,Default,,0000,0000,0000,,But it went, we worked it all out. Dialogue: 0,0:13:16.65,0:13:19.03,Default,,0000,0000,0000,,Something that I learned about dev ops. Everyone\Nactually Dialogue: 0,0:13:19.03,0:13:22.96,Default,,0000,0000,0000,,needs to be invested and it's new to people. Dialogue: 0,0:13:22.96,0:13:24.100,Default,,0000,0000,0000,,So, and it was released with a feature flag. Dialogue: 0,0:13:24.100,0:13:27.50,Default,,0000,0000,0000,,Only a small amount of people were actually\Nrunning Dialogue: 0,0:13:27.50,0:13:31.06,Default,,0000,0000,0000,,through it. So it, we had some really good Dialogue: 0,0:13:31.06,0:13:34.29,Default,,0000,0000,0000,,time to break it in production and really\Nfigure Dialogue: 0,0:13:34.29,0:13:37.25,Default,,0000,0000,0000,,out how, how it was really gonna run. Dialogue: 0,0:13:37.25,0:13:38.94,Default,,0000,0000,0000,,And we launched it to all of our users, Dialogue: 0,0:13:38.94,0:13:41.93,Default,,0000,0000,0000,,and it was actually, I would say, very successful. Dialogue: 0,0:13:41.93,0:13:46.53,Default,,0000,0000,0000,,It worked exactly intended. It was very resilient\Nto Dialogue: 0,0:13:46.53,0:13:49.39,Default,,0000,0000,0000,,failures. We had to do some unexpected database\Nmaintenance. Dialogue: 0,0:13:49.39,0:13:52.23,Default,,0000,0000,0000,,Restart master databases and we're like, you\Nknow what, Dialogue: 0,0:13:52.23,0:13:54.98,Default,,0000,0000,0000,,just do it. You know, just, just restart the Dialogue: 0,0:13:54.98,0:13:56.63,Default,,0000,0000,0000,,database. No, no, no, no, no. Don't turn off Dialogue: 0,0:13:56.63,0:13:59.37,Default,,0000,0000,0000,,the service. It's gonna recover. It's gonna\Nbe fine. Dialogue: 0,0:13:59.37,0:14:02.27,Default,,0000,0000,0000,,Maybe like one user will notice. Dialogue: 0,0:14:02.27,0:14:04.22,Default,,0000,0000,0000,,And the company's actually sort of figuring\Nout that Dialogue: 0,0:14:04.22,0:14:07.98,Default,,0000,0000,0000,,user metrics might be more important than\Ndates as Dialogue: 0,0:14:07.98,0:14:12.21,Default,,0000,0000,0000,,metrics, and the user metrics were generally\Nsuccessful. So Dialogue: 0,0:14:12.21,0:14:15.04,Default,,0000,0000,0000,,engineering, like, this, this is good. This\Nis good. Dialogue: 0,0:14:15.04,0:14:17.33,Default,,0000,0000,0000,,This is, this is how we do this. This Dialogue: 0,0:14:17.33,0:14:19.72,Default,,0000,0000,0000,,is, you know, the next project, this is how Dialogue: 0,0:14:19.72,0:14:22.01,Default,,0000,0000,0000,,we're gonna, we're gonna have to figure this. Dialogue: 0,0:14:22.01,0:14:25.20,Default,,0000,0000,0000,,And products is like three months? What are\Nyou Dialogue: 0,0:14:25.20,0:14:28.30,Default,,0000,0000,0000,,talking about? Success? That's not success.\NWe have these Dialogue: 0,0:14:28.30,0:14:30.74,Default,,0000,0000,0000,,other product features that needed to be done.\NAnd Dialogue: 0,0:14:30.74,0:14:32.30,Default,,0000,0000,0000,,we have these four engineers that are sitting\Nin Dialogue: 0,0:14:32.30,0:14:35.74,Default,,0000,0000,0000,,the corner, not able to do these things. Dialogue: 0,0:14:35.74,0:14:41.63,Default,,0000,0000,0000,,OK. So I would say that this is a Dialogue: 0,0:14:41.63,0:14:44.35,Default,,0000,0000,0000,,really important question to ask. What is,\Nwhat is Dialogue: 0,0:14:44.35,0:14:47.64,Default,,0000,0000,0000,,success? If engineering says it's a success,\Nand product Dialogue: 0,0:14:47.64,0:14:52.30,Default,,0000,0000,0000,,says it's a failure, who really wins? So,\Nthis Dialogue: 0,0:14:52.30,0:14:55.64,Default,,0000,0000,0000,,is actually a trick question, because it's\Na zero-sum Dialogue: 0,0:14:55.64,0:14:59.45,Default,,0000,0000,0000,,game. Like, nobody wins in this interaction. Dialogue: 0,0:14:59.45,0:15:00.80,Default,,0000,0000,0000,,So let's go a little bit deeper to ask Dialogue: 0,0:15:00.80,0:15:04.83,Default,,0000,0000,0000,,why we needed SOA in the first place. And, Dialogue: 0,0:15:04.83,0:15:07.92,Default,,0000,0000,0000,,I, this is really complicated. There's lots\Nof moving Dialogue: 0,0:15:07.92,0:15:09.80,Default,,0000,0000,0000,,parts, but some of the things that, that I Dialogue: 0,0:15:09.80,0:15:14.62,Default,,0000,0000,0000,,think now were because engineering didn't\Ntrust product, and Dialogue: 0,0:15:14.62,0:15:16.67,Default,,0000,0000,0000,,we actually didn't, what that really means\Nis we Dialogue: 0,0:15:16.67,0:15:21.70,Default,,0000,0000,0000,,didn't trust that we could do our jobs well Dialogue: 0,0:15:21.70,0:15:24.19,Default,,0000,0000,0000,,given the shortcuts that we needed to do to Dialogue: 0,0:15:24.19,0:15:28.04,Default,,0000,0000,0000,,actually do our job and actually meet our\Nmetrics. Dialogue: 0,0:15:28.04,0:15:30.44,Default,,0000,0000,0000,,And product didn't trust engineering to meet\Nthe products Dialogue: 0,0:15:30.44,0:15:32.96,Default,,0000,0000,0000,,we were given, and we, we couldn't actually\Nmeet Dialogue: 0,0:15:32.96,0:15:37.72,Default,,0000,0000,0000,,those promises. And, again, over time, this\Nwas changing, Dialogue: 0,0:15:37.72,0:15:40.98,Default,,0000,0000,0000,,but product was accountable for features,\Nnot or quality, Dialogue: 0,0:15:40.98,0:15:44.99,Default,,0000,0000,0000,,and, and the actual how users interacted with\Nthem. Dialogue: 0,0:15:44.99,0:15:47.53,Default,,0000,0000,0000,,And this is probably the subject of much more Dialogue: 0,0:15:47.53,0:15:49.73,Default,,0000,0000,0000,,discussion, and would love to continue this\Nand, and Dialogue: 0,0:15:49.73,0:15:51.43,Default,,0000,0000,0000,,learn more myself, but I think that a lot Dialogue: 0,0:15:51.43,0:15:55.85,Default,,0000,0000,0000,,of this comes down to trust. If, if, if Dialogue: 0,0:15:55.85,0:15:57.59,Default,,0000,0000,0000,,you can't trust that you can do your job Dialogue: 0,0:15:57.59,0:15:59.69,Default,,0000,0000,0000,,successfully, how, how can you actually do\Nyour job Dialogue: 0,0:15:59.69,0:16:02.04,Default,,0000,0000,0000,,successfully? If, if product, if different\Nparts of the Dialogue: 0,0:16:02.04,0:16:04.29,Default,,0000,0000,0000,,company don't trust each other to do their\Njobs Dialogue: 0,0:16:04.29,0:16:07.25,Default,,0000,0000,0000,,well, how can they actually do their jobs\Nwell? Dialogue: 0,0:16:07.25,0:16:10.69,Default,,0000,0000,0000,,So, what did, what did we learn? You know, Dialogue: 0,0:16:10.69,0:16:13.54,Default,,0000,0000,0000,,fuck it, next time it's SOA from the beginning. Dialogue: 0,0:16:13.54,0:16:15.69,Default,,0000,0000,0000,,Like, before we even do Rails new it's gonna Dialogue: 0,0:16:15.69,0:16:19.22,Default,,0000,0000,0000,,be RabbitMQ. We're gonna have a cluster. It's\Ngonna Dialogue: 0,0:16:19.22,0:16:22.67,Default,,0000,0000,0000,,be amazing. So, no. No, no, no. Not, not, Dialogue: 0,0:16:22.67,0:16:26.17,Default,,0000,0000,0000,,not the right answer. I almost went here,\Nand Dialogue: 0,0:16:26.17,0:16:29.96,Default,,0000,0000,0000,,thankfully I worked, then, with some very\Nhumble, empathetic Dialogue: 0,0:16:29.96,0:16:32.65,Default,,0000,0000,0000,,people, who were also very convincing. No. Dialogue: 0,0:16:32.65,0:16:36.65,Default,,0000,0000,0000,,So, I think what I've, what I have really Dialogue: 0,0:16:36.65,0:16:39.48,Default,,0000,0000,0000,,taken from this, is Agile's not just one sprint Dialogue: 0,0:16:39.48,0:16:42.11,Default,,0000,0000,0000,,after the next. It's like four miles is great. Dialogue: 0,0:16:42.11,0:16:44.57,Default,,0000,0000,0000,,You just break it up into a hundred meter Dialogue: 0,0:16:44.57,0:16:46.85,Default,,0000,0000,0000,,increments and you just, each one is a sprint. Dialogue: 0,0:16:46.85,0:16:48.33,Default,,0000,0000,0000,,It's gonna be fine. Dialogue: 0,0:16:48.33,0:16:52.47,Default,,0000,0000,0000,,What this really is about iterating. Deploying\Nthings, small Dialogue: 0,0:16:52.47,0:16:54.21,Default,,0000,0000,0000,,things, really quickly, using the data that\Nyou get Dialogue: 0,0:16:54.21,0:16:57.32,Default,,0000,0000,0000,,from that to figure out what to do next, Dialogue: 0,0:16:57.32,0:17:00.67,Default,,0000,0000,0000,,and refactoring. Refactoring is really, really\Nimportant. You might Dialogue: 0,0:17:00.67,0:17:03.98,Default,,0000,0000,0000,,be able to do a small thing quickly, and Dialogue: 0,0:17:03.98,0:17:07.99,Default,,0000,0000,0000,,with some shortcuts, not really needing to\Nknow how Dialogue: 0,0:17:07.99,0:17:09.99,Default,,0000,0000,0000,,it needs to be designed. But when you see Dialogue: 0,0:17:09.99,0:17:13.00,Default,,0000,0000,0000,,the pattern, you, you have to fix it. And Dialogue: 0,0:17:13.00,0:17:16.67,Default,,0000,0000,0000,,SOA's not gonna solve larger organizational\Nproblems. Dialogue: 0,0:17:16.67,0:17:19.98,Default,,0000,0000,0000,,It's not gonna fix your code. Really what\Nit Dialogue: 0,0:17:19.98,0:17:24.18,Default,,0000,0000,0000,,is is another tool at our disposal to solve Dialogue: 0,0:17:24.18,0:17:27.46,Default,,0000,0000,0000,,our pain points, and our, and our organization's,\Nour Dialogue: 0,0:17:27.46,0:17:31.09,Default,,0000,0000,0000,,company's pain points. And how we do that\Nis Dialogue: 0,0:17:31.09,0:17:38.04,Default,,0000,0000,0000,,through iteration. So, small changes deployed,\Ndeployed quickly, using Dialogue: 0,0:17:38.04,0:17:40.48,Default,,0000,0000,0000,,feature flags so that you can actually get\Ncode Dialogue: 0,0:17:40.48,0:17:43.32,Default,,0000,0000,0000,,into production as soon as possible, knowing\Nthat it's Dialogue: 0,0:17:43.32,0:17:46.39,Default,,0000,0000,0000,,off and it's not gonna affect users. And prioritizing Dialogue: 0,0:17:46.39,0:17:48.49,Default,,0000,0000,0000,,this when it's necessary. Dialogue: 0,0:17:48.49,0:17:51.63,Default,,0000,0000,0000,,So when might it be necessary? I would say Dialogue: 0,0:17:51.63,0:17:53.37,Default,,0000,0000,0000,,performance. That's a really big thing. This\Nis actually Dialogue: 0,0:17:53.37,0:17:57.77,Default,,0000,0000,0000,,driving a lot of what we're doing. Code complexity Dialogue: 0,0:17:57.77,0:17:59.74,Default,,0000,0000,0000,,might be less in a service than it would Dialogue: 0,0:17:59.74,0:18:02.38,Default,,0000,0000,0000,,be outside of a service. So if you have Dialogue: 0,0:18:02.38,0:18:03.80,Default,,0000,0000,0000,,these two things and you're like, this is\Nactually Dialogue: 0,0:18:03.80,0:18:05.49,Default,,0000,0000,0000,,gonna be easier to do over here than to Dialogue: 0,0:18:05.49,0:18:07.81,Default,,0000,0000,0000,,put in this tangled mess, maybe, maybe it\Nis Dialogue: 0,0:18:07.81,0:18:08.34,Default,,0000,0000,0000,,better. Dialogue: 0,0:18:08.34,0:18:10.96,Default,,0000,0000,0000,,May, and also maybe, sometimes you have a\Nnew Dialogue: 0,0:18:10.96,0:18:14.22,Default,,0000,0000,0000,,feature and it is completely unrelated to\Neverything else Dialogue: 0,0:18:14.22,0:18:18.37,Default,,0000,0000,0000,,that you've already done. With the caveat\Nthat you, Dialogue: 0,0:18:18.37,0:18:19.32,Default,,0000,0000,0000,,in the short term, you might be able to Dialogue: 0,0:18:19.32,0:18:20.71,Default,,0000,0000,0000,,put it in with all the rest of that Dialogue: 0,0:18:20.71,0:18:24.85,Default,,0000,0000,0000,,mess, trusting that when it becomes a problem\Nyou Dialogue: 0,0:18:24.85,0:18:27.54,Default,,0000,0000,0000,,will be empowered to fix that problem. Dialogue: 0,0:18:27.54,0:18:31.75,Default,,0000,0000,0000,,OK. So, performance. As I said, this is driving Dialogue: 0,0:18:31.75,0:18:35.18,Default,,0000,0000,0000,,a lot of, of our work. So, Winelow is Dialogue: 0,0:18:35.18,0:18:38.43,Default,,0000,0000,0000,,getting slower. We're running into some problems.\NWe just Dialogue: 0,0:18:38.43,0:18:41.01,Default,,0000,0000,0000,,got ring that the databases are becoming I/O\Nbound Dialogue: 0,0:18:41.01,0:18:42.89,Default,,0000,0000,0000,,on disk. This is a really, really bad place Dialogue: 0,0:18:42.89,0:18:47.36,Default,,0000,0000,0000,,to be. But our user growth is increasing dramatically. Dialogue: 0,0:18:47.36,0:18:50.85,Default,,0000,0000,0000,,The, the activity is increasing dramatically.\NWe're starting to Dialogue: 0,0:18:50.85,0:18:54.82,Default,,0000,0000,0000,,see exponential tendencies in our graphs,\Nand if you Dialogue: 0,0:18:54.82,0:18:59.35,Default,,0000,0000,0000,,see exponential tendencies in your user graphs,\Nit's kind Dialogue: 0,0:18:59.35,0:19:02.30,Default,,0000,0000,0000,,of like giving a talk to hundreds of people. Dialogue: 0,0:19:02.30,0:19:06.21,Default,,0000,0000,0000,,You're like, why are you all looking at me?! Dialogue: 0,0:19:06.21,0:19:09.90,Default,,0000,0000,0000,,It's, it can be scary. It can be really Dialogue: 0,0:19:09.90,0:19:13.76,Default,,0000,0000,0000,,scary. But we have, so we have one table Dialogue: 0,0:19:13.76,0:19:16.63,Default,,0000,0000,0000,,that's really outstripping the others, and\Nthat's causing problems. Dialogue: 0,0:19:16.63,0:19:19.24,Default,,0000,0000,0000,,That's, it's, we discover, because of our\Ndata, because Dialogue: 0,0:19:19.24,0:19:22.15,Default,,0000,0000,0000,,of our graphs, that it's really one table\Nthat's Dialogue: 0,0:19:22.15,0:19:24.86,Default,,0000,0000,0000,,really destroying the performance of the rest\Nof the Dialogue: 0,0:19:24.86,0:19:28.23,Default,,0000,0000,0000,,table. And we're in the cloud, cause we have Dialogue: 0,0:19:28.23,0:19:31.63,Default,,0000,0000,0000,,all those buzzwords. So there's really a maximum\Nsize Dialogue: 0,0:19:31.63,0:19:34.01,Default,,0000,0000,0000,,of a host that we can get. So there's Dialogue: 0,0:19:34.01,0:19:36.08,Default,,0000,0000,0000,,really, like, an upper limit of how much we Dialogue: 0,0:19:36.08,0:19:38.55,Default,,0000,0000,0000,,can actually solve this with one database. Dialogue: 0,0:19:38.55,0:19:42.63,Default,,0000,0000,0000,,Even after read-write splitting, we've already\Ndone that, and Dialogue: 0,0:19:42.63,0:19:45.45,Default,,0000,0000,0000,,we, and, and pretty soon, we realized that\Nthe Dialogue: 0,0:19:45.45,0:19:48.76,Default,,0000,0000,0000,,site is gonna break. If we don't do anything, Dialogue: 0,0:19:48.76,0:19:51.25,Default,,0000,0000,0000,,we're just not gonna have a company anymore.\NIt's Dialogue: 0,0:19:51.25,0:19:55.83,Default,,0000,0000,0000,,just gonna, it's gonna fall down. But, we\Nhave Dialogue: 0,0:19:55.83,0:20:00.08,Default,,0000,0000,0000,,really, really, really active committed users\Njoining us right Dialogue: 0,0:20:00.08,0:20:03.08,Default,,0000,0000,0000,,now. Now is not the time to stop feature-development. Dialogue: 0,0:20:03.08,0:20:05.41,Default,,0000,0000,0000,,Now's the time to really learn from what our Dialogue: 0,0:20:05.41,0:20:07.96,Default,,0000,0000,0000,,users are doing, double down on it, really\Ntweak Dialogue: 0,0:20:07.96,0:20:10.25,Default,,0000,0000,0000,,our features and figure out what is gonna\Nmake Dialogue: 0,0:20:10.25,0:20:11.56,Default,,0000,0000,0000,,our business successful. Dialogue: 0,0:20:11.56,0:20:14.04,Default,,0000,0000,0000,,And we only have ten engineers at this point. Dialogue: 0,0:20:14.04,0:20:16.17,Default,,0000,0000,0000,,We don't really have that much, that many\Nresources Dialogue: 0,0:20:16.17,0:20:19.15,Default,,0000,0000,0000,,to, to, to work with this. Dialogue: 0,0:20:19.15,0:20:24.67,Default,,0000,0000,0000,,So, our first step of iteration is realizing\Nthat Dialogue: 0,0:20:24.67,0:20:26.71,Default,,0000,0000,0000,,this is one problem. How do we solve this Dialogue: 0,0:20:26.71,0:20:29.53,Default,,0000,0000,0000,,one problem? And this is maybe going to be Dialogue: 0,0:20:29.53,0:20:31.28,Default,,0000,0000,0000,,a service. How do we get to a point Dialogue: 0,0:20:31.28,0:20:32.99,Default,,0000,0000,0000,,where it can be a service? So first step Dialogue: 0,0:20:32.99,0:20:37.90,Default,,0000,0000,0000,,is isolating the data. So ActiveRecord gives\Nyou these Dialogue: 0,0:20:37.90,0:20:42.29,Default,,0000,0000,0000,,really nice things. Associations, has_many,\Nhas_one. Things that really Dialogue: 0,0:20:42.29,0:20:45.87,Default,,0000,0000,0000,,make the joins between your tables easier. Dialogue: 0,0:20:45.87,0:20:48.29,Default,,0000,0000,0000,,When you have a service, you don't have joins. Dialogue: 0,0:20:48.29,0:20:50.11,Default,,0000,0000,0000,,So these need to go away. These, these just Dialogue: 0,0:20:50.11,0:20:52.43,Default,,0000,0000,0000,,don't exist. But it's actually really easy\Nto get Dialogue: 0,0:20:52.43,0:20:57.01,Default,,0000,0000,0000,,rid of these, honestly. A product has saves,\Nyou Dialogue: 0,0:20:57.01,0:20:59.92,Default,,0000,0000,0000,,know. You save this product into a collection.\NYou Dialogue: 0,0:20:59.92,0:21:02.56,Default,,0000,0000,0000,,know, we could just take that where clause\Nthat, Dialogue: 0,0:21:02.56,0:21:04.77,Default,,0000,0000,0000,,that ActiveRecord was gonna sort of do for\Nus Dialogue: 0,0:21:04.77,0:21:08.24,Default,,0000,0000,0000,,with, with a join, and just pull it out Dialogue: 0,0:21:08.24,0:21:10.51,Default,,0000,0000,0000,,as a, as a where. Dialogue: 0,0:21:10.51,0:21:14.19,Default,,0000,0000,0000,,Really not that hard, actually. And you know\Nwhat, Dialogue: 0,0:21:14.19,0:21:16.99,Default,,0000,0000,0000,,ActiveRecord also gives us ways of talking\Nto a Dialogue: 0,0:21:16.99,0:21:20.16,Default,,0000,0000,0000,,different database. But, you know, we can\Nactually use Dialogue: 0,0:21:20.16,0:21:22.51,Default,,0000,0000,0000,,this to just pretend it's in a different database. Dialogue: 0,0:21:22.51,0:21:26.81,Default,,0000,0000,0000,,Establish connection allows you to have this\Nmodel live Dialogue: 0,0:21:26.81,0:21:28.88,Default,,0000,0000,0000,,in this database and all the rest of your Dialogue: 0,0:21:28.88,0:21:31.06,Default,,0000,0000,0000,,stuff live in your main frames. It's really\Nnot Dialogue: 0,0:21:31.06,0:21:32.31,Default,,0000,0000,0000,,that hard. Dialogue: 0,0:21:32.31,0:21:34.08,Default,,0000,0000,0000,,And, one of the key things is that each Dialogue: 0,0:21:34.08,0:21:37.39,Default,,0000,0000,0000,,step of this, each slight change, is deployable,\Nand Dialogue: 0,0:21:37.39,0:21:40.33,Default,,0000,0000,0000,,it's testable. And you can deploy it to staging. Dialogue: 0,0:21:40.33,0:21:42.62,Default,,0000,0000,0000,,You can click around to see where, where your Dialogue: 0,0:21:42.62,0:21:45.20,Default,,0000,0000,0000,,test coverage is maybe missing. Figure out\Nwhere, where Dialogue: 0,0:21:45.20,0:21:46.38,Default,,0000,0000,0000,,it breaks. And one thing is that, that I Dialogue: 0,0:21:46.38,0:21:48.30,Default,,0000,0000,0000,,will say, is you might be doubling your database Dialogue: 0,0:21:48.30,0:21:51.48,Default,,0000,0000,0000,,connections at this point. And when you database\Nhits Dialogue: 0,0:21:51.48,0:21:56.30,Default,,0000,0000,0000,,the max connections, just everything stops.\NIt just stops Dialogue: 0,0:21:56.30,0:21:57.16,Default,,0000,0000,0000,,working. Dialogue: 0,0:21:57.16,0:22:04.16,Default,,0000,0000,0000,,So, we've learned this lesson the hard way.\NBut Dialogue: 0,0:22:04.64,0:22:07.06,Default,,0000,0000,0000,,now that we have this code deployed that pretends Dialogue: 0,0:22:07.06,0:22:08.46,Default,,0000,0000,0000,,like it's in a different database, we can\Nmake Dialogue: 0,0:22:08.46,0:22:11.97,Default,,0000,0000,0000,,it a different database. Without actually\Nthat much work. Dialogue: 0,0:22:11.97,0:22:15.76,Default,,0000,0000,0000,,You have a Postgres - we love Postgres - Dialogue: 0,0:22:15.76,0:22:17.75,Default,,0000,0000,0000,,we have a master database. And we spin up Dialogue: 0,0:22:17.75,0:22:20.86,Default,,0000,0000,0000,,a replica over here, and we put the site Dialogue: 0,0:22:20.86,0:22:27.62,Default,,0000,0000,0000,,into maintenance mode. If you have more critical\Ninteractions Dialogue: 0,0:22:27.62,0:22:29.88,Default,,0000,0000,0000,,with your company that maintenance mode might,\Nmight not Dialogue: 0,0:22:29.88,0:22:33.40,Default,,0000,0000,0000,,be possible, brain tree has some really great\Nblogs Dialogue: 0,0:22:33.40,0:22:37.54,Default,,0000,0000,0000,,and, I think, talks about this. But, for us, Dialogue: 0,0:22:37.54,0:22:40.14,Default,,0000,0000,0000,,the operational overhead of making it so we\Ncan Dialogue: 0,0:22:40.14,0:22:42.69,Default,,0000,0000,0000,,do this without the site being down was way Dialogue: 0,0:22:42.69,0:22:44.00,Default,,0000,0000,0000,,more than it was worth. Dialogue: 0,0:22:44.00,0:22:45.78,Default,,0000,0000,0000,,So we just take the site down. Push in Dialogue: 0,0:22:45.78,0:22:48.20,Default,,0000,0000,0000,,new database dot yml, saying now this connection\Nis Dialogue: 0,0:22:48.20,0:22:50.31,Default,,0000,0000,0000,,talking to this database. And we just promote\Nthat Dialogue: 0,0:22:50.31,0:22:52.96,Default,,0000,0000,0000,,to master and restart everything, bring the\Nsite back, Dialogue: 0,0:22:52.96,0:22:57.51,Default,,0000,0000,0000,,and now we have two databases. Five minutes\Nof Dialogue: 0,0:22:57.51,0:23:02.35,Default,,0000,0000,0000,,downtime. Not, not that bad, actually. And\Nyou know, Dialogue: 0,0:23:02.35,0:23:03.91,Default,,0000,0000,0000,,after the fact, you can clean up. You know, Dialogue: 0,0:23:03.91,0:23:05.94,Default,,0000,0000,0000,,we have a redundant table over here. A bunch Dialogue: 0,0:23:05.94,0:23:07.58,Default,,0000,0000,0000,,of redundant tables over here. You just truncate\Nthem Dialogue: 0,0:23:07.58,0:23:11.59,Default,,0000,0000,0000,,and delete them. Very carefully. Dialogue: 0,0:23:11.59,0:23:13.82,Default,,0000,0000,0000,,Not that hard. And actually, you know what,\Nat Dialogue: 0,0:23:13.82,0:23:16.29,Default,,0000,0000,0000,,this point, you might not need a service.\NYou Dialogue: 0,0:23:16.29,0:23:18.83,Default,,0000,0000,0000,,might be done. Your site might just be working. Dialogue: 0,0:23:18.83,0:23:23.50,Default,,0000,0000,0000,,It's fine. For us, we, we knew, based on Dialogue: 0,0:23:23.50,0:23:25.92,Default,,0000,0000,0000,,how things were going, that we were gonna\Nhave Dialogue: 0,0:23:25.92,0:23:27.50,Default,,0000,0000,0000,,to horizontally shared this data. Now it's\Nin a Dialogue: 0,0:23:27.50,0:23:31.00,Default,,0000,0000,0000,,different database. That is gonna have to\Nbe many Dialogue: 0,0:23:31.00,0:23:32.33,Default,,0000,0000,0000,,databases. Dialogue: 0,0:23:32.33,0:23:34.13,Default,,0000,0000,0000,,And we want to hide that complexity. We don't, Dialogue: 0,0:23:34.13,0:23:36.21,Default,,0000,0000,0000,,we do not want our main application to have Dialogue: 0,0:23:36.21,0:23:40.47,Default,,0000,0000,0000,,any of that code. So, we know we're gonna Dialogue: 0,0:23:40.47,0:23:43.11,Default,,0000,0000,0000,,have a service. Now isolate the interface.\NAnd now Dialogue: 0,0:23:43.11,0:23:45.35,Default,,0000,0000,0000,,what this, by this, I mean, how are you Dialogue: 0,0:23:45.35,0:23:48.15,Default,,0000,0000,0000,,actually accessing this data? And what is\Nyour long-term Dialogue: 0,0:23:48.15,0:23:52.19,Default,,0000,0000,0000,,goal? You know, ours is sharding, and Wanelo\Nis Dialogue: 0,0:23:52.19,0:23:54.15,Default,,0000,0000,0000,,saves, and anytime we're actually getting\Nsaves, we're either Dialogue: 0,0:23:54.15,0:23:55.96,Default,,0000,0000,0000,,looking at by product - a product has these Dialogue: 0,0:23:55.96,0:23:57.43,Default,,0000,0000,0000,,saves - or we have it by user. A Dialogue: 0,0:23:57.43,0:23:58.77,Default,,0000,0000,0000,,user has saved these things. Dialogue: 0,0:23:58.77,0:24:01.61,Default,,0000,0000,0000,,So, this is actually really helpful, how to\Nplan Dialogue: 0,0:24:01.61,0:24:04.63,Default,,0000,0000,0000,,out what, your DSL, what your API is gonna Dialogue: 0,0:24:04.63,0:24:07.08,Default,,0000,0000,0000,,look like, you know. We know that things are Dialogue: 0,0:24:07.08,0:24:09.06,Default,,0000,0000,0000,,gonna have to get to it via product or Dialogue: 0,0:24:09.06,0:24:12.88,Default,,0000,0000,0000,,via user. And so, you have some where clauses, Dialogue: 0,0:24:12.88,0:24:15.78,Default,,0000,0000,0000,,you know. Where is ActiveRecord? We are not\Ngonna Dialogue: 0,0:24:15.78,0:24:16.68,Default,,0000,0000,0000,,have ActiveRecord. Dialogue: 0,0:24:16.68,0:24:20.17,Default,,0000,0000,0000,,So, instead a save has a by_product method\Nthat Dialogue: 0,0:24:20.17,0:24:23.34,Default,,0000,0000,0000,,is also. Oh, so one thing I will say Dialogue: 0,0:24:23.34,0:24:26.31,Default,,0000,0000,0000,,is, at this point it's really helpful to remove Dialogue: 0,0:24:26.31,0:24:28.84,Default,,0000,0000,0000,,redundancy. If you have different ways of\Naccessing kind Dialogue: 0,0:24:28.84,0:24:31.50,Default,,0000,0000,0000,,of the same data, do you really need that? Dialogue: 0,0:24:31.50,0:24:33.20,Default,,0000,0000,0000,,You know. Can you change the product to mean Dialogue: 0,0:24:33.20,0:24:35.15,Default,,0000,0000,0000,,that you don't actually have as many of these Dialogue: 0,0:24:35.15,0:24:37.82,Default,,0000,0000,0000,,fingers as you have. And very soon, things\Nare Dialogue: 0,0:24:37.82,0:24:39.85,Default,,0000,0000,0000,,gonna break. So if you don't have tests, this Dialogue: 0,0:24:39.85,0:24:44.20,Default,,0000,0000,0000,,is a really good place to add tests. Dialogue: 0,0:24:44.20,0:24:49.47,Default,,0000,0000,0000,,So, now, we have a, a small sort of Dialogue: 0,0:24:49.47,0:24:52.20,Default,,0000,0000,0000,,Ruby DSL. How do we actually pull that out? Dialogue: 0,0:24:52.20,0:24:54.35,Default,,0000,0000,0000,,And I would say, right now, it actually doesn't Dialogue: 0,0:24:54.35,0:24:56.11,Default,,0000,0000,0000,,need to be a service. Really what you need Dialogue: 0,0:24:56.11,0:24:57.49,Default,,0000,0000,0000,,is a client. And how do you build the Dialogue: 0,0:24:57.49,0:25:01.41,Default,,0000,0000,0000,,client out? And that's where adapters really\Ncome in. Dialogue: 0,0:25:01.41,0:25:03.41,Default,,0000,0000,0000,,So, we use the module. This could be a Dialogue: 0,0:25:03.41,0:25:05.19,Default,,0000,0000,0000,,base class. Some of the reasons why we thought Dialogue: 0,0:25:05.19,0:25:07.08,Default,,0000,0000,0000,,we needed a module. Maybe we didn't Maybe\Nwe Dialogue: 0,0:25:07.08,0:25:08.94,Default,,0000,0000,0000,,could have actually done this as, as a base Dialogue: 0,0:25:08.94,0:25:12.63,Default,,0000,0000,0000,,class. But now, a save is a SaveClient. And Dialogue: 0,0:25:12.63,0:25:16.71,Default,,0000,0000,0000,,that SaveClient is where your fingers go as,\Ntheir Dialogue: 0,0:25:16.71,0:25:19.92,Default,,0000,0000,0000,,class methods. And one thing I would point\Nout Dialogue: 0,0:25:19.92,0:25:23.86,Default,,0000,0000,0000,,is that that, that finder is calling through\Nto Dialogue: 0,0:25:23.86,0:25:27.09,Default,,0000,0000,0000,,an adapter. A database adapter. Dialogue: 0,0:25:27.09,0:25:29.19,Default,,0000,0000,0000,,And really, that's what's wrapping up all\Nyour database Dialogue: 0,0:25:29.19,0:25:32.96,Default,,0000,0000,0000,,calls. Hiding them from, from your application.\NAnd really Dialogue: 0,0:25:32.96,0:25:34.91,Default,,0000,0000,0000,,one of the core pieces of this is that Dialogue: 0,0:25:34.91,0:25:38.16,Default,,0000,0000,0000,,your database, your, your adapter is your\Nfeature flag. Dialogue: 0,0:25:38.16,0:25:41.00,Default,,0000,0000,0000,,It's also deployable in place, you know. You,\Nyou Dialogue: 0,0:25:41.00,0:25:42.95,Default,,0000,0000,0000,,can have this in your lib folder. You can Dialogue: 0,0:25:42.95,0:25:44.71,Default,,0000,0000,0000,,actually start a gem now. And you can just Dialogue: 0,0:25:44.71,0:25:47.72,Default,,0000,0000,0000,,deploy it and it's, your main application\Nis still Dialogue: 0,0:25:47.72,0:25:50.61,Default,,0000,0000,0000,,talking directly to this other database. But\Nyou're starting Dialogue: 0,0:25:50.61,0:25:52.91,Default,,0000,0000,0000,,to build out your client. And later, when\Nyou Dialogue: 0,0:25:52.91,0:25:54.35,Default,,0000,0000,0000,,have a service, you can replace it with a Dialogue: 0,0:25:54.35,0:25:55.63,Default,,0000,0000,0000,,different adapter. Dialogue: 0,0:25:55.63,0:25:58.94,Default,,0000,0000,0000,,So that adapter gives you back, when you,\Nwhen Dialogue: 0,0:25:58.94,0:26:02.75,Default,,0000,0000,0000,,you call, like, a, you know, you get save.by_product Dialogue: 0,0:26:02.75,0:26:04.80,Default,,0000,0000,0000,,and you call all on it, that's actually, when Dialogue: 0,0:26:04.80,0:26:11.08,Default,,0000,0000,0000,,you call by_product, you're getting back a\Nrelation. And Dialogue: 0,0:26:11.08,0:26:13.93,Default,,0000,0000,0000,,this is something that we thought we didn't\Nneed, Dialogue: 0,0:26:13.93,0:26:16.80,Default,,0000,0000,0000,,but turns out ActiveRecord does this for very\Ngood Dialogue: 0,0:26:16.80,0:26:20.64,Default,,0000,0000,0000,,reason, and that's because threads and because\Nstate. Dialogue: 0,0:26:20.64,0:26:23.37,Default,,0000,0000,0000,,If you say I want this type of data Dialogue: 0,0:26:23.37,0:26:25.59,Default,,0000,0000,0000,,and you save it away to a variable, and Dialogue: 0,0:26:25.59,0:26:28.64,Default,,0000,0000,0000,,now you call some other method, order.by_this,\Nand it Dialogue: 0,0:26:28.64,0:26:31.38,Default,,0000,0000,0000,,changes state, you might do something else\Non this Dialogue: 0,0:26:31.38,0:26:34.34,Default,,0000,0000,0000,,variable over here, not realizing that you've\Naltered its Dialogue: 0,0:26:34.34,0:26:36.51,Default,,0000,0000,0000,,state later. So any time you make a change, Dialogue: 0,0:26:36.51,0:26:38.13,Default,,0000,0000,0000,,a state change on these objects, you really\Nwant Dialogue: 0,0:26:38.13,0:26:40.36,Default,,0000,0000,0000,,to get back a new instance. A different instance Dialogue: 0,0:26:40.36,0:26:43.41,Default,,0000,0000,0000,,with different state. And when you call, you\Nknow, Dialogue: 0,0:26:43.41,0:26:45.78,Default,,0000,0000,0000,,all, first, or pluck any of these things,\Nwhat Dialogue: 0,0:26:45.78,0:26:49.40,Default,,0000,0000,0000,,you're really calling it on is your relation\Ninstance. Dialogue: 0,0:26:49.40,0:26:52.10,Default,,0000,0000,0000,,And the, the key thing that we learned is Dialogue: 0,0:26:52.10,0:26:55.00,Default,,0000,0000,0000,,that that relation is sharable between all\Nof your Dialogue: 0,0:26:55.00,0:26:57.15,Default,,0000,0000,0000,,adapters. So the actual work done to get the Dialogue: 0,0:26:57.15,0:27:00.99,Default,,0000,0000,0000,,data is on your adapters. So the relation\Ndelegates Dialogue: 0,0:27:00.99,0:27:03.03,Default,,0000,0000,0000,,back. Dialogue: 0,0:27:03.03,0:27:07.98,Default,,0000,0000,0000,,So, in our database adapter, the thing actually\Ngetting Dialogue: 0,0:27:07.98,0:27:11.56,Default,,0000,0000,0000,,the data, is ActiveRecord. We've just moved\Nour ActiveRecord Dialogue: 0,0:27:11.56,0:27:14.08,Default,,0000,0000,0000,,class into the library and hidden it from\Nour Dialogue: 0,0:27:14.08,0:27:18.50,Default,,0000,0000,0000,,application. We, in this case, we were using\NActiveRecord, Dialogue: 0,0:27:18.50,0:27:20.97,Default,,0000,0000,0000,,so you could just, we'd do ActiveRecord. If\Nyou Dialogue: 0,0:27:20.97,0:27:23.73,Default,,0000,0000,0000,,have another favorite database adapter, great. Dialogue: 0,0:27:23.73,0:27:30.59,Default,,0000,0000,0000,,So you call Save.by_product. You, you get\Nan adapter Dialogue: 0,0:27:30.59,0:27:34.53,Default,,0000,0000,0000,,that, or so the, sorry, that calls through\Nto Dialogue: 0,0:27:34.53,0:27:38.01,Default,,0000,0000,0000,,the adapter and gives you back relation. You\Ncall Dialogue: 0,0:27:38.01,0:27:40.86,Default,,0000,0000,0000,,Relation dot all and that just delegates back\Nto Dialogue: 0,0:27:40.86,0:27:44.76,Default,,0000,0000,0000,,the adapter, which calls through to an ActiveRecord,\Ngets Dialogue: 0,0:27:44.76,0:27:48.38,Default,,0000,0000,0000,,to your data, takes the attributes out of\Nit Dialogue: 0,0:27:48.38,0:27:50.26,Default,,0000,0000,0000,,and gives you back an instance of, of your Dialogue: 0,0:27:50.26,0:27:52.46,Default,,0000,0000,0000,,core class. Because you're hiding ActiveRecord.\NYou don't want Dialogue: 0,0:27:52.46,0:27:55.25,Default,,0000,0000,0000,,to get back an ActiveRecord class. Dialogue: 0,0:27:55.25,0:27:56.74,Default,,0000,0000,0000,,And I would say it's critical to deploy at Dialogue: 0,0:27:56.74,0:28:00.20,Default,,0000,0000,0000,,this steps, because you've made mistakes.\NI guarantee you've Dialogue: 0,0:28:00.20,0:28:02.57,Default,,0000,0000,0000,,made mistakes. And the cost of fixing this\Nis Dialogue: 0,0:28:02.57,0:28:06.05,Default,,0000,0000,0000,,really low right now, as opposed to spending\Na Dialogue: 0,0:28:06.05,0:28:08.16,Default,,0000,0000,0000,,lot of time trying to design your server,\Nhow Dialogue: 0,0:28:08.16,0:28:09.94,Default,,0000,0000,0000,,that's going to interact, and realize, whoa,\Nwhoa, whoa, Dialogue: 0,0:28:09.94,0:28:11.75,Default,,0000,0000,0000,,whoa, we screwed up the client. All of this Dialogue: 0,0:28:11.75,0:28:13.78,Default,,0000,0000,0000,,work we've done on the service, we have to Dialogue: 0,0:28:13.78,0:28:17.47,Default,,0000,0000,0000,,through away because we did it wrong. Dialogue: 0,0:28:17.47,0:28:20.94,Default,,0000,0000,0000,,Now, you have a client. Now you need a Dialogue: 0,0:28:20.94,0:28:24.68,Default,,0000,0000,0000,,server. And it doesn't matter. What, whatever\Nyou want. Dialogue: 0,0:28:24.68,0:28:27.21,Default,,0000,0000,0000,,It's fine. It's actually the, the cost of\Nwriting Dialogue: 0,0:28:27.21,0:28:31.44,Default,,0000,0000,0000,,this is really, really low. Because the server\Nis Dialogue: 0,0:28:31.44,0:28:34.22,Default,,0000,0000,0000,,the simplest part of this, and if you did Dialogue: 0,0:28:34.22,0:28:36.31,Default,,0000,0000,0000,,it wrong, if you chose the wrong transport\Nmethod, Dialogue: 0,0:28:36.31,0:28:38.72,Default,,0000,0000,0000,,mechanism, you know what? You build a new\Nadapter. Dialogue: 0,0:28:38.72,0:28:41.40,Default,,0000,0000,0000,,That's actually really quite easy. Dialogue: 0,0:28:41.40,0:28:44.35,Default,,0000,0000,0000,,So let me take a moment to just reiterate, Dialogue: 0,0:28:44.35,0:28:47.31,Default,,0000,0000,0000,,why should we have deployed by now? And I'd Dialogue: 0,0:28:47.31,0:28:49.86,Default,,0000,0000,0000,,say it's because the client is much, much\Nmore Dialogue: 0,0:28:49.86,0:28:52.61,Default,,0000,0000,0000,,complicated than the server, so your bugs\Nare in Dialogue: 0,0:28:52.61,0:28:54.51,Default,,0000,0000,0000,,the client. Your bugs are not in the server Dialogue: 0,0:28:54.51,0:28:57.93,Default,,0000,0000,0000,,at this point. And the server is going to Dialogue: 0,0:28:57.93,0:28:59.70,Default,,0000,0000,0000,,be dictated by the choices you've made in\Nthe Dialogue: 0,0:28:59.70,0:29:02.97,Default,,0000,0000,0000,,client. So if you've made wrong choices and\Nyou Dialogue: 0,0:29:02.97,0:29:07.09,Default,,0000,0000,0000,,build your server, you've built the wrong\Nserver. Dialogue: 0,0:29:07.09,0:29:09.64,Default,,0000,0000,0000,,We used Sinatra and Oj, just cause it's awesome. Dialogue: 0,0:29:09.64,0:29:12.15,Default,,0000,0000,0000,,It just, it really just works. It's small\Nand Dialogue: 0,0:29:12.15,0:29:15.71,Default,,0000,0000,0000,,it's useful. We thought we would need to move Dialogue: 0,0:29:15.71,0:29:17.80,Default,,0000,0000,0000,,away from HTTP, but we've grown a lot and Dialogue: 0,0:29:17.80,0:29:19.15,Default,,0000,0000,0000,,we haven't had to do this yet. It just Dialogue: 0,0:29:19.15,0:29:21.72,Default,,0000,0000,0000,,works. Things that we thought we would have\Nto Dialogue: 0,0:29:21.72,0:29:24.61,Default,,0000,0000,0000,,change immediately, you know, it's almost\Na year later Dialogue: 0,0:29:24.61,0:29:26.85,Default,,0000,0000,0000,,and it's just. Dialogue: 0,0:29:26.85,0:29:30.38,Default,,0000,0000,0000,,OK, so now we use the service. And that's Dialogue: 0,0:29:30.38,0:29:32.53,Default,,0000,0000,0000,,really a feature flag. You just write a new Dialogue: 0,0:29:32.53,0:29:37.21,Default,,0000,0000,0000,,adapter that talks to the service instead\Nof the Dialogue: 0,0:29:37.21,0:29:39.90,Default,,0000,0000,0000,,database. So now you call, you know, by_product,\Nyou Dialogue: 0,0:29:39.90,0:29:42.54,Default,,0000,0000,0000,,get a HTTP, it calls through to the HTTPAdapter Dialogue: 0,0:29:42.54,0:29:45.05,Default,,0000,0000,0000,,which gets you back the same time of relation. Dialogue: 0,0:29:45.05,0:29:47.43,Default,,0000,0000,0000,,When you call all on it, you know, it Dialogue: 0,0:29:47.43,0:29:49.29,Default,,0000,0000,0000,,calls adapter dot all, which now goes to an Dialogue: 0,0:29:49.29,0:29:52.30,Default,,0000,0000,0000,,HTTPClass that actually gets the JSON and\Ntakes the Dialogue: 0,0:29:52.30,0:29:54.10,Default,,0000,0000,0000,,attributes out of it and gives you back your Dialogue: 0,0:29:54.10,0:29:56.53,Default,,0000,0000,0000,,save class. You're getting back the same object\Nyou're Dialogue: 0,0:29:56.53,0:29:59.09,Default,,0000,0000,0000,,getting back as save. Dialogue: 0,0:29:59.09,0:30:03.33,Default,,0000,0000,0000,,So, retrospective. Great. We've isolated the\Ndata. We've isolated Dialogue: 0,0:30:03.33,0:30:06.42,Default,,0000,0000,0000,,the interface. We started to build our DSL.\NWe've Dialogue: 0,0:30:06.42,0:30:09.76,Default,,0000,0000,0000,,pulled that DSL out into a gem. Now we've, Dialogue: 0,0:30:09.76,0:30:11.15,Default,,0000,0000,0000,,now that we actually kind of understand what\Nthat Dialogue: 0,0:30:11.15,0:30:13.33,Default,,0000,0000,0000,,gem needs to do, we can launch the service Dialogue: 0,0:30:13.33,0:30:15.38,Default,,0000,0000,0000,,and then just build a new adapter to switch Dialogue: 0,0:30:15.38,0:30:16.43,Default,,0000,0000,0000,,to this. Dialogue: 0,0:30:16.43,0:30:18.88,Default,,0000,0000,0000,,If, I would say that if we hadn't, if Dialogue: 0,0:30:18.88,0:30:20.55,Default,,0000,0000,0000,,we had realized that this was the order that Dialogue: 0,0:30:20.55,0:30:21.95,Default,,0000,0000,0000,,we needed to do it on, we, we would Dialogue: 0,0:30:21.95,0:30:25.33,Default,,0000,0000,0000,,have done this in two weeks. Instead. So that Dialogue: 0,0:30:25.33,0:30:27.37,Default,,0000,0000,0000,,first part of it was like a day worth Dialogue: 0,0:30:27.37,0:30:31.02,Default,,0000,0000,0000,,of work. That second part of it was like, Dialogue: 0,0:30:31.02,0:30:34.47,Default,,0000,0000,0000,,three hours worth of work. And deployed immediately. Dialogue: 0,0:30:34.47,0:30:37.63,Default,,0000,0000,0000,,The, the harder part was realizing that we\Nneeded Dialogue: 0,0:30:37.63,0:30:39.71,Default,,0000,0000,0000,,an adapter. And at this point, people, we\Ndidn't Dialogue: 0,0:30:39.71,0:30:42.36,Default,,0000,0000,0000,,really see anything about hexagonal architecture.\NThis might have Dialogue: 0,0:30:42.36,0:30:45.08,Default,,0000,0000,0000,,been before some of those talks and papers\Nhave Dialogue: 0,0:30:45.08,0:30:49.04,Default,,0000,0000,0000,,been coming out. But, but it's actually really\Nuseful. Dialogue: 0,0:30:49.04,0:30:52.98,Default,,0000,0000,0000,,Tests. We, we use Sunspot for some of our Dialogue: 0,0:30:52.98,0:30:54.97,Default,,0000,0000,0000,,Solar things. And we're already used to spinning\Nup Dialogue: 0,0:30:54.97,0:30:58.88,Default,,0000,0000,0000,,a Solar instance using a gem, trap-it-up.\NYou know Dialogue: 0,0:30:58.88,0:31:03.15,Default,,0000,0000,0000,,you can do that for your integration tests.\NBut Dialogue: 0,0:31:03.15,0:31:05.45,Default,,0000,0000,0000,,for unit tests, you know what, we have tests Dialogue: 0,0:31:05.45,0:31:08.41,Default,,0000,0000,0000,,around all of this. So we can have tests Dialogue: 0,0:31:08.41,0:31:11.03,Default,,0000,0000,0000,,around a fake adapter that proves that it\Nbehaves Dialogue: 0,0:31:11.03,0:31:14.17,Default,,0000,0000,0000,,the right way, and then that just saves, saves Dialogue: 0,0:31:14.17,0:31:18.40,Default,,0000,0000,0000,,data in, in memory, in your application. Dialogue: 0,0:31:18.40,0:31:21.64,Default,,0000,0000,0000,,And redundant tests, you know, you might say,\Neh, Dialogue: 0,0:31:21.64,0:31:24.73,Default,,0000,0000,0000,,do I really need this test? Yes. Because one Dialogue: 0,0:31:24.73,0:31:26.81,Default,,0000,0000,0000,,thing, you can delete your tests later that\Nare Dialogue: 0,0:31:26.81,0:31:29.94,Default,,0000,0000,0000,,redundant, and you want to be really confident\Nthat, Dialogue: 0,0:31:29.94,0:31:34.84,Default,,0000,0000,0000,,that when you do switch over, it's gonna work. Dialogue: 0,0:31:34.84,0:31:38.70,Default,,0000,0000,0000,,Foreman and Subcontractor are, are really\Nhelpful for this Dialogue: 0,0:31:38.70,0:31:42.10,Default,,0000,0000,0000,,kind of thing. So subcontractor is a gem that Dialogue: 0,0:31:42.10,0:31:45.65,Default,,0000,0000,0000,,really says, for this service, change directory\Nover here Dialogue: 0,0:31:45.65,0:31:48.67,Default,,0000,0000,0000,,and run this command in a completely isolated\NBundler Dialogue: 0,0:31:48.67,0:31:51.59,Default,,0000,0000,0000,,environment. Cause you really don't want to\Nmix your, Dialogue: 0,0:31:51.59,0:31:55.20,Default,,0000,0000,0000,,your dependencies. You don't want your server\Ndependencies and Dialogue: 0,0:31:55.20,0:31:58.34,Default,,0000,0000,0000,,the versions to be conflicting with your main\Napplication Dialogue: 0,0:31:58.34,0:32:00.17,Default,,0000,0000,0000,,dependencies. You want to be able to, to change Dialogue: 0,0:32:00.17,0:32:01.22,Default,,0000,0000,0000,,those separately. Dialogue: 0,0:32:01.22,0:32:03.54,Default,,0000,0000,0000,,OK. So what about a new app? I'm spinning Dialogue: 0,0:32:03.54,0:32:07.35,Default,,0000,0000,0000,,up a completely new thing. Not extracting.\NTotally new. Dialogue: 0,0:32:07.35,0:32:09.39,Default,,0000,0000,0000,,How do I do that? How do I iterate Dialogue: 0,0:32:09.39,0:32:12.22,Default,,0000,0000,0000,,on something that doesn't exist yet? And I\Nwould Dialogue: 0,0:32:12.22,0:32:13.95,Default,,0000,0000,0000,,say that some of the lessons that, that we've Dialogue: 0,0:32:13.95,0:32:16.07,Default,,0000,0000,0000,,learned from this, and actually from just\Ndoing our Dialogue: 0,0:32:16.07,0:32:20.47,Default,,0000,0000,0000,,product development in general is iterate.\NFind a way Dialogue: 0,0:32:20.47,0:32:23.43,Default,,0000,0000,0000,,to get to the smallest deployable thing as\Nquickly Dialogue: 0,0:32:23.43,0:32:27.59,Default,,0000,0000,0000,,as possible, and whatever tool you use to\Ndeploy, Dialogue: 0,0:32:27.59,0:32:30.71,Default,,0000,0000,0000,,to spin up infrastructure, one of the sort\Nof Dialogue: 0,0:32:30.71,0:32:35.08,Default,,0000,0000,0000,,heuristics that, that, that we've found is\Nreally focus Dialogue: 0,0:32:35.08,0:32:37.77,Default,,0000,0000,0000,,on organizing that code around being able\Nto change Dialogue: 0,0:32:37.77,0:32:41.71,Default,,0000,0000,0000,,things easily, and understand how this thing\Nis different Dialogue: 0,0:32:41.71,0:32:42.75,Default,,0000,0000,0000,,from this thing. Dialogue: 0,0:32:42.75,0:32:45.49,Default,,0000,0000,0000,,You know, the Chef makes it really easy to Dialogue: 0,0:32:45.49,0:32:48.76,Default,,0000,0000,0000,,define a giant hash of global state over here Dialogue: 0,0:32:48.76,0:32:50.80,Default,,0000,0000,0000,,and then just run this thing over here and Dialogue: 0,0:32:50.80,0:32:53.83,Default,,0000,0000,0000,,it's magic and it'll just do it. When you Dialogue: 0,0:32:53.83,0:32:56.42,Default,,0000,0000,0000,,actually start to spin up different services,\Nthis thing Dialogue: 0,0:32:56.42,0:32:58.94,Default,,0000,0000,0000,,is gonna need to be slightly different than\Nthis Dialogue: 0,0:32:58.94,0:33:03.05,Default,,0000,0000,0000,,thing. So how can your code make that as Dialogue: 0,0:33:03.05,0:33:05.97,Default,,0000,0000,0000,,easily understandable as possible? Dialogue: 0,0:33:05.97,0:33:10.21,Default,,0000,0000,0000,,So feature flags, also, on or off. Do customers Dialogue: 0,0:33:10.21,0:33:14.44,Default,,0000,0000,0000,,see this, or they don't. But you know what? Dialogue: 0,0:33:14.44,0:33:18.86,Default,,0000,0000,0000,,Maybe it's just kind of half on. Maybe everything, Dialogue: 0,0:33:18.86,0:33:22.67,Default,,0000,0000,0000,,every request that's gonna actually call through\Nthis, use Dialogue: 0,0:33:22.67,0:33:26.95,Default,,0000,0000,0000,,Sidekiq to just every time, just spin off\Na Dialogue: 0,0:33:26.95,0:33:30.40,Default,,0000,0000,0000,,job to hammer your, your service. And if it Dialogue: 0,0:33:30.40,0:33:33.17,Default,,0000,0000,0000,,breaks, you've learned that before you've\Nlaunched it to, Dialogue: 0,0:33:33.17,0:33:35.43,Default,,0000,0000,0000,,to your users. There's a lot of other ways Dialogue: 0,0:33:35.43,0:33:36.70,Default,,0000,0000,0000,,you can do this. Dialogue: 0,0:33:36.70,0:33:39.45,Default,,0000,0000,0000,,On to these five years users, and let's see Dialogue: 0,0:33:39.45,0:33:41.93,Default,,0000,0000,0000,,how we can break it, see how the interaction Dialogue: 0,0:33:41.93,0:33:44.68,Default,,0000,0000,0000,,feels. It's, it's really useful. Dialogue: 0,0:33:44.68,0:33:48.33,Default,,0000,0000,0000,,Also, one thing that we found is, it's often Dialogue: 0,0:33:48.33,0:33:52.68,Default,,0000,0000,0000,,helpful to inter, integrate very deeply before\Nyou go Dialogue: 0,0:33:52.68,0:33:56.24,Default,,0000,0000,0000,,widely. So, if you have a code-interaction\Nthat goes Dialogue: 0,0:33:56.24,0:33:59.24,Default,,0000,0000,0000,,through all this process, do it kind of once Dialogue: 0,0:33:59.24,0:34:01.97,Default,,0000,0000,0000,,through all the process, without worrying\Nso much about Dialogue: 0,0:34:01.97,0:34:04.63,Default,,0000,0000,0000,,the edge cases or the errors, because those\Nare, Dialogue: 0,0:34:04.63,0:34:06.23,Default,,0000,0000,0000,,you're gonna find those. Those are gonna,\Nthose are Dialogue: 0,0:34:06.23,0:34:08.64,Default,,0000,0000,0000,,gonna come up. But it's re- really useful\Nto Dialogue: 0,0:34:08.64,0:34:11.07,Default,,0000,0000,0000,,kind of go all the way through the interaction Dialogue: 0,0:34:11.07,0:34:13.05,Default,,0000,0000,0000,,knowing that it's really kind of sketch and\Ndoesn't Dialogue: 0,0:34:13.05,0:34:17.76,Default,,0000,0000,0000,,do everything, and really let that drive the\Ndesign. Dialogue: 0,0:34:17.76,0:34:19.97,Default,,0000,0000,0000,,And this is also a thing of like letting Dialogue: 0,0:34:19.97,0:34:23.25,Default,,0000,0000,0000,,the feature kind of drive the design and figuring Dialogue: 0,0:34:23.25,0:34:25.31,Default,,0000,0000,0000,,out, what is the pattern for how you really Dialogue: 0,0:34:25.31,0:34:28.02,Default,,0000,0000,0000,,need to organize the code, before you have.\NDon't Dialogue: 0,0:34:28.02,0:34:29.74,Default,,0000,0000,0000,,just like whiteboard everything and say this\Nis gonna Dialogue: 0,0:34:29.74,0:34:32.34,Default,,0000,0000,0000,,be perfect. You know. Dialogue: 0,0:34:32.34,0:34:34.59,Default,,0000,0000,0000,,Production is going to destroy every single\Ndesign that Dialogue: 0,0:34:34.59,0:34:39.62,Default,,0000,0000,0000,,you think you have. Also, if something seems\Nclever, Dialogue: 0,0:34:39.62,0:34:41.90,Default,,0000,0000,0000,,it's bad. If you're like, eh, this is kind Dialogue: 0,0:34:41.90,0:34:44.14,Default,,0000,0000,0000,,of cool. No. No, no, no. It's bad. Complexity Dialogue: 0,0:34:44.14,0:34:47.55,Default,,0000,0000,0000,,is gonna come to you. Don't, don't seek it Dialogue: 0,0:34:47.55,0:34:51.24,Default,,0000,0000,0000,,out. It's, it's, it's evil. Dialogue: 0,0:34:51.24,0:34:53.11,Default,,0000,0000,0000,,So if there are any kind of take aways Dialogue: 0,0:34:53.11,0:34:57.36,Default,,0000,0000,0000,,from this, I would say you know, hexagonal\Narchitecture Dialogue: 0,0:34:57.36,0:34:59.93,Default,,0000,0000,0000,,is really cool, but you don't have to design Dialogue: 0,0:34:59.93,0:35:03.39,Default,,0000,0000,0000,,it from the start. If you have trust, if Dialogue: 0,0:35:03.39,0:35:06.88,Default,,0000,0000,0000,,everyone in the organization has trust that\Nyou can Dialogue: 0,0:35:06.88,0:35:09.11,Default,,0000,0000,0000,,do your job and that you're all going, working Dialogue: 0,0:35:09.11,0:35:13.66,Default,,0000,0000,0000,,together to build an awesome product, an awesome\Ncompany, Dialogue: 0,0:35:13.66,0:35:16.40,Default,,0000,0000,0000,,you can fix this later. You can actually let Dialogue: 0,0:35:16.40,0:35:20.78,Default,,0000,0000,0000,,the needs of your product determine where\Nyour boundaries Dialogue: 0,0:35:20.78,0:35:21.83,Default,,0000,0000,0000,,are. Dialogue: 0,0:35:21.83,0:35:27.12,Default,,0000,0000,0000,,So, thank you. I actually have a few minutes Dialogue: 0,0:35:27.12,0:35:29.88,Default,,0000,0000,0000,,of, of questions, to answer questions.