0:00:25.699,0:00:27.679 PAVAN SUDARSHAN: Hi. My name is Pavan. 0:00:27.679,0:00:31.320 ANANDHA KRISHNAN: And I'm Anandha Krishnan.[br]I'm 0:00:31.320,0:00:35.980 also called Jake. Not Anandha. I know. We[br]work 0:00:35.980,0:00:37.390 at MavenHive technologies. 0:00:37.390,0:00:40.449 P.S.: This is probably the only 0:00:40.449,0:00:42.760 talk where there are two speakers, and we[br]haven't 0:00:42.760,0:00:45.260 rehearsed who says what, so we'll be stepping[br]on 0:00:45.260,0:00:47.750 each other's toes, so yeah. Bear with us.[br]So 0:00:47.750,0:00:50.260 yeah. Quick disclaimer: Most of what we are[br]going 0:00:50.260,0:00:52.589 to talk about is actually platform and language[br]independent, 0:00:52.589,0:00:55.510 or at least, in a sense, learned. But the 0:00:55.510,0:00:58.369 reason we are talking here in a Ruby Conf 0:00:58.369,0:01:01.180 is because of the Ruby community. We really[br]think 0:01:01.180,0:01:02.879 that a lot of things we are going to 0:01:02.879,0:01:04.739 talk about resonates really well with the[br]community, and 0:01:04.739,0:01:07.290 we are hoping to, you know, drive a good 0:01:07.290,0:01:10.890 discussion, conversation, whatever it is,[br]from this audience. So 0:01:10.890,0:01:13.340 that's really why we are talking here on this 0:01:13.340,0:01:13.659 topic. 0:01:13.659,0:01:15.350 A.K.: And a lot of the points that 0:01:15.350,0:01:17.460 we're going to talk about kind of naturally[br]apply 0:01:17.460,0:01:22.390 to Rails and Ruby. And most of these we 0:01:22.390,0:01:25.860 learned, and we sort of experience in our[br]projects, 0:01:25.860,0:01:29.490 which are mostly in Ruby and Rails, so. 0:01:29.490,0:01:33.619 P.S.: Yeah, so let's start with condition.[br]We have screwed 0:01:33.619,0:01:36.289 up a lot in our careers. Right, between me 0:01:36.289,0:01:38.740 and Jake, we have no idea how many mistakes 0:01:38.740,0:01:41.219 we have made. And on those rare occassions,[br]we 0:01:41.219,0:01:43.130 have actually learned from it, or at least[br]we 0:01:43.130,0:01:46.359 would like to think so. So yeah, this talk 0:01:46.359,0:01:52.789 is about one such mistake from which we learned, 0:01:52.789,0:01:53.100 and yeah. 0:01:53.100,0:01:54.899 A.K.: And, yes, I think most of 0:01:54.899,0:01:57.439 it, we just put it up front, just based 0:01:57.439,0:02:00.389 on projects, and you know, as we were talking 0:02:00.389,0:02:03.520 about what happened with each of us, and things 0:02:03.520,0:02:06.069 like that. So yeah, just trying to make it, 0:02:06.069,0:02:09.008 you know, presentable and that stuff. But[br]we- 0:02:09.008,0:02:11.680 P.S.: Yeah, like, though we screwed up, we[br]would like 0:02:11.680,0:02:14.170 to believe that no employers or paranoid androids[br]were 0:02:14.170,0:02:17.360 hurt in the process of our mistakes, so yeah. 0:02:17.360,0:02:21.230 OK, about three months back, so why pharamcist[br]and 0:02:21.230,0:02:23.930 doctors, right? So about three months about[br]I was 0:02:23.930,0:02:28.120 in this pharmacy buying diapers for my daughter,[br]and 0:02:28.120,0:02:30.090 in walks this guy - he just goes straight 0:02:30.090,0:02:33.700 to the pharmacist and he's like, hey, can[br]you 0:02:33.700,0:02:36.909 give me something for a toothache? There was[br]something 0:02:36.909,0:02:40.489 very interesting and weird about this, and[br]Jake and 0:02:40.489,0:02:42.540 I, we carpool. So the next morning I was 0:02:42.540,0:02:45.340 just telling Jake, and between the two of[br]us, 0:02:45.340,0:02:50.340 like, between the two of us, we realized that 0:02:50.340,0:02:54.150 we have seen people ask for all sorts of 0:02:54.150,0:02:56.829 medicines in a pharmacy. Right. Headaches,[br]fever, like, like, 0:02:56.829,0:02:59.640 true story, I even once saw this guy with 0:02:59.640,0:03:04.519 a lot of cuts on his face from a 0:03:04.519,0:03:06.939 knife, and yeah. Insane. Insane, right. So[br]about, when 0:03:06.939,0:03:08.930 we were talking about this, we thought there[br]was 0:03:08.930,0:03:11.390 something fundamentally wrong with this. Is[br]there anyone here 0:03:11.390,0:03:14.000 who thinks that it's totally OK for you to 0:03:14.000,0:03:21.000 just walk up to a pharmacist and ask for 0:03:25.129,0:03:28.120 a medicine? Oh yeah, cool. Yeah, so. Nice.[br]OK. 0:03:28.120,0:03:31.269 Hold that thought. Yeah, but like. So what[br]we 0:03:31.269,0:03:34.400 think, yes, a pharmacy potentially has a cure[br]for 0:03:34.400,0:03:37.390 pretty much any, most ailments that you could[br]think 0:03:37.390,0:03:41.120 of, and but the important thing is, though,[br]you 0:03:41.120,0:03:43.099 need to know what ailment you have. Right,[br]there's 0:03:43.099,0:03:47.260 that small implementation detail, right. And[br]if it was 0:03:47.260,0:03:48.620 that easy for you to just go to the 0:03:48.620,0:03:51.840 right medicine and get it, this world would[br]be 0:03:51.840,0:03:56.730 filled with only pharmacists and not doctors,[br]right. Yeah, 0:03:56.730,0:03:59.329 so that's, so that's where the whole analogy[br]starts, 0:03:59.329,0:04:01.269 and then we'll get to how we connect to 0:04:01.269,0:04:02.180 what we're going to talk about. 0:04:02.180,0:04:05.810 A.K.: Yeah, and that's, that's where we, in[br]a sort of thought 0:04:05.810,0:04:09.159 that we use this metaphor to drive home that 0:04:09.159,0:04:11.859 point. Of course, a lot of you might have 0:04:11.859,0:04:15.269 your opinions about self-medication and the[br]whole thing. So 0:04:15.269,0:04:18.790 we'll stop it at this, and we will give 0:04:18.790,0:04:21.269 us, our definition of what we think about[br]these 0:04:21.269,0:04:25.610 two sort of mindsets actually are and, you[br]know. 0:04:25.610,0:04:29.610 So starting off with like doctors, right.[br]They don't 0:04:29.610,0:04:32.580 treat, rarely, they don't try to treat the[br]symptoms, 0:04:32.580,0:04:34.710 it's about how you deal with them. So they 0:04:34.710,0:04:36.970 go about just figuring out what the problem[br]could 0:04:36.970,0:04:40.120 be, you know, and then probably, you know,[br]a 0:04:40.120,0:04:43.330 lot of tests, make you run through a few 0:04:43.330,0:04:46.250 tests or try and figure out what's what, if 0:04:46.250,0:04:49.460 indeed it is the problem, and then try and, 0:04:49.460,0:04:53.670 based on that, prescribe a treatment and,[br]of course, 0:04:53.670,0:04:55.660 make sure that you're OK at the end of 0:04:55.660,0:04:58.080 it, right. The symptoms are gone. 0:04:58.080,0:05:01.250 P.S.: And we didn't take a look through a[br]medical textbook, so 0:05:01.250,0:05:02.960 we don't know if this is right, but assuming 0:05:02.960,0:05:06.060 it is, though, this is what worked for us, 0:05:06.060,0:05:06.540 so. 0:05:06.540,0:05:10.620 A.K.: And, again, in contrast, a pharmacist's[br]job, 0:05:10.620,0:05:14.360 we think very different, should be more about[br]understanding 0:05:14.360,0:05:18.600 the medicines, the medicines themselves. Probably[br]even figure out 0:05:18.600,0:05:21.000 what the disease is based on the medicine,[br]right. 0:05:21.000,0:05:24.850 But definitely they don't really think about,[br]you know, 0:05:24.850,0:05:26.790 what was the problem originally or what are[br]we 0:05:26.790,0:05:29.420 prescribing the treatment for. And they usually[br]don't do 0:05:29.420,0:05:31.220 it. Hopefully they don't do it. 0:05:31.220,0:05:32.120 P.S.: Yeah. OK. 0:05:32.120,0:05:33.880 So now with this context of what we mean 0:05:33.880,0:05:37.560 by a doctor and a pharmacist and medicines[br]and 0:05:37.560,0:05:40.580 self-medication, all right. Let's get back[br]to our mistake, 0:05:40.580,0:05:44.310 which we want to talk about. Right. So our 0:05:44.310,0:05:45.670 mistake that we want to talk about is a 0:05:45.670,0:05:47.610 way we have dealt with, or rather we used 0:05:47.610,0:05:50.780 to deal with bad symptoms on our code bases 0:05:50.780,0:05:54.630 and on our projects, right. So you, a lot 0:05:54.630,0:05:57.680 of times you see these in your code bases. 0:05:57.680,0:06:01.130 There's the symptom, or there are some issues,[br]right. 0:06:01.130,0:06:04.360 So we obviously had a lot of those, in 0:06:04.360,0:06:07.080 every single project we have worked on, and[br]this 0:06:07.080,0:06:09.310 is about how we dealt with that, right. 0:06:09.310,0:06:12.740 A.K.: Let's start off with one very simple[br]one, or 0:06:12.740,0:06:14.690 at least the one which was the most easily 0:06:14.690,0:06:15.440 expressible. 0:06:15.440,0:06:18.930 P.S.: Yeah, as in, Tejas Dinkar, who has 0:06:18.930,0:06:21.560 already been mentioned several times in different[br]talks, he 0:06:21.560,0:06:24.380 threatened us to throw off the stage if we 0:06:24.380,0:06:28.410 took anything more than twenty-nine minutes,[br]fifty-nine seconds. So 0:06:28.410,0:06:32.390 we had to like really dumbify our, you know, 0:06:32.390,0:06:34.890 anecdotes. But you learn, we have like a quick 0:06:34.890,0:06:36.440 mention of different things which we would[br]love to 0:06:36.440,0:06:40.210 talk about offline, but yeah. So thanks Dejas. 0:06:40.210,0:06:43.270 A.K.: So we'll get started on the first one.[br]So 0:06:43.270,0:06:45.800 this was a project where we had a familiar 0:06:45.800,0:06:49.340 problem of regression bugs. We added new features,[br]and 0:06:49.340,0:06:53.460 that kept breaking things. So this is what[br]we 0:06:53.460,0:06:56.120 designed. We want this down. We want the number 0:06:56.120,0:06:58.650 of bugs down from 10 to 5, you know. 0:06:58.650,0:07:01.250 At that time it was, like, let's set up 0:07:01.250,0:07:03.410 this goal, let's try and achieve this. What[br]did 0:07:03.410,0:07:05.410 we do? Oh, before that. Some facts about the 0:07:05.410,0:07:09.470 project, right. This was not a project we[br]started 0:07:09.470,0:07:11.810 on from scratch, it was a lot of legacy 0:07:11.810,0:07:13.280 code, a lot of code that we did not 0:07:13.280,0:07:17.560 understand, and probably that's why we thought[br]it was 0:07:17.560,0:07:19.280 bad. And the test coverage was- 0:07:19.280,0:07:21.910 P.S.: How many of you have taken over a code[br]base from 0:07:21.910,0:07:24.160 another team and thought the code base was[br]awesome? 0:07:24.160,0:07:29.110 Very small samples, so you realize what we[br]mean 0:07:29.110,0:07:32.320 when we thought it was bad. So. 0:07:32.320,0:07:33.070 A.K.: Sure. 0:07:33.070,0:07:36.200 So test-coverage was low, which was probably[br]one of 0:07:36.200,0:07:39.470 the reasons why people complained about the[br]code base, 0:07:39.470,0:07:41.990 of course. So what's your guess? 0:07:41.990,0:07:46.090 P.S.: OK, so the problem we had was every[br]time we checked 0:07:46.090,0:07:48.640 in something, built a new feature, touch any[br]part 0:07:48.640,0:07:50.330 of the code base, we ended up breaking a 0:07:50.330,0:07:52.280 whole bunch of other things. And we would[br]not 0:07:52.280,0:07:54.300 even know it right away, we would know it 0:07:54.300,0:07:55.240 over a period of time. Right, so this was 0:07:55.240,0:07:57.930 a regression problem. And given the facts,[br]what would 0:07:57.930,0:07:59.000 you probably have done? 0:07:59.000,0:08:00.860 A.K.: I'll try and just 0:08:00.860,0:08:03.910 go back again, and then hopefully forward[br]- we're 0:08:03.910,0:08:04.680 done [00:08:04]??. 0:08:04.680,0:08:07.750 P.S.: Yeah, based on some facts. 0:08:07.750,0:08:13.820 A.K.: Sure, so the low coverage was definitely[br]a problem. 0:08:13.820,0:08:17.040 We thought, I mean, everybody agreed that[br]we need 0:08:17.040,0:08:19.880 to start working on that, and you know, fix 0:08:19.880,0:08:23.340 the coverage. So we went in there, put the 0:08:23.340,0:08:26.150 coverage tool in place, you know. And then[br]we 0:08:26.150,0:08:28.170 decided we will write tests for every bug[br]we 0:08:28.170,0:08:32.610 caught. We got the coverage up, not very surprising, 0:08:32.610,0:08:36.279 I mean, we didn't manage to- you know, improving 0:08:36.279,0:08:37.200 the coverage- 0:08:37.200,0:08:41.039 P.S.: Yeah like, so we spend like the whole[br]time- 0:08:41.039,0:08:42.539 A.K.: over a period of time. 0:08:42.539,0:08:44.880 P.S.: OK, so, like so this was a problem, 0:08:44.880,0:08:46.360 right. When you look at that, when you try 0:08:46.520,0:08:48.380 to abstract the, into, like what our thought[br]process 0:08:48.440,0:08:56.540 was. It was something like this, right. Check.[br]Yeah. 0:08:56.540,0:08:58.620 So, we had a symptom. In this case it 0:08:58.620,0:09:04.140 was low test-coverage, and - Jake - and we 0:09:04.140,0:09:06.750 had, we decided on what metric and tool to 0:09:06.750,0:09:09.700 use. In our case it was a simple line 0:09:09.700,0:09:11.570 coverage, right and, archive?? [00:09:10],[br]this was back in 0:09:11.570,0:09:14.930 the days. And then we started solving that[br]problem 0:09:14.930,0:09:17.550 that we had, and then, you know, hopefully,[br]for 0:09:17.550,0:09:20.670 example, we were TDDing most of the new code 0:09:20.670,0:09:23.970 that we wrote, so coverage was good on that, 0:09:23.970,0:09:28.500 then start writing tests for things, which[br]were, any 0:09:28.500,0:09:29.980 part of the code base which we touched where 0:09:29.980,0:09:31.720 there were no tests, we started adding tests[br]there. 0:09:31.720,0:09:33.900 You know, a bunch of different things. So[br]basically, 0:09:33.900,0:09:36.240 like, the idea was to improve the coverage[br]and 0:09:36.240,0:09:39.620 keep on writing, right. So cool, so. And what 0:09:39.620,0:09:42.710 was the result? We ended up with, of course, 0:09:42.710,0:09:45.390 drastically improving our test coverage, so[br]we were in 0:09:45.390,0:09:48.130 the late '90s for most the part of the 0:09:48.130,0:09:50.630 code base, which was awesome. 0:09:50.630,0:09:53.010 A.K.: A hundred, man, a hundred. 0:09:53.010,0:09:55.890 P.S.: A hundred, yeah. Or, yeah, sure. 0:09:55.890,0:10:00.070 Very good coverage. But things got only marginally[br]better. 0:10:00.070,0:10:02.200 At this point, this was when we realized that 0:10:02.200,0:10:04.260 inspite of putting so much effort into actually[br]improving 0:10:04.260,0:10:07.000 our test coverage, our actual goal was to[br]actual 0:10:07.000,0:10:10.640 reduce the number of regression bugs. So we,[br]we 0:10:10.640,0:10:13.500 were still no better than what we started[br]off, 0:10:13.500,0:10:17.240 about two months back. So the developers were[br]generally 0:10:17.240,0:10:19.580 very happy, now they were doing a lot more 0:10:19.580,0:10:22.360 TDD, they have a lot, they had manag- successfully 0:10:22.360,0:10:24.600 convinced the manag- you know the product[br]manager and 0:10:24.600,0:10:27.590 the stake holders to spend more time on the 0:10:27.590,0:10:29.600 tech deck?? [00:10:29] and things like that.[br]They they 0:10:29.600,0:10:31.800 also were happy. But the project manager was[br]extremely 0:10:31.800,0:10:34.430 frustrated, because in spite of spending so[br]much effort, 0:10:34.430,0:10:37.430 there was no real benefit from any of it, 0:10:37.430,0:10:39.560 right. So it's like one of those very classic 0:10:39.560,0:10:41.730 moments where you know, in Dilbert where,[br]you know, 0:10:41.730,0:10:45.029 the, OK, in Dilbert developers are never happy,[br]but 0:10:45.029,0:10:47.080 at least here we were happy and the project 0:10:47.080,0:10:48.960 manager was sad, right. A.K.: And we weren't[br]happy 0:10:48.960,0:10:49.870 with the project managers as well. 0:10:49.870,0:10:52.510 P.S.: Yeah, and eventually we feel there was[br]something wrong, 0:10:52.510,0:10:56.200 it's not like we take pleasure out of it.[br]So, we 0:10:56.200,0:10:58.630 think this is a very big mistake, where we 0:10:58.630,0:11:01.380 spent almost two months of time without really[br]realizing 0:11:01.380,0:11:03.870 where we were going wrong, right. So this[br]mistake 0:11:03.870,0:11:07.490 and several mistakes across different projects[br]which Dejas won't 0:11:07.490,0:11:11.620 let us go into, ended up making us realize 0:11:11.620,0:11:15.770 something very basic, right. And that's, this[br]is basically 0:11:15.770,0:11:17.000 what, this is what we were going to say. 0:11:17.000,0:11:18.080 A.K.: OK, tell us a little bit. 0:11:18.080,0:11:20.700 P.S.: If we had like a lightning talk, this[br]is what 0:11:20.700,0:11:22.050 we probably the only thing we would have put 0:11:22.050,0:11:26.230 up and left. So never improve a metric. Solving 0:11:26.230,0:11:29.850 a problem should automatically imrpve the[br]metric that you're 0:11:29.850,0:11:34.350 measuring, right. So the focus is on, is never 0:11:34.350,0:11:36.700 on making a metric better. It's always about[br]solving 0:11:36.700,0:11:38.270 the problem. And, the metric- 0:11:38.270,0:11:38.690 A.K.: This is like 0:11:38.690,0:11:40.430 one of those, one of those things that is, 0:11:40.430,0:11:41.620 it's very easily said and- 0:11:41.620,0:11:42.080 P.S.: Yeah, and it- 0:11:42.080,0:11:43.480 A.K.: You have to, at least for us, we 0:11:43.480,0:11:45.070 always fell in that trap of- 0:11:45.070,0:11:45.900 P.S.: Yeah, like 0:11:45.900,0:11:48.480 it almost sounds like 'do the right thing,'[br]but, 0:11:48.480,0:11:51.090 yeah, like, it's very, it fits your common[br]sense 0:11:51.090,0:11:52.670 very well, but then when you're caught up[br]in 0:11:52.670,0:11:55.000 the daily, the day-to-day stuff in what you[br]do 0:11:55.000,0:11:57.029 in a project, it becomes very easy for you 0:11:57.029,0:11:59.430 to miss the point here. So yeah, like this 0:11:59.430,0:12:03.120 is really what, what is essence of what we 0:12:03.120,0:12:05.779 are trying to say, right. 0:12:05.779,0:12:08.190 A.K.: So, so what really happened here. 0:12:08.190,0:12:09.050 Let's go a little bit more 0:12:09.050,0:12:11.940 into what we were trying earlier and what[br]we 0:12:11.940,0:12:14.770 think we should have probably done. Instead[br]of something 0:12:14.770,0:12:18.800 like this, which, which actually ended up[br]attacking the 0:12:18.800,0:12:23.279 symptoms, or you know, targeting the symptom,[br]we want 0:12:23.279,0:12:25.430 to do something like this: There is a symptom, 0:12:25.430,0:12:26.360 so just like always- 0:12:26.360,0:12:27.480 P.S.: This is where the 0:12:27.480,0:12:29.570 whole, like, the pharmacist and the doctor[br]approach, yeah, 0:12:29.570,0:12:32.279 like, it's a very long-shot metaphor, we agree,[br]but- 0:12:32.279,0:12:35.170 A.K.: The doctor thinking, which we hopefully[br]want to 0:12:35.170,0:12:39.800 do, is first is just try and take a 0:12:39.800,0:12:41.339 guess at least at the problem, at least in 0:12:41.339,0:12:42.810 our context, maybe not the doctor's. But in[br]our 0:12:42.810,0:12:46.570 context, take a quess at the problem, right.[br]Think 0:12:46.570,0:12:49.720 what it might be. Then that hopefully will[br]tell 0:12:49.720,0:12:52.230 you what you could do to probably solve the 0:12:52.230,0:12:55.320 problem, solve, you know, that could be the[br]solution 0:12:55.320,0:12:59.230 which hope- will hopefully fix the problem,[br]right. So 0:12:59.230,0:13:01.740 this kind of very similar, we are iterating??[00:13:00][br]over 0:13:01.740,0:13:05.380 this and hopefully, you know, improving on[br]what we 0:13:05.380,0:13:09.589 thought was the problem. And how do you know, 0:13:09.589,0:13:12.420 then, that you know we are in fact improving 0:13:12.420,0:13:13.870 on the problem? How do we know that is 0:13:13.870,0:13:13.900 the problem? 0:13:13.900,0:13:14.050 P.S.: Like the whole, how do you 0:13:14.050,0:13:14.650 define them, right. So, how do we define them? 0:13:14.650,0:13:17.900 A.K.: And that's where we think, that's where[br]we 0:13:17.900,0:13:21.420 think the metrics come in. Again, not metric,[br]hopefully 0:13:21.420,0:13:24.410 metrics, because that lets us measure the[br]problem. It 0:13:24.410,0:13:27.620 tells us at every point that, you know, you're 0:13:27.620,0:13:30.440 doing better, you know, it's improving. And[br]hopefully you 0:13:30.440,0:13:34.620 also, when it gets done, right. So, yeah.[br]So 0:13:34.620,0:13:36.700 this is, this is probably the approach that[br]we 0:13:36.700,0:13:40.020 would like to try on, try from now on, 0:13:40.020,0:13:43.860 also. And, right, there, you know, the problem[br]may 0:13:43.860,0:13:46.050 not be the, what is the one that we 0:13:46.050,0:13:48.400 started out to fix. Like, like, probably in[br]our 0:13:48.400,0:13:50.610 previous case, you know, it, you should always[br]be 0:13:50.610,0:13:53.270 open to the idea that the problem will, what 0:13:53.270,0:13:54.990 you thought was the problem was never the[br]case, 0:13:54.990,0:13:57.670 and it was not showing up. I mean, you 0:13:57.670,0:14:00.029 were trying to, you were seeing the metrics[br]improve, 0:14:00.029,0:14:02.360 but then the symptom never went away, right.[br]So 0:14:02.360,0:14:04.040 be open to the notion that the problem could 0:14:04.040,0:14:06.520 be different, in which case, the important[br]thing is 0:14:06.520,0:14:09.170 the solution is different and the metrics[br]are different, 0:14:09.170,0:14:10.380 right. So yeah. 0:14:10.380,0:14:12.000 P.S.: Any guesses on what could 0:14:12.000,0:14:15.240 have been the problem on that project? Where[br]the 0:14:15.240,0:14:20.460 regression bugs were written very high? It[br]was duplication, 0:14:20.460,0:14:23.180 as in there was, like, rampant duplication[br]all over 0:14:23.180,0:14:26.270 the place. And we would change something but[br]forget 0:14:26.270,0:14:28.410 to change the same thing in some other place. 0:14:28.410,0:14:30.110 But, and because we didn't know about the[br]code 0:14:30.110,0:14:33.610 base, yeah. We were just blindly adding tests.[br]And 0:14:33.610,0:14:36.710 incrimentally going through different places,[br]where each place where 0:14:36.710,0:14:38.870 we found that there were no tests, we added 0:14:38.870,0:14:40.470 a test, right. But that didn't really help[br]us 0:14:40.470,0:14:42.870 with actually solving the problem of duplication.[br]Yeah. So- 0:14:42.870,0:14:44.730 A.K.: The coverage number is something which[br]is, it 0:14:44.730,0:14:47.300 easily drives you to just keep adding the[br]specs, 0:14:47.300,0:14:50.210 and we will talk about, more about that soon. 0:14:50.210,0:14:53.440 P.S.: Yeah, so, if you really think about[br]it, 0:14:53.440,0:14:55.980 of, basically what, at least, we would love[br]to 0:14:55.980,0:14:59.490 believe that we have stopped doing this, right.[br]So 0:14:59.490,0:15:02.490 Yogi mentioned this in the panel discussion[br]yesterday, block-force 0:15:02.490,0:15:05.779 driven decisions, right. So that was really[br]what we 0:15:05.779,0:15:07.870 were doing, essentially. Like, we were a bunch[br]of 0:15:07.870,0:15:10.899 kids on this project, who'd see a problem[br]at 0:15:10.899,0:15:14.220 the first, the, at the first, trigger we would 0:15:14.220,0:15:17.399 just start crawling the web, start crawling[br]block force, 0:15:17.399,0:15:20.600 see different github projects, find a gem,[br]install it, 0:15:20.600,0:15:23.270 start, like, monitoring it, measuring it,[br]try to improve 0:15:23.270,0:15:25.510 it, you know. We don't really spending too[br]much 0:15:25.510,0:15:28.850 time into figuring out what was really the[br]problem, 0:15:28.850,0:15:35.850 right. And, especially, so in, OK - where[br]does- 0:15:36.960,0:15:40.399 Especially so in Rails projects, where, you[br]know, or 0:15:40.399,0:15:42.589 Ruby projects, where we believe that the number[br]of 0:15:42.589,0:15:46.800 gems which actually bundle best practices[br]is actually very 0:15:46.800,0:15:48.620 high, right. Here it's very easy for us to 0:15:48.620,0:15:50.600 fall into the trap of, OK, just choose a 0:15:50.600,0:15:53.360 gem, start using it, and then two months or 0:15:53.360,0:15:54.690 three months down the way you have no idea 0:15:54.690,0:15:56.589 where you used it in the first place. But 0:15:56.589,0:15:58.580 it's just there in your process, right. Yeah.[br]Like 0:15:58.580,0:16:01.020 at least we used to find ourselves in that 0:16:01.020,0:16:04.600 trap all the time. So yeah. This is basically 0:16:04.600,0:16:08.200 what we stopped doing. OK, at this- 0:16:08.200,0:16:08.820 A.K.: [indecipherable] 0:16:08.820,0:16:10.740 P.S.: So this, this dude is basically Hari, 0:16:10.740,0:16:13.680 he's sitting way over there. Yesterday we[br]were doing 0:16:13.680,0:16:16.600 a write-in??[00:16:14], and the only dude[br]that, after this 0:16:16.600,0:16:18.810 point it's fine, but it's getting monotonous,[br]it's very 0:16:18.810,0:16:21.760 black and white. And you need more images.[br]And, 0:16:21.760,0:16:24.690 like, Jake and I were really, we really think 0:16:24.690,0:16:24.959 that- 0:16:24.959,0:16:26.290 A.K.: That's our image, Hari! 0:16:26.290,0:16:28.720 P.S.: We really think that we don't know how[br]to add images 0:16:28.720,0:16:31.290 to a presentation. And we were like, OK fine 0:16:31.290,0:16:34.709 Hari, we'll just add your picture. And, yeah,[br]so 0:16:34.709,0:16:37.190 thanks for- and as you notice, we are very 0:16:37.190,0:16:38.850 receptive of feedback, so. 0:16:38.850,0:16:41.110 A.K.: He hasn't spoken yet, 0:16:41.110,0:16:42.250 but his is full of interesting ones. 0:16:42.250,0:16:44.959 P.S.: Like it would have been funny if like[br]his was 0:16:44.959,0:16:46.649 the presentation before we got the schedule,[br]but yeah, 0:16:46.649,0:16:51.080 anyway. He'll be talking next. So yeah, when[br]you 0:16:51.080,0:16:53.279 look at test coverage, right, how many of[br]you 0:16:53.279,0:16:59.010 think you understand test coverage very well?[br]Well enough. 0:16:59.010,0:17:03.970 OK, I mean, sure, yeah, like- 0:17:03.970,0:17:07.510 A.K.: This was one thing which at least took[br]us as a 0:17:07.510,0:17:10.419 very obvious metrics thing, which we always[br]get into, 0:17:10.419,0:17:10.609 and- 0:17:10.609,0:17:12.250 P.S.: When we were young and stupid as 0:17:12.250,0:17:14.299 against now old and stupid, right, we were,[br]we 0:17:14.299,0:17:16.500 used to think oh, test coverage, what's that,[br]it's 0:17:16.500,0:17:18.799 just - meh. It's so easy, right. But then 0:17:18.799,0:17:21.839 we realized even something so seemingly obvious[br]had, like, 0:17:21.839,0:17:25.059 so many different shades of details. And once[br]you 0:17:25.059,0:17:27.669 start understanding it and interpreting it[br]in context is 0:17:27.669,0:17:32.029 when you really understand the, the complexity[br]of that, 0:17:32.029,0:17:35.980 of that thing that you're measuring, right.[br]Now think 0:17:35.980,0:17:38.409 of all the things that people at Flipkart[br]measure. 0:17:38.409,0:17:40.820 I don't even know if they have a rational 0:17:40.820,0:17:43.940 behind every one of it. I'm hoping they do, 0:17:43.940,0:17:46.129 but you know like, it becomes very OK, we 0:17:46.129,0:17:48.239 just need to monitor these ten things. Why?[br]Why 0:17:48.239,0:17:51.080 are you doing it? Right. So it should not 0:17:51.080,0:17:52.940 be like a checklist at every project on start. 0:17:52.940,0:17:55.519 You just start using it. So yeah, test coverage 0:17:55.519,0:17:57.779 is definitely one thing that we found where,[br]on 0:17:57.779,0:17:59.059 start of every project we just set up a 0:17:59.059,0:18:01.350 coverage tool. We just wanted to talk about[br]some 0:18:01.350,0:18:04.450 details on what we learned when doing that,[br]so 0:18:04.450,0:18:05.309 yeah. 0:18:05.309,0:18:07.330 A.K.: So first we want to start off 0:18:07.330,0:18:11.850 the obvious one. The measuring. So controller[br]specs versus 0:18:11.850,0:18:15.989 model specs coverage. I- I'm guessing it,[br]does it 0:18:15.989,0:18:20.989 ring any bells? I'm- so, so I'm, think of 0:18:20.989,0:18:23.519 it this way, like, he has a question for 0:18:23.519,0:18:27.320 you, right? You have, let's take a simple[br]case. 0:18:27.320,0:18:29.190 There is a single controller, you have a spec 0:18:29.190,0:18:32.090 around it, there's a corresponding module,[br]you have a 0:18:32.090,0:18:34.279 spec around it, right. And then, you, with[br]these 0:18:34.279,0:18:35.330 two tests you run your coverage, right. 0:18:35.330,0:18:36.649 P.S.: And you get some coverage from- 0:18:36.649,0:18:39.059 A.K.: I'm guessing it's going to be a hundred[br]percent. 0:18:39.059,0:18:43.779 P.S.: Do you see a problem with this? Could[br]there, rather, OK, 0:18:43.779,0:18:49.320 could there be a problem with this? 0:18:49.320,0:18:53.669 A.K.: What if you just removed the model spec? 0:18:53.669,0:18:56.960 P.S.: What will the coverage for model be?[br]Is there a 0:18:56.960,0:19:01.570 chance that model's coverage is not zero? 0:19:01.570,0:19:04.570 A.K.: Your controller spec is still gonna[br]be loading the model. 0:19:04.570,0:19:05.049 So your coverage- 0:19:05.049,0:19:05.519 P.S.: Depends on- 0:19:05.519,0:19:06.309 A.K.: -is still in question. 0:19:06.309,0:19:08.139 P.S.: The answer is it depends, right, 0:19:08.139,0:19:09.950 like, really depends on how you are testing[br]your 0:19:09.950,0:19:11.730 controller. But most of all things, what we[br]have 0:19:11.730,0:19:14.409 seen is, not every model is mocked out in 0:19:14.409,0:19:17.169 the controller. Well, it's a totally different[br]debate, whether 0:19:17.169,0:19:19.980 should you mock your models or not, but if 0:19:19.980,0:19:22.629 you are not modelin- or, mocking, your models[br]are 0:19:22.629,0:19:25.330 being loaded in your controller. So the controller[br]spec, 0:19:25.330,0:19:27.789 when it is tested for, like when the coverage 0:19:27.789,0:19:31.289 is reported your models are being reported[br]as well. 0:19:31.289,0:19:33.759 A.K.: While, while the, or the point of, the 0:19:33.759,0:19:35.600 point we are trying to make is, here, is 0:19:35.600,0:19:37.919 not whether you should, how you should test[br]your 0:19:37.919,0:19:41.570 model specs and controller specs. What we[br]do implore 0:19:41.570,0:19:44.220 you to do is make sure that when you're 0:19:44.220,0:19:45.989 doing, when you're looking at your coverage,[br]you do 0:19:45.989,0:19:48.350 have in mind your testing strategy, which[br]is, am 0:19:48.350,0:19:50.549 I actually mocking the model out or is it 0:19:50.549,0:19:52.980 also getting wrote as a part of my controller 0:19:52.980,0:19:54.879 spec? Is my controller spec also hitting the[br]models, 0:19:54.879,0:19:57.169 right? Think about these things when, when[br]you're looking 0:19:57.169,0:20:00.059 at these numbers, right. Or something that[br]worked for 0:20:00.059,0:20:02.179 us which we tried to do was we started 0:20:02.179,0:20:05.730 monitoring the model specs coverage independently,[br]and then started 0:20:05.730,0:20:12.539 looking at the controller specs in light of[br]the, 0:20:12.539,0:20:14.470 in light of the model spec coverage. We wanted 0:20:14.470,0:20:16.820 the model spec coverage to be high, because[br]at 0:20:16.820,0:20:19.649 least we wanted all, hopefully all our business[br]logic 0:20:19.649,0:20:22.590 was in the model specs, and you know, that's 0:20:22.590,0:20:28.960 what we were keen on. Yes. Yeah, and then 0:20:28.960,0:20:31.590 the next one, the line coverage itself, I[br]think 0:20:31.590,0:20:33.320 most commonly when we talk about coverage[br]we just 0:20:33.320,0:20:35.419 talk about line coverage. But then there is[br]a 0:20:35.419,0:20:38.080 bunch of other things as well, branch coverage,[br]and 0:20:38.080,0:20:39.830 then unique path coverage. 0:20:39.830,0:20:40.710 P.S.: How many of you 0:20:40.710,0:20:42.239 pay attention to branch coverages? 0:20:42.239,0:20:44.730 A.K.: Or even monitor it? 0:20:44.730,0:20:46.850 P.S.: How many of you don't think it's 0:20:46.850,0:20:52.690 important? How many of you have no opinions?[br]Cool. 0:20:52.690,0:20:58.190 Yeah. I mean, sure. We have it on projects 0:20:58.190,0:21:00.690 where it's been important, it's not been important,[br]it's 0:21:00.690,0:21:02.739 fine. But it's just that, you just need to 0:21:02.739,0:21:05.830 know that it exists, and you need to train 0:21:05.830,0:21:07.570 your data, right, so. 0:21:07.570,0:21:08.590 A.K.: Just, hopefully it should 0:21:08.590,0:21:11.809 not be a single metric. Something usually[br]seems wrong 0:21:11.809,0:21:13.019 if it is just gonna be about that one 0:21:13.019,0:21:19.080 metric. Next one. So reporting. Yeah, this[br]one is 0:21:19.080,0:21:21.389 a bit tricky. What I usually don't like about 0:21:21.389,0:21:24.480 coverage tools and these tools in general[br]is they 0:21:24.480,0:21:26.929 sometimes miss out this aspect of it. And[br]they, 0:21:26.929,0:21:28.489 in an attempt to try and be nice to 0:21:28.489,0:21:30.820 you when you are very simple answered is try 0:21:30.820,0:21:32.809 and give you a number which inherently makes[br]it 0:21:32.809,0:21:36.070 good or bad. There's nothing in between, and[br]then 0:21:36.070,0:21:38.960 the focus is lost. Like you either start liking 0:21:38.960,0:21:41.340 it or you don't like it. You don't really 0:21:41.340,0:21:46.149 think about what is there in between, right.[br]Yeah. 0:21:46.149,0:21:47.950 So the focus on, focus on some of the 0:21:47.950,0:21:49.499 aspects of where is the coverage, you know,[br]what 0:21:49.499,0:21:51.909 does it mean, right. One thing that worked[br]for 0:21:51.909,0:21:55.109 us was code climate in the region projects.[br]I 0:21:55.109,0:21:56.989 really like it because they put a lot of 0:21:56.989,0:21:59.700 focus into the presentation aspect of it.[br]Not just 0:21:59.700,0:22:03.179 the collection aspect of it. It really, you[br]know, 0:22:03.179,0:22:06.929 takes you down to the, to the code, which 0:22:06.929,0:22:09.649 is missing the specs. Of course, they do also 0:22:09.649,0:22:11.940 other metrics like code quality, which I really[br]like, 0:22:11.940,0:22:14.489 by the way. They have some notification things[br]like 0:22:14.489,0:22:17.109 that, like, on, like Lexus a lot, whenever[br]this 0:22:17.109,0:22:19.169 climate goes in, poof the coverage goes down[br]or 0:22:19.169,0:22:21.019 something like that. [00:22:19] It doesn't[br]break the builder 0:22:21.019,0:22:23.600 part, it doesn't break the build, but it lets 0:22:23.600,0:22:25.080 you know, and then you can deal with it 0:22:25.080,0:22:27.109 if you think it is important to deal with. 0:22:27.109,0:22:30.389 P.S.: OK, speaking of breaking build, how[br]many of 0:22:30.389,0:22:35.859 you know what racheting, in builds? OK. So[br]the 0:22:35.859,0:22:37.999 idea of racheting is basically you will never[br]leave 0:22:37.999,0:22:41.100 your code base worse than what it already[br]was, 0:22:41.100,0:22:45.059 right. So every commit basically makes sure,[br]even if 0:22:45.059,0:22:46.759 it doesn't do any good, it doesn't do any 0:22:46.759,0:22:48.779 bad to your code base. So for example, if 0:22:48.779,0:22:51.859 you're, your current code coverage is at 70%,[br]and 0:22:51.859,0:22:53.840 if this check-in makes it 69%, it will break 0:22:53.840,0:22:56.309 the build. Even though there's nothing functionally[br]wrong with 0:22:56.309,0:23:00.169 it, you know, it's bad, right. We really think 0:23:00.169,0:23:02.600 it's a double-edged sword. I will, this is[br]one 0:23:02.600,0:23:05.249 of those things which I have a, in theory 0:23:05.249,0:23:08.629 sounds very, very good, and direct, but in[br]practice, 0:23:08.629,0:23:10.950 what it typically ends up doing is people[br]end 0:23:10.950,0:23:14.539 up fretting the actual metric, and never about[br]what 0:23:14.539,0:23:17.570 the problem is, right. Becau- this exactly[br]does what 0:23:17.570,0:23:20.450 we said in the previous slide, which is coverage 0:23:20.450,0:23:24.029 is never red or green, right. Sometimes you[br]are 0:23:24.029,0:23:26.359 OK with taking this hit because you want to 0:23:26.359,0:23:28.859 do something. I mean there are all, there[br]are 0:23:28.859,0:23:33.720 so many reasons why which, in practic- in[br]reality 0:23:33.720,0:23:35.850 you may have to do some bad things, and 0:23:35.850,0:23:37.509 eventually have to pay for it, but it's OK, 0:23:37.509,0:23:40.690 it's a conscious decision, right. But racheting[br]invariably stops 0:23:40.690,0:23:44.759 that. It makes it very, you know, black and 0:23:44.759,0:23:45.470 white, right. 0:23:45.470,0:23:47.309 A.K.: Difficult for you to proceed at 0:23:47.309,0:23:47.869 that very moment. 0:23:47.869,0:23:49.369 P.S.: Yeah and it has a 0:23:49.369,0:23:53.379 more behavioral impact on the team, which[br]is your, 0:23:53.379,0:23:56.850 your team members start hating either the[br]racheting, or 0:23:56.850,0:24:00.259 they start hating the metric, or you know,[br]we 0:24:00.259,0:24:03.799 had this one person who did not commit for 0:24:03.799,0:24:06.129 four days because they thought they did not[br]have 0:24:06.129,0:24:09.299 enough test coverage. And, like, when we breached[br]the 0:24:09.299,0:24:12.350 whole, OK, frequent check-ins, call check-in,[br]and this person 0:24:12.350,0:24:14.389 was actually scared because they were about,[br]they would 0:24:14.389,0:24:17.600 break the build, is actually a, very, very[br]bad 0:24:17.600,0:24:20.729 signal, of, a bad sign from your team, right. 0:24:20.729,0:24:22.690 Now well, you can always argue, OK, this person 0:24:22.690,0:24:25.139 totally missed the point, we can say a bunch 0:24:25.139,0:24:27.499 of things, right, but this is the reality.[br]So 0:24:27.499,0:24:29.739 we think that it's a good idea, so that 0:24:29.739,0:24:32.039 you might want to do it at certain points 0:24:32.039,0:24:35.229 in time. But yeah, be very, very careful about 0:24:35.229,0:24:37.729 the freakanomic implication that it has on[br]your team, 0:24:37.729,0:24:38.080 right, always keep that in mind. 0:24:38.080,0:24:40.419 A.K.: And then 0:24:40.419,0:24:43.269 the very other popular thing, which is, you[br]just 0:24:43.269,0:24:46.109 write that test to bump up the coverage, if 0:24:46.109,0:24:46.679 you're not just- 0:24:46.679,0:24:47.309 P.S.: Yeah, so there was, there 0:24:47.309,0:24:49.769 was just one more philosophy of full-on coverage??[br][00:24:50], 0:24:49.769,0:24:52.429 which is saying, OK, you just checked-in code,[br]but 0:24:52.429,0:24:54.249 you don't have a test for this, but that's 0:24:54.249,0:24:56.669 OK. There's this other class which does not[br]have 0:24:56.669,0:24:58.669 a test for it, which is easy, so let's 0:24:58.669,0:25:01.479 start this there and keep my coverage maintained[br]right 0:25:01.479,0:25:04.049 there. There's so many, like, weird things[br]people end 0:25:04.049,0:25:06.389 up doing, just because they are now worried[br]about 0:25:06.389,0:25:09.119 coverage and not really worried about what[br]it means 0:25:09.119,0:25:11.470 to- you know, what it means with what they 0:25:11.470,0:25:12.419 are doing, right. So it's- 0:25:12.419,0:25:14.759 is done with the best of intentions, but then 0:25:14.759,0:25:16.749 you get really, really bad, cause, like- 0:25:16.749,0:25:17.320 P.S.: Yeah. 0:25:17.320,0:25:19.879 So, OK, how, how did we go, I mean, 0:25:19.879,0:25:22.440 how do we now improve, like, so we still 0:25:22.440,0:25:25.639 take on a lot of projects, customer, we are, 0:25:25.639,0:25:27.600 we are mainly now in consulting, so we do 0:25:27.600,0:25:29.889 end up taking worker code bases, right. So[br]what 0:25:29.889,0:25:32.389 do we do to improve coverage if we have 0:25:32.389,0:25:34.690 a bad one? One thing we realized is adding 0:25:34.690,0:25:37.950 unit tests to classes, existing classes, could[br]be a 0:25:37.950,0:25:41.200 very dangerous thing, right. What that essentially[br]means, is 0:25:41.200,0:25:43.369 you have, you know, you are cementing the[br]current 0:25:43.369,0:25:46.379 design. Now I won't say, like prejudiously,[br]it might 0:25:46.379,0:25:48.639 be bad to say not a good design, right. 0:25:48.639,0:25:50.989 But you are cementing it, right. If ever you 0:25:50.989,0:25:54.470 want to cement something, cement features.[br]Cement functionality, right. 0:25:54.470,0:25:56.529 Which means you might want to write like a 0:25:56.529,0:26:00.059 much higher level test of, and, you know,[br]ensure 0:26:00.059,0:26:01.799 that the functionality is the same, so that[br]you 0:26:01.799,0:26:04.239 can go and refactor later. On this one project, 0:26:04.239,0:26:07.009 which Yogi, me, and Jake worked together on[br]in 0:26:07.009,0:26:11.470 ThoughtWorks, it worked beautifully for us,[br]where we were 0:26:11.470,0:26:15.879 strangling ?? to Hibernate [00:26:14]. Which[br]meant that all 0:26:15.879,0:26:18.840 that entire unit tests and database level[br]tests were 0:26:18.840,0:26:21.960 completely invalidated, they were useless,[br]right. And because of 0:26:21.960,0:26:24.309 the way, and because we wanted to turn on 0:26:24.309,0:26:26.470 to caches?? [00:26:24], transactions changed.[br]Like that meant the 0:26:26.470,0:26:30.100 whole app was rendered useless from a testing[br]point 0:26:30.100,0:26:31.359 of view, right, from a safety net point of 0:26:31.359,0:26:34.979 view. But what came to our help was controller 0:26:34.979,0:26:38.289 and beyond level tests. So our biggest, we[br]had 0:26:38.289,0:26:40.929 such good coverage there, that we went in[br]and 0:26:40.929,0:26:42.989 we just modified a whole bunch of things,[br]and 0:26:42.989,0:26:45.399 we like started deleting tests, you know.[br]You get 0:26:45.399,0:26:48.289 a lot more flexibility and freedom inside[br]your code 0:26:48.289,0:26:49.840 base when you know that you're not breaking[br]any 0:26:49.840,0:26:53.210 functionality. So yeah like it's a really,[br]really, like, 0:26:53.210,0:26:55.570 good thing, so definitely think about it when[br]you're 0:26:55.570,0:26:57.229 inheriting a legacy codebase. 0:26:57.229,0:26:58.669 A.K.: Unit tests, unit tests 0:26:58.669,0:27:01.279 are great, but do keep in mind that they 0:27:01.279,0:27:03.029 might also come in the way of- 0:27:03.029,0:27:03.619 P.S.: Changes. 0:27:03.619,0:27:04.489 A.K.: Refactoring, and changes. 0:27:04.489,0:27:04.909 P.S.: Yeah. 0:27:04.909,0:27:05.899 A.K.: Big, big refactoring- 0:27:05.899,0:27:07.739 P.S.: So, OK. What - the whole measurement 0:27:07.739,0:27:11.399 reporting, racheting, improvement, all of[br]this is basically saying, 0:27:11.399,0:27:13.279 always keep the problem you're solving in[br]mind, right. 0:27:13.279,0:27:15.739 Rachet don't rachet - how do you decide? Well, 0:27:15.739,0:27:17.950 is it helping you to achieve your goal, or 0:27:17.950,0:27:20.460 the problem you have at hand? Sure, you know, 0:27:20.460,0:27:26.499 so do it. Otherwise don't do it, right. It's- 0:27:26.499,0:27:27.249 Yeah. 0:27:27.249,0:27:28.659 A.K.: I think- 0:27:28.659,0:27:29.999 P.S.: So, the second- 0:27:29.999,0:27:30.669 A.K.: Let's- 0:27:30.669,0:27:33.350 P.S.: -anecdote- I'll just be, quickly talk[br]about- 0:27:33.350,0:27:35.359 A.K.: We have five minutes, so- 0:27:35.359,0:27:36.359 P.S.: Yeah, like, 0:27:36.359,0:27:37.369 the second anecdote was basically, OK, we[br]had this 0:27:37.369,0:27:42.489 server which was under a very heavy load.[br]And, 0:27:42.489,0:27:48.629 like thousands of requests, a minute, and[br]only about 0:27:48.629,0:27:52.320 5% of those requests, in very seemingly arbitrary[br]periods 0:27:52.320,0:27:56.340 of times, and arbirtrary controllers and actions,[br]would pause, 0:27:56.340,0:27:59.409 and it would take a very long time, right. 0:27:59.409,0:28:01.899 So the- this problem was way more technical.[br]It 0:28:01.899,0:28:04.169 had nothing to do with the behavior or, you 0:28:04.169,0:28:09.440 know, like, or practices part of, or side[br]of 0:28:09.440,0:28:11.460 things. It was pure technical problem. And[br]goal was 0:28:11.460,0:28:13.059 for us to find the root cause of this 0:28:13.059,0:28:17.200 unpredictable behavior and fix it, right.[br]And, yeah, like 0:28:17.200,0:28:20.340 we were, like we can definitely talk about[br]how 0:28:20.340,0:28:22.499 we went into, like a lot of different solving, 0:28:22.499,0:28:24.549 a lot of different symptoms, at one point[br]even 0:28:24.549,0:28:28.159 suspecting JRuby. You know, like, so it's[br]very, like, 0:28:28.159,0:28:30.580 it becomes very hard for you to figure out, 0:28:30.580,0:28:32.470 OK, what is a problem, what is a symptom, 0:28:32.470,0:28:35.159 and like, go very methodical about it, right.[br]So 0:28:35.159,0:28:38.009 that's what this, this problem was going to[br]be 0:28:38.009,0:28:38.999 about. But let's take this offline. At this[br]point 0:28:38.999,0:28:39.029 we can- 0:28:39.029,0:28:39.139 A.K.: I mean, before that, yeah, let's 0:28:39.139,0:28:43.159 get out some questions. 0:28:43.159,0:28:45.839 P.S.: Yeah, let's take some 0:28:45.840,0:28:47.720 questions if you have any. 0:28:47.720,0:28:48.920 A.K.: Cool. 0:28:48.920,0:28:50.520 P.S.: Cool, thanks. 0:28:50.520,0:28:51.720 A.K.: Thanks. 0:28:51.720,0:28:53.180 P.S.: Thanks guys.