0:00:17.039,0:00:18.769 ERIC SAXBY: Thanks for coming. 0:00:18.769,0:00:21.279 So, I am Eric Saxby. Today I'm gonna be talking 0:00:21.279,0:00:24.609 about iterating towards service-oriented 0:00:24.609,0:00:28.869 architecture. I may have time for questions 0:00:28.869,0:00:30.449 at the end, but I may not. 0:00:30.449,0:00:31.380 This might go forty minutes, 0:00:31.380,0:00:32.598 so I'm just gonna get started. 0:00:32.598,0:00:35.829 So, if you're like me, you can't really pay 0:00:35.829,0:00:38.500 attention in talking about programming 0:00:38.500,0:00:39.250 unless there are pictures 0:00:39.250,0:00:44.559 of cats. So really, we're going from this[br]to 0:00:44.559,0:00:48.579 something a little bit more like this. But[br]working 0:00:48.579,0:00:50.729 together, as a family. 0:00:50.729,0:00:53.229 So why should you care? Why should you listen 0:00:53.229,0:00:57.869 to me? So you may not know this, but 0:00:57.869,0:01:01.799 I'm kind of a big deal. But, but really, 0:01:01.799,0:01:04.519 I've, I've actually not been doing this for[br]that 0:01:04.519,0:01:07.490 long. I've been doing Rails for about six[br]years. 0:01:07.490,0:01:11.490 Before and after that, I had been using various 0:01:11.490,0:01:17.149 different technologies. And I have been fortunate[br]to work 0:01:17.149,0:01:19.540 with some very smart people and be able to 0:01:19.540,0:01:21.750 learn from them and to break a lot of 0:01:21.750,0:01:24.900 things really quickly. And right now I work[br]at 0:01:24.900,0:01:28.030 Wanelo. Also, I'm trying to collect all of[br]the 0:01:28.030,0:01:30.770 buzzwords on my resume. I have more. I have 0:01:30.770,0:01:32.070 more than just this. 0:01:32.070,0:01:37.040 But, so, why is Wanelo important? We're like[br]a 0:01:37.040,0:01:40.940 social network for shopping, but really it's[br]because we 0:01:40.940,0:01:44.670 have many millions of users, active users,[br]and databases 0:01:44.670,0:01:46.840 with billions of records. And we've gone through[br]the 0:01:46.840,0:01:50.040 pain of getting there and keeping the site[br]actually 0:01:50.040,0:01:54.390 running. So, you can save any product from[br]any 0:01:54.390,0:01:56.750 store on the internet into your own collections[br]and 0:01:56.750,0:01:59.890 have your own wishlist. That's what we do. 0:01:59.890,0:02:04.260 More importantly, we've gone from having this[br]as one 0:02:04.260,0:02:08.199 main Rails application, doing all of this,[br]to a 0:02:08.199,0:02:11.870 central Rails application that's still fairly[br]large, but supported 0:02:11.870,0:02:15.200 by a lot of services. We've done as much 0:02:15.200,0:02:17.340 as we could open source. Some of the, the 0:02:17.340,0:02:20.120 business domain logic, it's really hard to[br]open source. 0:02:20.120,0:02:23.080 But, but we try as much as possible. 0:02:23.080,0:02:26.290 We've done almost all of this in Ruby, including 0:02:26.290,0:02:29.999 some things that people who prefer other languages[br]say 0:02:29.999,0:02:32.549 can't be done in Ruby. And we've done this 0:02:32.549,0:02:36.439 with a very, very small team very quickly. 0:02:36.439,0:02:39.450 If you're like me, though, you're really not[br]so 0:02:39.450,0:02:42.469 interested in the success story as you're[br]interested in, 0:02:42.469,0:02:45.659 how did you screw up, how did you, how 0:02:45.659,0:02:50.099 did you break. So, let me take you on 0:02:50.099,0:02:56.260 a journey to another company that a friend[br]of 0:02:56.260,0:03:03.260 mine once, recently, called "The Anti-Pattern[br]Goldmine." Completely hypothetical 0:03:03.739,0:03:06.400 company. Not naming any names. That I may[br]or 0:03:06.400,0:03:07.909 may not have worked for. Some of you in 0:03:07.909,0:03:12.359 the audience may or may not have worked for. 0:03:12.359,0:03:13.620 After some of this story, you might think[br]you 0:03:13.620,0:03:18.169 did. Come in, it's a startup. It's new. Small 0:03:18.169,0:03:20.230 team. And come in and say, wow. For a 0:03:20.230,0:03:26.730 startup, you have a lot of code that's really, 0:03:26.730,0:03:31.099 really tangled. It's all Rails 2 code base.[br]You 0:03:31.099,0:03:33.519 know, if you remember vendoring Rails, we,[br]we did 0:03:33.519,0:03:36.379 that. If you remember how vendoring Rails[br]can go 0:03:36.379,0:03:38.519 wrong? Yeah, yeah. Yeah, that was there. That[br]was 0:03:38.519,0:03:40.159 there. 0:03:40.159,0:03:41.599 And I think a lot of this might have 0:03:41.599,0:03:45.709 come down to the fact that at least early 0:03:45.709,0:03:50.569 on, success of a product, success of a feature, 0:03:50.569,0:03:53.689 really was launching it as quickly as possible.[br]And 0:03:53.689,0:03:56.219 no, no, no, no. Don't worry about that stuff. 0:03:56.219,0:03:59.849 Don't worry about design. And we have thirty[br]engineers 0:03:59.849,0:04:03.279 doing that as rapidly as possible. Like, five[br]or 0:04:03.279,0:04:06.809 six teams all doing that as rapidly as possible, 0:04:06.809,0:04:10.059 trying to get it into production. And releases[br]were 0:04:10.059,0:04:12.999 a mess, you know. I'm sure a lot of 0:04:12.999,0:04:19.029 you can relate to this. Deployments. Multiple[br]hours with 0:04:19.029,0:04:21.449 all of this engineer, all these engineers[br]trying to 0:04:21.449,0:04:23.449 put all of this code in as quickly as 0:04:23.449,0:04:29.410 possible. Invariably, deployments went wrong. 0:04:29.410,0:04:34.320 And eventually this got a little bit faster[br]from, 0:04:34.320,0:04:39.050 from monthly releases to weekly releases.[br]But then we 0:04:39.050,0:04:42.900 would have code freezes, where for three months,[br]everyone's 0:04:42.900,0:04:44.960 trying to cram in all the features without[br]deploying, 0:04:44.960,0:04:46.510 and you can imagine where that goes. 0:04:46.510,0:04:50.140 And, over time, really, things are just getting[br]worse. 0:04:50.140,0:04:54.070 We, our rough estimates that we're trying[br]to give 0:04:54.070,0:04:57.380 to see how long things are gonna last come 0:04:57.380,0:04:59.000 back, and we say, oh, that means we were 0:04:59.000,0:05:00.680 deploying on this date. You know, hey, we[br]told 0:05:00.680,0:05:02.930 the board, great. That's awesome. You're gonna[br]deploy on 0:05:02.930,0:05:06.940 this date. Ah. Whoo. With a deadline like[br]that, 0:05:06.940,0:05:09.450 the only really way to meet it is to 0:05:09.450,0:05:13.230 make serious shortcuts. And then as soon as[br]a 0:05:13.230,0:05:18.410 product finishes, because we're invariably[br]missing those deadlines, and 0:05:18.410,0:05:20.580 there's the next project that is supposed[br]to be 0:05:20.580,0:05:22.930 out in, in a week, based on the estimates 0:05:22.930,0:05:26.620 that you were supposed to do. Team gets dispersed. 0:05:26.620,0:05:30.580 Finish these new projects. And no matter how[br]worse 0:05:30.580,0:05:32.310 case we are in our estimates, it's just never 0:05:32.310,0:05:35.380 worst case enough. It just, it just keeps[br]getting 0:05:35.380,0:05:36.510 worse. 0:05:36.510,0:05:39.910 So some of you might, might be familiar with 0:05:39.910,0:05:44.340 this story. So, during the course of this,[br]I, 0:05:44.340,0:05:47.500 I, I, I think I've learned a lot. You 0:05:47.500,0:05:49.580 know, programming is one of the most fun careers 0:05:49.580,0:05:51.960 that I've, that I've had, and when it's not 0:05:51.960,0:05:55.710 fun, you know, you know something's wrong.[br]And keep 0:05:55.710,0:05:58.860 reading about service-oriented architecture,[br]and, you know, a lot 0:05:58.860,0:06:01.970 of us latch onto this. This is the solution 0:06:01.970,0:06:03.690 to all of our problems. And you know at 0:06:03.690,0:06:06.420 dev ops, that's pretty cool over there. You[br]know, 0:06:06.420,0:06:07.530 dev ops is the answer. That's how we're gonna 0:06:07.530,0:06:10.310 do services. It's just gonna, it's a done[br]deal. 0:06:10.310,0:06:12.370 All we have to do is do services, dev 0:06:12.370,0:06:15.110 opsy, and like, we're done. 0:06:15.110,0:06:19.150 So around this time, I move into the operations, 0:06:19.150,0:06:22.670 not, not the operations team, cause dev ops.[br]Not 0:06:22.670,0:06:25.220 the operations team. Not the team over there[br]that 0:06:25.220,0:06:27.160 you just throw the things over the wall and 0:06:27.160,0:06:29.170 they just make it work. No, no, no. Not, 0:06:29.170,0:06:32.600 not the operations team at all. 0:06:32.600,0:06:36.010 And certainly me, a number of other people[br]in 0:06:36.010,0:06:40.600 the engineering team, I, I could say, really[br]decided 0:06:40.600,0:06:44.490 services are the only way forward. And really[br]quickly, 0:06:44.490,0:06:47.510 product, and, and I don't mean an individual[br]project 0:06:47.510,0:06:49.460 manager or anything like that. By product,[br]I mean 0:06:49.460,0:06:52.120 really, all of the people, all of the teams 0:06:52.120,0:06:56.080 going into designing the product, planning[br]the product, really 0:06:56.080,0:06:59.560 how it was going forward, they quickly come[br]to 0:06:59.560,0:07:01.720 the conclusion that services are really just[br]that, just 0:07:01.720,0:07:03.940 that, that thing getting in the way of us 0:07:03.940,0:07:08.040 cranking out these features. Cause features[br]is success. 0:07:08.040,0:07:10.130 But at first, if at first you can't succeed, 0:07:10.130,0:07:13.220 I have, I have, I have learned, you know, 0:07:13.220,0:07:15.180 there's, there's a few things. You can take[br]a 0:07:15.180,0:07:21.930 firm stance, breathe deeply, and become the[br]loudest person 0:07:21.930,0:07:27.330 in the room. Really, really helps. Also, if[br]there's 0:07:27.330,0:07:29.740 anything that I've learned from my cats, it's[br]throw 0:07:29.740,0:07:34.490 shit, you know. Done. It really, really helps[br]in 0:07:34.490,0:07:36.340 situations like this. 0:07:36.340,0:07:39.100 So, we, we have a few things coming up. 0:07:39.100,0:07:43.850 A few products. These, these aren't necessarily[br]concurrent, these, 0:07:43.850,0:07:46.860 these features. These projects. But we have[br]a new 0:07:46.860,0:07:51.530 login feature and login, in this application,[br]is as 0:07:51.530,0:07:55.400 homegrown as you could possibly imagine it[br]could go 0:07:55.400,0:07:59.750 wrong. And it's this core, core login functionality,[br]and 0:07:59.750,0:08:01.810 we're like, no, no, no, no, no, no. No, 0:08:01.810,0:08:03.430 no, no, no, no, no. That's not going in 0:08:03.430,0:08:06.710 this code base. That's gonna be a new application, 0:08:06.710,0:08:10.520 we're. That's the only way we're gonna do[br]this. 0:08:10.520,0:08:12.930 Otherwise we're just not gonna do this. It's[br]gonna 0:08:12.930,0:08:14.980 fail. We know it's gonna fail. So let's just 0:08:14.980,0:08:16.930 skip to not doing it. 0:08:16.930,0:08:22.230 And, also, we have this enterprise software[br]over here, 0:08:22.230,0:08:24.889 and we have this homegrown Rails application,[br]and all 0:08:24.889,0:08:28.080 the data really needs to kind of be synced 0:08:28.080,0:08:30.830 between it in order for the company to actually 0:08:30.830,0:08:35.700 work. So a lot of iterations on this, but 0:08:35.700,0:08:37.880 really this time, we're gonna do it right,[br]and 0:08:37.880,0:08:40.870 it's gonna be a, a data service. We're gonna 0:08:40.870,0:08:43.179 have our Enterprise software in our Rails[br]app and 0:08:43.179,0:08:45.589 that is totally just gonna make this an Enterprise-Rails 0:08:45.589,0:08:46.190 app. It's gonna be amazing. 0:08:46.190,0:08:49.930 And I remember saying this a lot to a 0:08:49.930,0:08:52.129 lot of different people. Like, we're gonna[br]screw this 0:08:52.129,0:08:55.149 up. We're gonna fail. I know we're gonna fail. 0:08:55.149,0:08:56.930 But it's the only option that we have. It's 0:08:56.930,0:08:59.230 the only way that we're actually gonna be[br]able 0:08:59.230,0:09:01.470 to get to be able to do this and 0:09:01.470,0:09:05.360 succeed at some point in the future. 0:09:05.360,0:09:10.309 OK, so on, on a side track, hopefully this 0:09:10.309,0:09:13.749 is not new to very many of you, but 0:09:13.749,0:09:15.610 really there's a lot of different ways to[br]do 0:09:15.610,0:09:17.959 service-oriented architecture. It can mean[br]a lot of different 0:09:17.959,0:09:21.779 things. Read blog posts. You get a lot of 0:09:21.779,0:09:24.550 different ideas. It can be synchronous, asynchronous.[br]Use a 0:09:24.550,0:09:28.279 message bus. Maybe some services require actually[br]hitting them 0:09:28.279,0:09:31.680 over HTTP, TCP sockets. You know, there's[br]a lot 0:09:31.680,0:09:34.589 of ways of different doing, of doing this[br]kind 0:09:34.589,0:09:35.670 of thing. 0:09:35.670,0:09:37.680 But why would you really want to? So, you 0:09:37.680,0:09:39.139 know, scale the organization. You have a lot[br]of 0:09:39.139,0:09:41.769 different teams. A lot of different engineers.[br]Maybe you 0:09:41.769,0:09:43.740 really want this team over here to just have 0:09:43.740,0:09:47.240 their own code base that they deploy separately.[br]Also, 0:09:47.240,0:09:48.959 maybe you want to outsource this to a different 0:09:48.959,0:09:50.740 team, and you really don't want to give all 0:09:50.740,0:09:53.050 of the code to the other team. You really 0:09:53.050,0:09:55.699 just want to isolate this and say, you know, 0:09:55.699,0:10:00.939 you guys over here, you know, just, here,[br]here's 0:10:00.939,0:10:03.889 this. Sorry. I'm, I'm actually trying to explain[br]it 0:10:03.889,0:10:09.459 all gendered pronounce from my vocabulary[br]but it's really 0:10:09.459,0:10:11.860 hard. Sorry. 0:10:11.860,0:10:15.540 So, you can also scale the code base, you 0:10:15.540,0:10:20.019 know. Performance of this thing over here[br]might be 0:10:20.019,0:10:23.809 completely different than this thing over[br]here, and that 0:10:23.809,0:10:25.709 might actually be easier in a service. You[br]can 0:10:25.709,0:10:28.439 really tune the code to the work load. You 0:10:28.439,0:10:31.369 might have this really complicated code that,[br]for various 0:10:31.369,0:10:33.439 reasons, needs to be complicated. It might[br]be really 0:10:33.439,0:10:36.029 complicated functionality. But you can, you[br]might be able 0:10:36.029,0:10:40.980 to hide that behind a, a clean interface.[br]An 0:10:40.980,0:10:41.559 API. 0:10:41.559,0:10:46.019 And tests, usually, not always, but a small[br]code 0:10:46.019,0:10:49.470 base can mean fast tests. And if you're sitting 0:10:49.470,0:10:52.110 around for hours waiting for tests to complete,[br]you 0:10:52.110,0:10:54.009 know, that can be, that can really eat into 0:10:54.009,0:10:56.459 your productivity. But it, but it comes at[br]a 0:10:56.459,0:10:58.499 cost. All of this comes at a cost. 0:10:58.499,0:11:00.720 And I think one of the things that, that 0:11:00.720,0:11:04.180 I've been learning is that sometimes the cost[br]of 0:11:04.180,0:11:06.779 not doing this is greater than the cost of 0:11:06.779,0:11:10.149 doing. The cost of the infrastructure, new[br]servers, how 0:11:10.149,0:11:12.740 they talk together. It's really complicated.[br]Things will go 0:11:12.740,0:11:15.129 wrong. But sometimes not doing this is gonna,[br]is 0:11:15.129,0:11:17.269 gonna mean that your productivity is going[br]down and 0:11:17.269,0:11:20.439 down and down and, and it actually is more 0:11:20.439,0:11:21.149 costly. 0:11:21.149,0:11:24.269 OK, so back to these projects. We have this 0:11:24.269,0:11:27.920 data service. It's sometimes, I think six[br]engineers, sometimes 0:11:27.920,0:11:31.899 eight. I don't, I don't really remember. And[br]nine 0:11:31.899,0:11:35.749 months of, of work. It's really complicated,[br]like state 0:11:35.749,0:11:38.740 transactions, and this is really critical[br]data that really 0:11:38.740,0:11:43.920 needs to be done right. And there are, so, 0:11:43.920,0:11:46.369 there, there might have been, when deploying[br]it, some, 0:11:46.369,0:11:48.369 some slight data things. But they were fixable.[br]Really 0:11:48.369,0:11:50.189 quickly. It was fine. There were actually[br]no major 0:11:50.189,0:11:52.449 data problems. 0:11:52.449,0:11:53.959 And there were some applications that were[br]built on 0:11:53.959,0:11:57.490 top of this data service. And depending on[br]who 0:11:57.490,0:12:00.519 you talk to, they, they were more or less 0:12:00.519,0:12:02.779 successful. Some people using that, these[br]applications are like, 0:12:02.779,0:12:05.740 oh, thank you, this did exactly what, what[br]I 0:12:05.740,0:12:07.269 need. It's actually helping me with my workflow.[br]Some 0:12:07.269,0:12:11.449 people are like, oh, OK. 0:12:11.449,0:12:13.329 But engineering, you know what, this was really[br]critical 0:12:13.329,0:12:16.639 data. It was really hard. Totally new for[br]us. 0:12:16.639,0:12:19.910 This was a success. We did not break anything. 0:12:19.910,0:12:26.410 Product is like nine months? Nine months.[br]Eight engineers, 0:12:26.410,0:12:29.709 nine months. How could you possibly call that[br]a 0:12:29.709,0:12:30.740 success? 0:12:30.740,0:12:37.019 OK. So different application. Login flow.[br]Depending on the 0:12:37.019,0:12:39.509 time period, two engineers, four engineers,[br]plus the dev 0:12:39.509,0:12:46.410 ops team. Dev ops. Three months, you know.[br]You 0:12:46.410,0:12:50.399 know, we were figuring out, like, the system's[br]automation 0:12:50.399,0:12:55.209 was really tangled and in, in a few weeks 0:12:55.209,0:12:59.790 we had some staging servers. And about two[br]months 0:12:59.790,0:13:02.980 later, someone comes up to me and says, hey, 0:13:02.980,0:13:05.290 where, where, where are the servers gonna,[br]gonna be? 0:13:05.290,0:13:08.179 Can we get those? And I'm like, deep breath. 0:13:08.179,0:13:12.269 Deep breath. Which servers? Oh, this, those[br]staging servers. 0:13:12.269,0:13:16.649 But it went, we worked it all out. 0:13:16.649,0:13:19.029 Something that I learned about dev ops. Everyone[br]actually 0:13:19.029,0:13:22.959 needs to be invested and it's new to people. 0:13:22.959,0:13:24.999 So, and it was released with a feature flag. 0:13:24.999,0:13:27.499 Only a small amount of people were actually[br]running 0:13:27.499,0:13:31.059 through it. So it, we had some really good 0:13:31.059,0:13:34.290 time to break it in production and really[br]figure 0:13:34.290,0:13:37.249 out how, how it was really gonna run. 0:13:37.249,0:13:38.939 And we launched it to all of our users, 0:13:38.939,0:13:41.929 and it was actually, I would say, very successful. 0:13:41.929,0:13:46.529 It worked exactly intended. It was very resilient[br]to 0:13:46.529,0:13:49.389 failures. We had to do some unexpected database[br]maintenance. 0:13:49.389,0:13:52.230 Restart master databases and we're like, you[br]know what, 0:13:52.230,0:13:54.980 just do it. You know, just, just restart the 0:13:54.980,0:13:56.629 database. No, no, no, no, no. Don't turn off 0:13:56.629,0:13:59.369 the service. It's gonna recover. It's gonna[br]be fine. 0:13:59.369,0:14:02.269 Maybe like one user will notice. 0:14:02.269,0:14:04.220 And the company's actually sort of figuring[br]out that 0:14:04.220,0:14:07.980 user metrics might be more important than[br]dates as 0:14:07.980,0:14:12.209 metrics, and the user metrics were generally[br]successful. So 0:14:12.209,0:14:15.040 engineering, like, this, this is good. This[br]is good. 0:14:15.040,0:14:17.329 This is, this is how we do this. This 0:14:17.329,0:14:19.720 is, you know, the next project, this is how 0:14:19.720,0:14:22.009 we're gonna, we're gonna have to figure this. 0:14:22.009,0:14:25.199 And products is like three months? What are[br]you 0:14:25.199,0:14:28.300 talking about? Success? That's not success.[br]We have these 0:14:28.300,0:14:30.739 other product features that needed to be done.[br]And 0:14:30.739,0:14:32.300 we have these four engineers that are sitting[br]in 0:14:32.300,0:14:35.739 the corner, not able to do these things. 0:14:35.739,0:14:41.629 OK. So I would say that this is a 0:14:41.629,0:14:44.350 really important question to ask. What is,[br]what is 0:14:44.350,0:14:47.639 success? If engineering says it's a success,[br]and product 0:14:47.639,0:14:52.300 says it's a failure, who really wins? So,[br]this 0:14:52.300,0:14:55.639 is actually a trick question, because it's[br]a zero-sum 0:14:55.639,0:14:59.449 game. Like, nobody wins in this interaction. 0:14:59.449,0:15:00.800 So let's go a little bit deeper to ask 0:15:00.800,0:15:04.829 why we needed SOA in the first place. And, 0:15:04.829,0:15:07.920 I, this is really complicated. There's lots[br]of moving 0:15:07.920,0:15:09.800 parts, but some of the things that, that I 0:15:09.800,0:15:14.619 think now were because engineering didn't[br]trust product, and 0:15:14.619,0:15:16.670 we actually didn't, what that really means[br]is we 0:15:16.670,0:15:21.699 didn't trust that we could do our jobs well 0:15:21.699,0:15:24.189 given the shortcuts that we needed to do to 0:15:24.189,0:15:28.040 actually do our job and actually meet our[br]metrics. 0:15:28.040,0:15:30.439 And product didn't trust engineering to meet[br]the products 0:15:30.439,0:15:32.959 we were given, and we, we couldn't actually[br]meet 0:15:32.959,0:15:37.720 those promises. And, again, over time, this[br]was changing, 0:15:37.720,0:15:40.980 but product was accountable for features,[br]not or quality, 0:15:40.980,0:15:44.989 and, and the actual how users interacted with[br]them. 0:15:44.989,0:15:47.529 And this is probably the subject of much more 0:15:47.529,0:15:49.730 discussion, and would love to continue this[br]and, and 0:15:49.730,0:15:51.429 learn more myself, but I think that a lot 0:15:51.429,0:15:55.850 of this comes down to trust. If, if, if 0:15:55.850,0:15:57.589 you can't trust that you can do your job 0:15:57.589,0:15:59.689 successfully, how, how can you actually do[br]your job 0:15:59.689,0:16:02.040 successfully? If, if product, if different[br]parts of the 0:16:02.040,0:16:04.290 company don't trust each other to do their[br]jobs 0:16:04.290,0:16:07.249 well, how can they actually do their jobs[br]well? 0:16:07.249,0:16:10.689 So, what did, what did we learn? You know, 0:16:10.689,0:16:13.540 fuck it, next time it's SOA from the beginning. 0:16:13.540,0:16:15.689 Like, before we even do Rails new it's gonna 0:16:15.689,0:16:19.220 be RabbitMQ. We're gonna have a cluster. It's[br]gonna 0:16:19.220,0:16:22.670 be amazing. So, no. No, no, no. Not, not, 0:16:22.670,0:16:26.170 not the right answer. I almost went here,[br]and 0:16:26.170,0:16:29.959 thankfully I worked, then, with some very[br]humble, empathetic 0:16:29.959,0:16:32.649 people, who were also very convincing. No. 0:16:32.649,0:16:36.649 So, I think what I've, what I have really 0:16:36.649,0:16:39.480 taken from this, is Agile's not just one sprint 0:16:39.480,0:16:42.110 after the next. It's like four miles is great. 0:16:42.110,0:16:44.569 You just break it up into a hundred meter 0:16:44.569,0:16:46.850 increments and you just, each one is a sprint. 0:16:46.850,0:16:48.329 It's gonna be fine. 0:16:48.329,0:16:52.470 What this really is about iterating. Deploying[br]things, small 0:16:52.470,0:16:54.209 things, really quickly, using the data that[br]you get 0:16:54.209,0:16:57.319 from that to figure out what to do next, 0:16:57.319,0:17:00.670 and refactoring. Refactoring is really, really[br]important. You might 0:17:00.670,0:17:03.980 be able to do a small thing quickly, and 0:17:03.980,0:17:07.990 with some shortcuts, not really needing to[br]know how 0:17:07.990,0:17:09.990 it needs to be designed. But when you see 0:17:09.990,0:17:13.000 the pattern, you, you have to fix it. And 0:17:13.000,0:17:16.670 SOA's not gonna solve larger organizational[br]problems. 0:17:16.670,0:17:19.980 It's not gonna fix your code. Really what[br]it 0:17:19.980,0:17:24.180 is is another tool at our disposal to solve 0:17:24.180,0:17:27.459 our pain points, and our, and our organization's,[br]our 0:17:27.459,0:17:31.090 company's pain points. And how we do that[br]is 0:17:31.090,0:17:38.040 through iteration. So, small changes deployed,[br]deployed quickly, using 0:17:38.040,0:17:40.480 feature flags so that you can actually get[br]code 0:17:40.480,0:17:43.320 into production as soon as possible, knowing[br]that it's 0:17:43.320,0:17:46.390 off and it's not gonna affect users. And prioritizing 0:17:46.390,0:17:48.490 this when it's necessary. 0:17:48.490,0:17:51.630 So when might it be necessary? I would say 0:17:51.630,0:17:53.370 performance. That's a really big thing. This[br]is actually 0:17:53.370,0:17:57.770 driving a lot of what we're doing. Code complexity 0:17:57.770,0:17:59.740 might be less in a service than it would 0:17:59.740,0:18:02.380 be outside of a service. So if you have 0:18:02.380,0:18:03.800 these two things and you're like, this is[br]actually 0:18:03.800,0:18:05.490 gonna be easier to do over here than to 0:18:05.490,0:18:07.810 put in this tangled mess, maybe, maybe it[br]is 0:18:07.810,0:18:08.340 better. 0:18:08.340,0:18:10.960 May, and also maybe, sometimes you have a[br]new 0:18:10.960,0:18:14.220 feature and it is completely unrelated to[br]everything else 0:18:14.220,0:18:18.370 that you've already done. With the caveat[br]that you, 0:18:18.370,0:18:19.320 in the short term, you might be able to 0:18:19.320,0:18:20.710 put it in with all the rest of that 0:18:20.710,0:18:24.850 mess, trusting that when it becomes a problem[br]you 0:18:24.850,0:18:27.540 will be empowered to fix that problem. 0:18:27.540,0:18:31.750 OK. So, performance. As I said, this is driving 0:18:31.750,0:18:35.180 a lot of, of our work. So, Winelow is 0:18:35.180,0:18:38.430 getting slower. We're running into some problems.[br]We just 0:18:38.430,0:18:41.010 got ring that the databases are becoming I/O[br]bound 0:18:41.010,0:18:42.890 on disk. This is a really, really bad place 0:18:42.890,0:18:47.360 to be. But our user growth is increasing dramatically. 0:18:47.360,0:18:50.850 The, the activity is increasing dramatically.[br]We're starting to 0:18:50.850,0:18:54.820 see exponential tendencies in our graphs,[br]and if you 0:18:54.820,0:18:59.350 see exponential tendencies in your user graphs,[br]it's kind 0:18:59.350,0:19:02.300 of like giving a talk to hundreds of people. 0:19:02.300,0:19:06.210 You're like, why are you all looking at me?! 0:19:06.210,0:19:09.900 It's, it can be scary. It can be really 0:19:09.900,0:19:13.760 scary. But we have, so we have one table 0:19:13.760,0:19:16.630 that's really outstripping the others, and[br]that's causing problems. 0:19:16.630,0:19:19.240 That's, it's, we discover, because of our[br]data, because 0:19:19.240,0:19:22.150 of our graphs, that it's really one table[br]that's 0:19:22.150,0:19:24.860 really destroying the performance of the rest[br]of the 0:19:24.860,0:19:28.230 table. And we're in the cloud, cause we have 0:19:28.230,0:19:31.630 all those buzzwords. So there's really a maximum[br]size 0:19:31.630,0:19:34.010 of a host that we can get. So there's 0:19:34.010,0:19:36.080 really, like, an upper limit of how much we 0:19:36.080,0:19:38.550 can actually solve this with one database. 0:19:38.550,0:19:42.630 Even after read-write splitting, we've already[br]done that, and 0:19:42.630,0:19:45.450 we, and, and pretty soon, we realized that[br]the 0:19:45.450,0:19:48.760 site is gonna break. If we don't do anything, 0:19:48.760,0:19:51.250 we're just not gonna have a company anymore.[br]It's 0:19:51.250,0:19:55.830 just gonna, it's gonna fall down. But, we[br]have 0:19:55.830,0:20:00.080 really, really, really active committed users[br]joining us right 0:20:00.080,0:20:03.080 now. Now is not the time to stop feature-development. 0:20:03.080,0:20:05.410 Now's the time to really learn from what our 0:20:05.410,0:20:07.960 users are doing, double down on it, really[br]tweak 0:20:07.960,0:20:10.250 our features and figure out what is gonna[br]make 0:20:10.250,0:20:11.560 our business successful. 0:20:11.560,0:20:14.040 And we only have ten engineers at this point. 0:20:14.040,0:20:16.170 We don't really have that much, that many[br]resources 0:20:16.170,0:20:19.150 to, to, to work with this. 0:20:19.150,0:20:24.670 So, our first step of iteration is realizing[br]that 0:20:24.670,0:20:26.710 this is one problem. How do we solve this 0:20:26.710,0:20:29.530 one problem? And this is maybe going to be 0:20:29.530,0:20:31.280 a service. How do we get to a point 0:20:31.280,0:20:32.990 where it can be a service? So first step 0:20:32.990,0:20:37.900 is isolating the data. So ActiveRecord gives[br]you these 0:20:37.900,0:20:42.290 really nice things. Associations, has_many,[br]has_one. Things that really 0:20:42.290,0:20:45.870 make the joins between your tables easier. 0:20:45.870,0:20:48.290 When you have a service, you don't have joins. 0:20:48.290,0:20:50.110 So these need to go away. These, these just 0:20:50.110,0:20:52.430 don't exist. But it's actually really easy[br]to get 0:20:52.430,0:20:57.010 rid of these, honestly. A product has saves,[br]you 0:20:57.010,0:20:59.920 know. You save this product into a collection.[br]You 0:20:59.920,0:21:02.560 know, we could just take that where clause[br]that, 0:21:02.560,0:21:04.770 that ActiveRecord was gonna sort of do for[br]us 0:21:04.770,0:21:08.240 with, with a join, and just pull it out 0:21:08.240,0:21:10.510 as a, as a where. 0:21:10.510,0:21:14.190 Really not that hard, actually. And you know[br]what, 0:21:14.190,0:21:16.990 ActiveRecord also gives us ways of talking[br]to a 0:21:16.990,0:21:20.160 different database. But, you know, we can[br]actually use 0:21:20.160,0:21:22.510 this to just pretend it's in a different database. 0:21:22.510,0:21:26.810 Establish connection allows you to have this[br]model live 0:21:26.810,0:21:28.880 in this database and all the rest of your 0:21:28.880,0:21:31.060 stuff live in your main frames. It's really[br]not 0:21:31.060,0:21:32.310 that hard. 0:21:32.310,0:21:34.080 And, one of the key things is that each 0:21:34.080,0:21:37.390 step of this, each slight change, is deployable,[br]and 0:21:37.390,0:21:40.330 it's testable. And you can deploy it to staging. 0:21:40.330,0:21:42.620 You can click around to see where, where your 0:21:42.620,0:21:45.200 test coverage is maybe missing. Figure out[br]where, where 0:21:45.200,0:21:46.380 it breaks. And one thing is that, that I 0:21:46.380,0:21:48.300 will say, is you might be doubling your database 0:21:48.300,0:21:51.480 connections at this point. And when you database[br]hits 0:21:51.480,0:21:56.300 the max connections, just everything stops.[br]It just stops 0:21:56.300,0:21:57.160 working. 0:21:57.160,0:22:04.160 So, we've learned this lesson the hard way.[br]But 0:22:04.640,0:22:07.060 now that we have this code deployed that pretends 0:22:07.060,0:22:08.460 like it's in a different database, we can[br]make 0:22:08.460,0:22:11.970 it a different database. Without actually[br]that much work. 0:22:11.970,0:22:15.760 You have a Postgres - we love Postgres - 0:22:15.760,0:22:17.750 we have a master database. And we spin up 0:22:17.750,0:22:20.860 a replica over here, and we put the site 0:22:20.860,0:22:27.620 into maintenance mode. If you have more critical[br]interactions 0:22:27.620,0:22:29.880 with your company that maintenance mode might,[br]might not 0:22:29.880,0:22:33.400 be possible, brain tree has some really great[br]blogs 0:22:33.400,0:22:37.540 and, I think, talks about this. But, for us, 0:22:37.540,0:22:40.140 the operational overhead of making it so we[br]can 0:22:40.140,0:22:42.690 do this without the site being down was way 0:22:42.690,0:22:44.000 more than it was worth. 0:22:44.000,0:22:45.780 So we just take the site down. Push in 0:22:45.780,0:22:48.200 new database dot yml, saying now this connection[br]is 0:22:48.200,0:22:50.310 talking to this database. And we just promote[br]that 0:22:50.310,0:22:52.960 to master and restart everything, bring the[br]site back, 0:22:52.960,0:22:57.510 and now we have two databases. Five minutes[br]of 0:22:57.510,0:23:02.350 downtime. Not, not that bad, actually. And[br]you know, 0:23:02.350,0:23:03.910 after the fact, you can clean up. You know, 0:23:03.910,0:23:05.940 we have a redundant table over here. A bunch 0:23:05.940,0:23:07.580 of redundant tables over here. You just truncate[br]them 0:23:07.580,0:23:11.590 and delete them. Very carefully. 0:23:11.590,0:23:13.820 Not that hard. And actually, you know what,[br]at 0:23:13.820,0:23:16.290 this point, you might not need a service.[br]You 0:23:16.290,0:23:18.830 might be done. Your site might just be working. 0:23:18.830,0:23:23.500 It's fine. For us, we, we knew, based on 0:23:23.500,0:23:25.920 how things were going, that we were gonna[br]have 0:23:25.920,0:23:27.500 to horizontally shared this data. Now it's[br]in a 0:23:27.500,0:23:31.000 different database. That is gonna have to[br]be many 0:23:31.000,0:23:32.330 databases. 0:23:32.330,0:23:34.130 And we want to hide that complexity. We don't, 0:23:34.130,0:23:36.210 we do not want our main application to have 0:23:36.210,0:23:40.470 any of that code. So, we know we're gonna 0:23:40.470,0:23:43.110 have a service. Now isolate the interface.[br]And now 0:23:43.110,0:23:45.350 what this, by this, I mean, how are you 0:23:45.350,0:23:48.150 actually accessing this data? And what is[br]your long-term 0:23:48.150,0:23:52.190 goal? You know, ours is sharding, and Wanelo[br]is 0:23:52.190,0:23:54.150 saves, and anytime we're actually getting[br]saves, we're either 0:23:54.150,0:23:55.960 looking at by product - a product has these 0:23:55.960,0:23:57.430 saves - or we have it by user. A 0:23:57.430,0:23:58.770 user has saved these things. 0:23:58.770,0:24:01.610 So, this is actually really helpful, how to[br]plan 0:24:01.610,0:24:04.630 out what, your DSL, what your API is gonna 0:24:04.630,0:24:07.080 look like, you know. We know that things are 0:24:07.080,0:24:09.060 gonna have to get to it via product or 0:24:09.060,0:24:12.880 via user. And so, you have some where clauses, 0:24:12.880,0:24:15.780 you know. Where is ActiveRecord? We are not[br]gonna 0:24:15.780,0:24:16.680 have ActiveRecord. 0:24:16.680,0:24:20.170 So, instead a save has a by_product method[br]that 0:24:20.170,0:24:23.340 is also. Oh, so one thing I will say 0:24:23.340,0:24:26.310 is, at this point it's really helpful to remove 0:24:26.310,0:24:28.840 redundancy. If you have different ways of[br]accessing kind 0:24:28.840,0:24:31.500 of the same data, do you really need that? 0:24:31.500,0:24:33.200 You know. Can you change the product to mean 0:24:33.200,0:24:35.150 that you don't actually have as many of these 0:24:35.150,0:24:37.820 fingers as you have. And very soon, things[br]are 0:24:37.820,0:24:39.850 gonna break. So if you don't have tests, this 0:24:39.850,0:24:44.200 is a really good place to add tests. 0:24:44.200,0:24:49.470 So, now, we have a, a small sort of 0:24:49.470,0:24:52.200 Ruby DSL. How do we actually pull that out? 0:24:52.200,0:24:54.350 And I would say, right now, it actually doesn't 0:24:54.350,0:24:56.110 need to be a service. Really what you need 0:24:56.110,0:24:57.490 is a client. And how do you build the 0:24:57.490,0:25:01.410 client out? And that's where adapters really[br]come in. 0:25:01.410,0:25:03.410 So, we use the module. This could be a 0:25:03.410,0:25:05.190 base class. Some of the reasons why we thought 0:25:05.190,0:25:07.080 we needed a module. Maybe we didn't Maybe[br]we 0:25:07.080,0:25:08.940 could have actually done this as, as a base 0:25:08.940,0:25:12.630 class. But now, a save is a SaveClient. And 0:25:12.630,0:25:16.710 that SaveClient is where your fingers go as,[br]their 0:25:16.710,0:25:19.920 class methods. And one thing I would point[br]out 0:25:19.920,0:25:23.860 is that that, that finder is calling through[br]to 0:25:23.860,0:25:27.090 an adapter. A database adapter. 0:25:27.090,0:25:29.190 And really, that's what's wrapping up all[br]your database 0:25:29.190,0:25:32.960 calls. Hiding them from, from your application.[br]And really 0:25:32.960,0:25:34.910 one of the core pieces of this is that 0:25:34.910,0:25:38.160 your database, your, your adapter is your[br]feature flag. 0:25:38.160,0:25:41.000 It's also deployable in place, you know. You,[br]you 0:25:41.000,0:25:42.950 can have this in your lib folder. You can 0:25:42.950,0:25:44.710 actually start a gem now. And you can just 0:25:44.710,0:25:47.720 deploy it and it's, your main application[br]is still 0:25:47.720,0:25:50.610 talking directly to this other database. But[br]you're starting 0:25:50.610,0:25:52.910 to build out your client. And later, when[br]you 0:25:52.910,0:25:54.350 have a service, you can replace it with a 0:25:54.350,0:25:55.630 different adapter. 0:25:55.630,0:25:58.940 So that adapter gives you back, when you,[br]when 0:25:58.940,0:26:02.750 you call, like, a, you know, you get save.by_product 0:26:02.750,0:26:04.800 and you call all on it, that's actually, when 0:26:04.800,0:26:11.080 you call by_product, you're getting back a[br]relation. And 0:26:11.080,0:26:13.930 this is something that we thought we didn't[br]need, 0:26:13.930,0:26:16.800 but turns out ActiveRecord does this for very[br]good 0:26:16.800,0:26:20.640 reason, and that's because threads and because[br]state. 0:26:20.640,0:26:23.370 If you say I want this type of data 0:26:23.370,0:26:25.590 and you save it away to a variable, and 0:26:25.590,0:26:28.640 now you call some other method, order.by_this,[br]and it 0:26:28.640,0:26:31.380 changes state, you might do something else[br]on this 0:26:31.380,0:26:34.340 variable over here, not realizing that you've[br]altered its 0:26:34.340,0:26:36.510 state later. So any time you make a change, 0:26:36.510,0:26:38.130 a state change on these objects, you really[br]want 0:26:38.130,0:26:40.360 to get back a new instance. A different instance 0:26:40.360,0:26:43.410 with different state. And when you call, you[br]know, 0:26:43.410,0:26:45.780 all, first, or pluck any of these things,[br]what 0:26:45.780,0:26:49.400 you're really calling it on is your relation[br]instance. 0:26:49.400,0:26:52.100 And the, the key thing that we learned is 0:26:52.100,0:26:55.000 that that relation is sharable between all[br]of your 0:26:55.000,0:26:57.150 adapters. So the actual work done to get the 0:26:57.150,0:27:00.990 data is on your adapters. So the relation[br]delegates 0:27:00.990,0:27:03.030 back. 0:27:03.030,0:27:07.980 So, in our database adapter, the thing actually[br]getting 0:27:07.980,0:27:11.560 the data, is ActiveRecord. We've just moved[br]our ActiveRecord 0:27:11.560,0:27:14.080 class into the library and hidden it from[br]our 0:27:14.080,0:27:18.500 application. We, in this case, we were using[br]ActiveRecord, 0:27:18.500,0:27:20.970 so you could just, we'd do ActiveRecord. If[br]you 0:27:20.970,0:27:23.730 have another favorite database adapter, great. 0:27:23.730,0:27:30.590 So you call Save.by_product. You, you get[br]an adapter 0:27:30.590,0:27:34.530 that, or so the, sorry, that calls through[br]to 0:27:34.530,0:27:38.010 the adapter and gives you back relation. You[br]call 0:27:38.010,0:27:40.860 Relation dot all and that just delegates back[br]to 0:27:40.860,0:27:44.760 the adapter, which calls through to an ActiveRecord,[br]gets 0:27:44.760,0:27:48.380 to your data, takes the attributes out of[br]it 0:27:48.380,0:27:50.260 and gives you back an instance of, of your 0:27:50.260,0:27:52.460 core class. Because you're hiding ActiveRecord.[br]You don't want 0:27:52.460,0:27:55.250 to get back an ActiveRecord class. 0:27:55.250,0:27:56.740 And I would say it's critical to deploy at 0:27:56.740,0:28:00.200 this steps, because you've made mistakes.[br]I guarantee you've 0:28:00.200,0:28:02.570 made mistakes. And the cost of fixing this[br]is 0:28:02.570,0:28:06.050 really low right now, as opposed to spending[br]a 0:28:06.050,0:28:08.160 lot of time trying to design your server,[br]how 0:28:08.160,0:28:09.940 that's going to interact, and realize, whoa,[br]whoa, whoa, 0:28:09.940,0:28:11.750 whoa, we screwed up the client. All of this 0:28:11.750,0:28:13.780 work we've done on the service, we have to 0:28:13.780,0:28:17.470 through away because we did it wrong. 0:28:17.470,0:28:20.940 Now, you have a client. Now you need a 0:28:20.940,0:28:24.680 server. And it doesn't matter. What, whatever[br]you want. 0:28:24.680,0:28:27.210 It's fine. It's actually the, the cost of[br]writing 0:28:27.210,0:28:31.440 this is really, really low. Because the server[br]is 0:28:31.440,0:28:34.220 the simplest part of this, and if you did 0:28:34.220,0:28:36.310 it wrong, if you chose the wrong transport[br]method, 0:28:36.310,0:28:38.720 mechanism, you know what? You build a new[br]adapter. 0:28:38.720,0:28:41.400 That's actually really quite easy. 0:28:41.400,0:28:44.350 So let me take a moment to just reiterate, 0:28:44.350,0:28:47.310 why should we have deployed by now? And I'd 0:28:47.310,0:28:49.860 say it's because the client is much, much[br]more 0:28:49.860,0:28:52.610 complicated than the server, so your bugs[br]are in 0:28:52.610,0:28:54.510 the client. Your bugs are not in the server 0:28:54.510,0:28:57.930 at this point. And the server is going to 0:28:57.930,0:28:59.700 be dictated by the choices you've made in[br]the 0:28:59.700,0:29:02.970 client. So if you've made wrong choices and[br]you 0:29:02.970,0:29:07.090 build your server, you've built the wrong[br]server. 0:29:07.090,0:29:09.640 We used Sinatra and Oj, just cause it's awesome. 0:29:09.640,0:29:12.150 It just, it really just works. It's small[br]and 0:29:12.150,0:29:15.710 it's useful. We thought we would need to move 0:29:15.710,0:29:17.800 away from HTTP, but we've grown a lot and 0:29:17.800,0:29:19.150 we haven't had to do this yet. It just 0:29:19.150,0:29:21.720 works. Things that we thought we would have[br]to 0:29:21.720,0:29:24.610 change immediately, you know, it's almost[br]a year later 0:29:24.610,0:29:26.850 and it's just. 0:29:26.850,0:29:30.380 OK, so now we use the service. And that's 0:29:30.380,0:29:32.530 really a feature flag. You just write a new 0:29:32.530,0:29:37.210 adapter that talks to the service instead[br]of the 0:29:37.210,0:29:39.900 database. So now you call, you know, by_product,[br]you 0:29:39.900,0:29:42.540 get a HTTP, it calls through to the HTTPAdapter 0:29:42.540,0:29:45.050 which gets you back the same time of relation. 0:29:45.050,0:29:47.430 When you call all on it, you know, it 0:29:47.430,0:29:49.290 calls adapter dot all, which now goes to an 0:29:49.290,0:29:52.300 HTTPClass that actually gets the JSON and[br]takes the 0:29:52.300,0:29:54.100 attributes out of it and gives you back your 0:29:54.100,0:29:56.530 save class. You're getting back the same object[br]you're 0:29:56.530,0:29:59.090 getting back as save. 0:29:59.090,0:30:03.330 So, retrospective. Great. We've isolated the[br]data. We've isolated 0:30:03.330,0:30:06.420 the interface. We started to build our DSL.[br]We've 0:30:06.420,0:30:09.760 pulled that DSL out into a gem. Now we've, 0:30:09.760,0:30:11.150 now that we actually kind of understand what[br]that 0:30:11.150,0:30:13.330 gem needs to do, we can launch the service 0:30:13.330,0:30:15.380 and then just build a new adapter to switch 0:30:15.380,0:30:16.430 to this. 0:30:16.430,0:30:18.880 If, I would say that if we hadn't, if 0:30:18.880,0:30:20.550 we had realized that this was the order that 0:30:20.550,0:30:21.950 we needed to do it on, we, we would 0:30:21.950,0:30:25.330 have done this in two weeks. Instead. So that 0:30:25.330,0:30:27.370 first part of it was like a day worth 0:30:27.370,0:30:31.020 of work. That second part of it was like, 0:30:31.020,0:30:34.470 three hours worth of work. And deployed immediately. 0:30:34.470,0:30:37.630 The, the harder part was realizing that we[br]needed 0:30:37.630,0:30:39.710 an adapter. And at this point, people, we[br]didn't 0:30:39.710,0:30:42.360 really see anything about hexagonal architecture.[br]This might have 0:30:42.360,0:30:45.080 been before some of those talks and papers[br]have 0:30:45.080,0:30:49.040 been coming out. But, but it's actually really[br]useful. 0:30:49.040,0:30:52.980 Tests. We, we use Sunspot for some of our 0:30:52.980,0:30:54.970 Solar things. And we're already used to spinning[br]up 0:30:54.970,0:30:58.880 a Solar instance using a gem, trap-it-up.[br]You know 0:30:58.880,0:31:03.150 you can do that for your integration tests.[br]But 0:31:03.150,0:31:05.450 for unit tests, you know what, we have tests 0:31:05.450,0:31:08.410 around all of this. So we can have tests 0:31:08.410,0:31:11.030 around a fake adapter that proves that it[br]behaves 0:31:11.030,0:31:14.170 the right way, and then that just saves, saves 0:31:14.170,0:31:18.400 data in, in memory, in your application. 0:31:18.400,0:31:21.640 And redundant tests, you know, you might say,[br]eh, 0:31:21.640,0:31:24.730 do I really need this test? Yes. Because one 0:31:24.730,0:31:26.809 thing, you can delete your tests later that[br]are 0:31:26.809,0:31:29.940 redundant, and you want to be really confident[br]that, 0:31:29.940,0:31:34.840 that when you do switch over, it's gonna work. 0:31:34.840,0:31:38.700 Foreman and Subcontractor are, are really[br]helpful for this 0:31:38.700,0:31:42.100 kind of thing. So subcontractor is a gem that 0:31:42.100,0:31:45.650 really says, for this service, change directory[br]over here 0:31:45.650,0:31:48.670 and run this command in a completely isolated[br]Bundler 0:31:48.670,0:31:51.590 environment. Cause you really don't want to[br]mix your, 0:31:51.590,0:31:55.200 your dependencies. You don't want your server[br]dependencies and 0:31:55.200,0:31:58.340 the versions to be conflicting with your main[br]application 0:31:58.340,0:32:00.170 dependencies. You want to be able to, to change 0:32:00.170,0:32:01.220 those separately. 0:32:01.220,0:32:03.540 OK. So what about a new app? I'm spinning 0:32:03.540,0:32:07.350 up a completely new thing. Not extracting.[br]Totally new. 0:32:07.350,0:32:09.390 How do I do that? How do I iterate 0:32:09.390,0:32:12.220 on something that doesn't exist yet? And I[br]would 0:32:12.220,0:32:13.950 say that some of the lessons that, that we've 0:32:13.950,0:32:16.070 learned from this, and actually from just[br]doing our 0:32:16.070,0:32:20.470 product development in general is iterate.[br]Find a way 0:32:20.470,0:32:23.430 to get to the smallest deployable thing as[br]quickly 0:32:23.430,0:32:27.590 as possible, and whatever tool you use to[br]deploy, 0:32:27.590,0:32:30.710 to spin up infrastructure, one of the sort[br]of 0:32:30.710,0:32:35.080 heuristics that, that, that we've found is[br]really focus 0:32:35.080,0:32:37.770 on organizing that code around being able[br]to change 0:32:37.770,0:32:41.710 things easily, and understand how this thing[br]is different 0:32:41.710,0:32:42.750 from this thing. 0:32:42.750,0:32:45.490 You know, the Chef makes it really easy to 0:32:45.490,0:32:48.760 define a giant hash of global state over here 0:32:48.760,0:32:50.800 and then just run this thing over here and 0:32:50.800,0:32:53.830 it's magic and it'll just do it. When you 0:32:53.830,0:32:56.420 actually start to spin up different services,[br]this thing 0:32:56.420,0:32:58.940 is gonna need to be slightly different than[br]this 0:32:58.940,0:33:03.050 thing. So how can your code make that as 0:33:03.050,0:33:05.970 easily understandable as possible? 0:33:05.970,0:33:10.210 So feature flags, also, on or off. Do customers 0:33:10.210,0:33:14.440 see this, or they don't. But you know what? 0:33:14.440,0:33:18.860 Maybe it's just kind of half on. Maybe everything, 0:33:18.860,0:33:22.670 every request that's gonna actually call through[br]this, use 0:33:22.670,0:33:26.950 Sidekiq to just every time, just spin off[br]a 0:33:26.950,0:33:30.400 job to hammer your, your service. And if it 0:33:30.400,0:33:33.170 breaks, you've learned that before you've[br]launched it to, 0:33:33.170,0:33:35.430 to your users. There's a lot of other ways 0:33:35.430,0:33:36.700 you can do this. 0:33:36.700,0:33:39.450 On to these five years users, and let's see 0:33:39.450,0:33:41.930 how we can break it, see how the interaction 0:33:41.930,0:33:44.680 feels. It's, it's really useful. 0:33:44.680,0:33:48.330 Also, one thing that we found is, it's often 0:33:48.330,0:33:52.680 helpful to inter, integrate very deeply before[br]you go 0:33:52.680,0:33:56.240 widely. So, if you have a code-interaction[br]that goes 0:33:56.240,0:33:59.240 through all this process, do it kind of once 0:33:59.240,0:34:01.970 through all the process, without worrying[br]so much about 0:34:01.970,0:34:04.630 the edge cases or the errors, because those[br]are, 0:34:04.630,0:34:06.230 you're gonna find those. Those are gonna,[br]those are 0:34:06.230,0:34:08.639 gonna come up. But it's re- really useful[br]to 0:34:08.639,0:34:11.069 kind of go all the way through the interaction 0:34:11.069,0:34:13.050 knowing that it's really kind of sketch and[br]doesn't 0:34:13.050,0:34:17.760 do everything, and really let that drive the[br]design. 0:34:17.760,0:34:19.969 And this is also a thing of like letting 0:34:19.969,0:34:23.250 the feature kind of drive the design and figuring 0:34:23.250,0:34:25.310 out, what is the pattern for how you really 0:34:25.310,0:34:28.020 need to organize the code, before you have.[br]Don't 0:34:28.020,0:34:29.739 just like whiteboard everything and say this[br]is gonna 0:34:29.739,0:34:32.340 be perfect. You know. 0:34:32.340,0:34:34.590 Production is going to destroy every single[br]design that 0:34:34.590,0:34:39.619 you think you have. Also, if something seems[br]clever, 0:34:39.619,0:34:41.899 it's bad. If you're like, eh, this is kind 0:34:41.899,0:34:44.139 of cool. No. No, no, no. It's bad. Complexity 0:34:44.139,0:34:47.550 is gonna come to you. Don't, don't seek it 0:34:47.550,0:34:51.239 out. It's, it's, it's evil. 0:34:51.239,0:34:53.110 So if there are any kind of take aways 0:34:53.110,0:34:57.360 from this, I would say you know, hexagonal[br]architecture 0:34:57.360,0:34:59.930 is really cool, but you don't have to design 0:34:59.930,0:35:03.390 it from the start. If you have trust, if 0:35:03.390,0:35:06.880 everyone in the organization has trust that[br]you can 0:35:06.880,0:35:09.110 do your job and that you're all going, working 0:35:09.110,0:35:13.660 together to build an awesome product, an awesome[br]company, 0:35:13.660,0:35:16.400 you can fix this later. You can actually let 0:35:16.400,0:35:20.780 the needs of your product determine where[br]your boundaries 0:35:20.780,0:35:21.830 are. 0:35:21.830,0:35:27.119 So, thank you. I actually have a few minutes 0:35:27.119,0:35:29.880 of, of questions, to answer questions.