324: Coding Time!
The Bike Shed - Podcast autorstwa thoughtbot - Wtorki
Kategorie:
Chris updates us on his new window manager of choice, Moom, and tells us what's good with it. He's also giving yet another task manager a go: OmniFocus. (Sorry Things.) Steph talks about defining test classes in RSpec and readdresses flaky tests to improve CI build time. Chris is worried about productivity. He's still not coding as much as he'd like to be. Steph lends an ear, and together, they discuss potential ways Chris could gain back a little bit of coding time at work. This episode is brought to you by ScoutAPM. Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. Moom OmniFocus Is It Worth the Time? Knapsack Pro Shopify Monolith Sacrificial Test Classes rspecq Become a Sponsor of The Bike Shed! Transcript: STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari. CHRIS: And I'm Chris Toomey. STEPH: And together, we're here to share a bit of what we've learned along the way. So hey, Chris, what's new in your world? CHRIS: What's new in my world? Well, hey, Steph. Oh, I have an update on a thing that I think I talked about a while back or at least asked on Twitter. But I've been looking for a window manager for forever. And in that way that I sort of overcorrected a while back, I think where I'm no longer allowed to do anything related to productivity or dev tools. I was just forbidden because it was a time sink. I'm slowly trying to correct back and be like, you know what? I regularly think about how it would be nice to have a better window manager. So previously, I had used Divvy, D-I-V-V-Y, which is fine. It did an okay job, but it just didn't have quite the level of control that I wanted, or maybe I didn't investigate it enough. But it felt like it was lacking. So I did a little bit of research. A bunch of people recommended different things. There was Spectacle; there was Rectangle. There was a whole bunch of other things that I'm forgetting now because I have settled on Moom, M-O-O-M. Those are fun words. STEPH: I feel like you keep bringing interesting words [laughs] because last time, it was Things where you're tracking all the things. And now we have Moom to track the space. All right. CHRIS: If this is my legacy as a podcaster, then I feel like I will have done well just, you know, weird sounds mostly that's what he's going for. But yes, I've been using Moom now for…[laughs] God, it's just ridiculous to say, but here we are. STEPH: [laughs] CHRIS: I've been using it. I've been enjoying it. In particular, the thing that I liked about it...a bunch of the other ones that I looked at were like, oh, we've got all these different configurations. And you can move things any which way, and you can have any number of hotkeys. And I was like, wait, wait, wait, say more right now. You want to take over my global namespace of hotkeys and just clutter it with 19 different things? You know that that is a limited space that I'm working with here. And so Moom, somewhat uniquely, at least in the ones that I experienced, was what I would describe as a modal window manager. So much like Vim is modal where you start out in normal mode, and you're moving around and you kind of bounce and search and all of that, and then you enter insert mode. And in insert mode, keys do different things. And then in command mode...it's got all these different modes. And so there are lots of different namespaces for hotkeys. It's one of the things that makes Vim so powerful. Moom is similar in that there's one global activation hotkey. And then, within that, I can have a whole namespace of hotkeys. So like M will put something in the middle of my screen now. F will put something full-screen. And I don't need to remember weird multikey combinations for that. There's just the one to get started, and then I've configured it such that the tab will bounce to a secondary display and sort of rotate through them. M and F and Q and P I've got it physically laid out on the keyboard. So it looks like my screen. Q being on the left side will push something to the left side, P to the right side. And I'm very happy with that. I don't need a lot out of this tool. I don't need very complex management or scripting or any of that, which are very nice features that exist in the other ones. But that combination, the one hotkey to rule them all, and then the sub hotkeys within it, and the ability to mostly move between the screens and then put stuff where I want it is great. I'm very happy. STEPH: I think I've figured it out. So Moom, I think it's a combination of move and zoom, and that's how they got Moom. CHRIS: You're probably right. STEPH: That does sound really nice. I'm a Spectacle fan. And I have enjoyed it and just stuck with it because I haven't felt a need to change from it. And it's really nice where I use my arrow keys for which direction I want to go. So that has been easy for me to recall. But that sounds really nice, all the things that you're describing with Moom. CHRIS: Does spectacle have the like, is it some Command Option Control and then left or right or up or down? Or is it you type something, and then you type left, right, up, down? STEPH: I have to actually touch my keyboard to answer that question because I have the muscle memory, which is an interesting thing that my muscles knows it, but my brain has to really think about it. So I think it's like the Option Command, and then yeah, then use the arrow keys. CHRIS: Gotcha. That's roughly what I had when I was using Divvy previously, but I found just enough of a limitation there. And so Moom has been great as another tool. But I think Spectacle has a lot more features in terms of scripting and other fancier stuff that you can do, which is both super intriguing and, again, sort of the thing that I'm not allowed to do. [laughs] So I went with, like, this tool seems fine and has the one feature that I really want. That said, you brought up Things, which is the to-do list app that I've been looking at. I've been using it for a week now. It's great. I'm enjoying having a more structured way to say, like, here's what I'm doing today. Here's what I'm doing tomorrow. It's been wonderful. But I'm already looking at OmniFocus as a better version. STEPH: [laughs] CHRIS: Because I think there's some stuff that I don't love, and yes, I can hear my own voice in the back of my head that's like, always chasing that next thing. But I haven't actually made the effort to switch over or even tried. I've used OmniFocus in the past. But anyway, I'll let you know if I do make additional moves there. STEPH: Yeah, I'm enjoying this journey. Keep me up to date on it. I've heard of OmniFocus, but I know nothing about it. But I feel like I've heard good things. So I like this journey you're going on where you just keep switching and trying new things. That's fun for me [laughs], and there's chasing productivity. So I'm into it; I'm here for it. CHRIS: If I just invest enough hours to save a handful of minutes down the road, then I will have...oh no, wait, that's not how this goes. There's, of course, an xkcd about this which we can include in the show notes. But I'm trying to be very intentional with it. I waited for many years before I allowed myself to reinvestigate the world of to-do lists. And I'm hopefully going to keep it to just a couple of weeks of nonsense and then back to a few years of stable. That's the dream. But yeah, that's some of the smaller things that are up in my world. I have another topic that I want to chat about. But I'd love to hear what's new in your world? STEPH: Yeah, I have some interesting bits that I can talk about with the project that I'm working on. But more concretely, I have something that's been on my mind that I don't think that I've talked about here on the show, but I think would be fun to talk about because I just happened to run into it this week while working on some code. And it's the idea of defining test classes in RSpec so as you are testing part of your code, but then you want to create just like a fake class, something that you can use as a substitute for real application code. And so it's a really nice way that then you can have this replica behavior, but then maybe it's just one particular method or some behavior that you need to use in the class but then doesn't actually go to the real code. That's wonderful. That's great. One thing that I've learned is that with RSpec is when you are introducing a test class, so let's say if you have your RSpec describe and then either a string or it's the name of a class, and then you have a block so do, and then within that block is where you write your test. If you create a temporary class, say, like I have my class test class, and then I have some behavior, that gets defined in the global namespace. It's not scoped to that particular RSpec example. And the reason for that it's not specific to RSpec. RSpec is not the one that's doing this; it's actually Ruby behavior. So for Ruby, when you're defining within a block like that, if you're defining a constant, if you're defining another class inside of a block, it's going to use the outer namespace as its namespace. So if you had a top-level class that you were defining, but if you define a class as a block, and then inside of that block you define a constant, that constant is then defined in the object namespace instead of within that particular class that you have written. And so that's why RSpec has this behavior. Because someone brought up a really great question about this on RSpec::Core asking about it, and they're like, yeah, that's actually how Ruby works. And so we're not going to change RSpec's behavior since that is how Ruby has decided to handle this. And the part where this becomes important is when you define a test class within an RSpec example. While it may be unlikely that someone is going to use that exact same name for their test class that they're going to create in their RSpec example, if they were to use that same name, then you're going to have a collision between the two. One of them's going to win, and you're probably going to end up with some really weird test failures because it's going to get confusing as to which class is being used, and they may not match up with each other. So one way around this, and this is going to be one of the rare times that I suggest this, but let. Let is scoped to an RSpec example. And so you could define a class inside of a let, and then that will scope it to the example. There are probably some other approaches as well, but that's the one that I'm most familiar with to ensure that when you define that class or constant, it's not getting defined in the global namespace and ensuring that none of the other tests have access to it. CHRIS: Well, this is certainly interesting. I'm pretty sure I've been operating under the opposite assumption for the entirety of my career. This is good to know. I feel like I probably have had tests that failed because of this. And then I learned this truth, and then I subsequently forgot it. I don't know if you know this, but if you define a method within just a helper method that you extract in RSpec, are those also on the global namespace? I don't define classes in RSpec blocks that often. It's pretty rare. Like if I have a controller concern sort of thing that I want to test, I might say random controller and inject the thing there or some other abstracted piece. That is the only case I can think of where I have a fake model or a fake controller or something like that for test purposes. But it doesn't come up that often. I do extract a heck ton of local helper methods. And I'm wondering now, are those all in the shared global namespace? STEPH: I'm pretty sure they're not. And I'm getting on the edges of my knowledge here, but I think it has to do with the fact of when you're defining a constant. So if you're defining a class versus an actual constant, that will get into the global namespace because it's using the outer scoping. But in my experience, I'm pretty sure that's not true for the method just because I remember one time I did some funky stuff with RSpec. And I remember seeing that I couldn't access those methods from another example. CHRIS: I like the honesty. And you're like, to be clear, I was doing something weird, but I learned that day. Okay, that's good because at least that part maps to my understanding. So methods may be safe, but classes get shared. Very interesting. STEPH: And it's something that I rarely think about or had worried about just because if I'm defining a fake test class, I often will put it somewhere that's intended to be more global. So I'll stuff it somewhere in like spec support. So then other people can see, hey, I've already mimicked this behavior. So if you need to use the same thing, just go ahead and use this. It's not often that I am adding that class directly to the RSpec example group. So I think I've been fortunate where I haven't actually run into that conflict for that reason. But this came up while giving an RSpec course. And while we were just in a very small, tiny codebase and replicating some examples, someone in the class was like, "Hey, by the way, do you know that that's in the global namespace?" And I was like, "No, friend. Tell me more." So thanks to that person, they're the ones that actually enlightened me about how it's going into that namespace and how it can actually pollute your testing namespace. There's a really good article that's written by Ken Mayer. And we'll be sure to include a link in the show notes that talks about it and also provides the let example as a way to work around this. And also links to the GitHub discussion on RSpec::Core, where they talk about this behavior and why things are the way that they are. Circling back to some of the more general project-y things that I alluded to earlier, I've shared a bit about the project that I'm working on. But just to recap it, it is focused on helping a very large team that has a large number of tests, around 85,000. And they are looking to address flaky tests that they have and overall really improve their CI build time. So right now, it takes about 30 minutes for the build to take place. But they also have flaky tests, and then that slows things down. And so, the re-verify rate has been painful for them. There's been some really great work that has improved that, particularly there is a, I think we've talked about this before, but where they're re-verifying certain flaky tests, which isn't great because they're still flaky tests, but at least they're not preventing people from moving forward and shipping code. But some of the bigger stuff that is just on my mind is when you have a very large team and a very large application, by large team, I'm talking about 100 developers, and they are all contributing to this codebase. And there are around 85,000 tests, and that has grown substantially in the last 12 months. And so, if you think about the trajectory of the addition of those tests, it is just going to continue to grow. So there's a concern there of even if we address flaky tests and we improve things, there's an architecture concern of how do we really reduce the CI build time? And so there's that aspect, and then there's also the aspect of then well, how do we still work to improve the tests and the codebase as well as we go across all of these disparate teams? And right now, there is a bit of a culture where engineers don't feel empowered where they can necessarily address all of the flaky tests or things that they run into. And so there is a bit of a mindset of I'm stuck on this, or this test failed, or it's flaky, or I don't understand it. So I'm just going mute it, or I'm going to hand it off to someone else to work on it. So there are three big areas that are on my mind. The first one is architecture. You can throw architecture at it. There's also the code quality that's a concern. And then how do you improve the code quality in a way that you're improving it fast enough that then you've got 100 other developers that are also contributing to it at the same time? And then individual IC empowerment where then people feel like, hey, I ran into a slow test or a flaky test, and I feel like I can triage this, and I can make changes. For the architecture piece, we're still in the infancy stages of how to approach this and the strategy that we're using. But one of the ideas that has come up is how do we reduce tentpoles? And the tentpole is like when you're running your test and, let's say that it's parallelized, all of the various tests. But there is one process that takes like 20 minutes, and then the other process is completed in 5 minutes as a drastic example. And overall, you could have reduced your time if you had managed to split that 120-minute process across all the other workers who are then available for that work. So there are some tentpoles that are taking place. And that could be one first step in reducing the CI build time. There are also discussions around how to scale horizontally. Right now, we don't think that's something we can do with the service that we're using to run the test. But it's something that maybe we need to manually look into is then how do we build a queue of all these tests and not where we just split test by a file, which is typically how the Parallelize gem does it. But you could actually split up tests within a file. So if you had a particularly large file, that doesn't necessarily matter. But then building a queue of all these tests so then as each test finishes, a worker can just grab that next test. And then also you can easily scale up and scale down workers. As I'm saying that, that feels big, that's a lot to invest in. But that as an idea is how can we essentially then scale the architecture? So even as we continue to invest in the tests, in the system, and they continue to grow, our architecture can keep up with it. CHRIS: That last bit there is super interesting to me. It's something that I've looked into and haven't pursued yet. We're currently running on CircleCI with our test suite. And I don't even know that we pushed on parallelization because we're early enough on that. And we turned off bcrypt recently, which super-duper helps with the speed up. But overall, the test suite time is fine, is where I would put it. It had crept up, though, to a place where it was starting to be painful, is how I would describe it. And I think it's very easy for that to just continue growing and suddenly, it's 20 and 25 minutes. And then, depending on your merge strategy and all of that, it can be all the more complicated, and this gets in the way of deploys. And so, I think it is a super important thing to keep an eye on. I know Charity Majors pushes really hard for 15 minutes from merge to deploy to production. And so if your CI suite takes 25 minutes, then already you're stuck. As an aside, I just once more want to say out into the ether, CircleCI or any other CI platform, if you would allow me to say yes, we've already tested this Git hash, this Git SHA, or the working tree, ideally, because that's also deterministic, I would love that feature. I would love to not have to rebuild the same code when it gets merged into main, just saying once more out into the world. Also, GitHub, if you want to put me on the merge queue beta, I would love that if anybody out there is listening. [laughs] STEPH: I like how this has become a special requests hotline for all the things [laughs] that you're hoping to get a part of or features you'd like to see added. CHRIS: Hello, internet. I have some requests. STEPH: [laughs] CHRIS: I would love to see those things, but in the world where those don't exist. The particular thing that you're talking sort of a test queue, is something that I've seen. So Knapsack is a...what's the word? It's a tool; it's a service. It's a combination of things. But it does that essentially where it starts up a local build agent. And then it basically says like, all right, give me all of the tests that you need to run, and then I will feed them back to each of the individual agents that there's one agent running per parallelized process. And so say you've got five of them. The first one says, "Hey, give me a test," and runs it. And the second one says, "Give me a test," and et cetera. And so, the queue manager on the other side is in charge of that orchestration. And it means that they basically all finish in identical time, with one being an outlier, whichever one happens to be the longest. But it's only going to be however long your longest test is is basically that outlier versus what you're describing of like, well, if we split it by file, we can end up with more naive things where there's a bunch of feature specs on one of them, and it skews by two minutes. We obviously don't want that. So Knapsack, in particular, is a tool that I've looked at, but generally, I'm very interested in that as a solution to how do we maximally take advantage of parallelization there? STEPH: Interesting. I have not heard of Knapsack. There is one that sounds similar. It's called RSpec Queue. And it does some really interesting work where it will split the individual test, so it won't do it by file. It will also look at historical data to then try to be intelligent about how it's going to split it and find the longer running test. And I believe it uses Redis to then keep track of the test set up in run and things that still need to be run. That is a gem that the team is looking into using as well. I don't know how that works if that can integrate with the current platform as we're using TeamCity to run tests. I don't know if that's something that can integrate with TeamCity, if it's a replacement. I don't have all of the knowledge about RSpec Queue yet. But it seems to do a number of the things that we're interested in. So even if we can't use the gem, then maybe it's something that we can still imitate. CHRIS: The other thing that I'm surprised we haven't said yet is this is one of the places where people would often reach for microservices. I feel like we have to have the microservice conversation at this moment. Microservices can actually be a great solution to organizational problems. As a team scales, it does become really hard to manage a large group of developers. And so microservices introduces a very fixed boundary that then draws nice lines that you can have around things. And so, the individual build time for a portion of your application can be much more manageable by virtue of that. But it has this huge cost of technical complexity and overhead and et cetera, et cetera, all of the reasons that we may not want to go that route. And so interestingly, I was just looking at Shopify's Deconstructing the Monolith blog post, which I think at this point, they've skewed a little bit more into the microservices. Shopify is huge, one of the largest Rails apps out there. And so looking at them and being like, oh, what are they doing? It's an interesting sort of plot a course and to see how long they waited before they even started thinking about the much deeper things and even exploring microservices. But in this blog post, they talk about a different approach where they stuck with sort of a monolith. But then they started to introduce Rails engines and clear encapsulation within the large codebase such that then you can actually start to say, well, we don't need to run all the tests every time because if we're making a change within this section of the application, then we just need to run those tests. I've also heard of organizations having some logic that can determine based on the code change; we know the associated test files that we should run. I'm scared of that is how I would describe it. I want to trust my test suite. I want to be able to deploy on a Friday and say if tests are green, it's going out to production. That's great. And I worry about that sort of thing. That's hard to get right. That feels like caching, right? And that's one of those things that we historically get wrong a lot. But nonetheless, that is an approach that large organizations I've heard having good success with. So some way to determine what's the affected code and what tests do we need to rerun and et cetera. And that can really drastically reduce down the scope of each CI build. But those are some larger things that I have not had to reach for on any of the applications I've worked with. I've taken different approaches, different ways to reduce the time or otherwise Parallelizer et cetera. But it's interesting for when you get to a certain scale. STEPH: Yeah, it's funny that you bring up that idea because that came up in conversation with some of the other developers as well, was the idea of, like, what if we could just not run all the tests? You changed one file, and you don't need to run everything. And I immediately was like, that sounds very cool and super hard to be able to get right. And a lot of this code is extremely coupled, which then moves to the code quality area. So I suspect a lot of the test times could be improved by creating smaller objects because right now, a lot of the tests will load the entire world because they have to. They have to test everything. And so that is creating a ton of data, and then taking a long time to run versus if we were able to split out that code into smaller objects and test in unit tests, then that would also help speed up. But that's also hard to do. Where do you look first? We do have some great data, thanks to RSpec. RSpec is letting us know how long each test file takes to run, and then we are capturing that data. So I can go look at which files and say, oh, this file takes 10 minutes to run. Let's look at that file first versus some of the other ones that are performing better. But that is a battle that will take a long time to win. And it's something that takes consistency and then also encouraging others to join that battle. So while it's very important, it doesn't address the concern of tests growing rapidly and then being able to support that. Something that you said in a previous episode also was on my mind in talking about building processes in a way that encouraged people that they can make small, quick changes. And I think that's really important. So if we can build out the architecture to help scale this so then the tests were running in say 15 minutes, then if someone saw a test and they wanted to make a small refactor, they saw a factory.create, and they're like, oh, that could be a FactoryBot.build_stubbed instead and issue that into a pull request or change request and get that merged. I don't know if people feel as comfortable doing that right now because it takes them 30 minutes or longer to run the test. But that idea of how do we get a structure in place where people can make tiny, little improvements and do that as a whole, as a team, to then work on the code quality concerns? CHRIS: That last little bit is so interesting where you're saying, like, oh, we have a FactoryBot.create, FactoryBot.Build, but it has the overhead of having to go through the 30-minute test suite. But coming back to the thing we were talking about before, what if we didn't have to run all the tests? Although I find it very hard to tell, given a code change in actual production code, what tests do I need to run? When I'm just changing a test, I'm pretty sure I know which test I need to run in order to determine if that test still runs correctly. So that feels is there an optimization that can happen there? Which is I've only made test changes; therefore only run the changed tests. And then that's an encouragement to say, like; this is a part of our codebase that we are trying to improve on. Let's optimize the iteration speed there. You'd have to figure out how to write that. And so it's probably much like my productivity adventures, maybe not a good investment. Although given that this is such an organizational concern, maybe that is the thing that's worth spending an afternoon on and seeing if it could happen. Because if you can speed that process up, get more [inaudible 23:46] and more iteration in fixing the tests, that feels like it could be a win. STEPH: I think that's a really good idea. I think we could certainly tell that if a file's changed, that it's only a test file that has changed. And then I've heard very good things from the other developers that TeamCity has a wonderful API to work with. And so there's a way that we could then tell TeamCity to say, hey,...or it may not even be a TeamCity command. It may just be somewhere in the universe we have to say, "Hey, RSpec, only run this test," or "TeamCity, we're only going to feed you this one RSpec test to run, so user agent but only run this particular test." So I really like that idea. I think that's really intriguing. And I'll bring it up with the team because that would be a huge win, especially as Joël and I are really focused more on tests. That would just improve our lives. So selfishly, I'm excited about that idea because we are touching less of the application code and more focused on improving the test at this point. CHRIS: I mean, if right now you're getting, say, 5 or 10 pull requests through a day which frankly feels like a high bar on this, if suddenly that's 10 to 20, that's material right there. STEPH: Yeah, I don't know how large of an impact it would have for the rest of the team because I don't know how often they're only making changes to a test file, but it still feels like a nice optimization to have. Cool. Well, thanks. I appreciate that idea. CHRIS: My pleasure. Mid-roll Ad And now a quick break to hear from today's sponsor, Scout APM. Scout APM is leading-edge application performance monitoring that's designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise platform feature bloat. With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve those performance abnormalities like N+1 queries, slow database queries, memory bloat, and much more. Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them. Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform. See for yourself why developers call Scout their best friend and try our error monitoring and APM free for 14 days; no credit card needed. And as an added-on bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. Learn more at scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. CHRIS: What else is going on in my world? I continue to not code a ton which is interesting and probably makes sense for right now. But to share a small anecdote from this week, we had retro, and I ended up attending retro ever so slightly late. I was doing a hiring interview, which is super exciting. Again, for anyone that's out there, we are hiring at Sagewell Financial. And I would love to chat with you if that sounds interesting. But so I was having a wonderful hiring conversation that ran a little bit long. So I was a little bit late to retro, and I arrived, say like eight minutes in, and someone was expressing a concern. And the concern was, I very sincerely know this to be true, but they were saying in the most positive way. But they were like, "It'd be great if Chris could code more," and not in the judgmental like, Chris, why are you not getting as much done? Not in that way at all, very much in the it would be great if Chris had more time, if there wasn't as much pulling my attention in different directions. But then it kind of went into this interesting direction. So we then go back through and address the concerns and talk as a group about how we resolve them. But this one was like, my name was in the concern, again, in a very positive way, in a very supportive way. And we had a wonderful conversation, and there were really great ideas that were passed around. But man, did I feel weird having my name in a retro item. [laughs] STEPH: So one thing I've learned is that you do a really good job when you are giving presentations and being in the spotlight. But I don't think you actually love it. You love sharing content and things that you have learned. But I could see how being a focal point, especially if there's a concern or something that could have a negative connotation, that would feel squeamish. It would make me feel squeamish. CHRIS: I hadn't thought about it in that way. But as you say it, also, this conversation is a meta version of that. Like, let's talk about me talking about me. I don't want to be the center of attention. But I love technology or process. I love talking about the work. That's great. And so I'm happy to do that. I'm happy to stand in front of a room and talk about it. But yeah, when it's about me, that's weird. And so now I'm going to move...well, no, I'm not going to move on [laughs] because this is the topic right now. But so there's a bunch of things that we have been trying to introduce. And I think this is a useful part of the conversation more broadly and less about me. So one of the things that I think I mentioned in a previous episode was the introduction of point-dev, which is each week, we rotate through a person. And that person is in charge of triaging the errors, making sure that nothing is stuck in Sidekiq, responding to any support requests, et cetera, et cetera. But they're meant to be the frontline such that everyone else can be heads down and really focus on the work. And what was interesting of the three developers that are working on the project, I am point-dev this week. So I was like, yes, that's awesome this week because I'm the person on the frontline. That has not helped me, but in the future, it will. And then one of the other developers mentioned that they feel like it's really useful but also feel like it's been noisy. And we realized the previous week was their week on point-dev. But the other developer was like, "Yeah, it's been great. I haven't had to think about anything." And so they have been off of that rotation for two weeks now. They'll be taking it over next week. But it is doing exactly its job of providing that attention coverage so that they can keep their focus on the code, and that's really wonderful. So I'll be honest, when we started talking about it, there was a tiny voice in my head that was like, is this a failure mode? Should we be dealing with the noise rather than having a process to address it in the moment? Should we be dealing with the root cause rather than the symptoms? And I still think that's a good point of view. But we found so much value from this. And as I've mentioned it, many people are like, oh yeah, we have that. It's great. I've heard enough positive things. So I've backed away from that. But there was a voice in my head that was like, are we failing right now? But yeah, so point-dev has been really wonderful. And next week, I will have to...well, frankly, the next two weeks, I'm off of point-dev appointments, so I'm very excited about that. I've been doing some of the product management or sort of the tech side of the product management and helping to triage cards and make sure that there's very clear work lined up for the engineering team when they're ready to do that. I'm trying to back away from that just a little bit. And one of the things that we did there was introduced an inbox column in our Trello board. You know how I love a good inbox. You know how I love to get to inbox zero. But that is a good way for me, for anyone now in the organization, which I don't want everyone to have to learn our processes, but just saying, "This is the place that you put requests, and we will deal with them. I assure you of that." It has been great because that means I don't need to be quite as responsive in Slack. I can just gently redirect people, "Hey, if you don't mind, please put this in Slack in the inbox column, and that'll be great." That thing, though, that gentle pushback in Slack is one of the things that I've struggled with. And this was one of the more personal aspects of the conversation that happened in retro was me being, like, if we're being honest, I tried to do that. But it's not my favorite thing to do in the world. Whenever someone asks me something, I want to be helpful. I don't want to seem rude or brisk or like I'm too busy for you, et cetera, et cetera. So I will often respond to the question or do the thing that they're asking and then say, "In the future, if you could go to this other place." And ideally, I'm slowly moving forward and being like, "No, no, no, please go to the other place. We've talked about this a few times." But it is an interesting example of one of the specific aspects of my personality coming through in this. But that introduction of an inbox has been great. Love me a good inbox, as I said. And then, more generally, we just tried to talk through what are the things that I'm doing? Do I need to own all of those uniquely? And some of them the answer we decided was yes but some of them we decided no. And we started to sort of distribute the work there or some of the meetings or different aspects of it. And so overall, it was a really great conversation but also very weird for me. STEPH: Yeah, because then you wonder, am I not doing the right thing? Am I not spending my time the right way? But then hopefully, that meeting helped reinforce that yes, you are spending your time the right way and that you're doing a lot of productive things. There are just too many productive things for you to do, and so you have to prioritize those aggressively. I like all the things that you just highlighted. There's one in particular, the last one that you mentioned about finding things that you can hand off to others. And I love that for a couple of reasons. It came up in a recent conversation that I was having with some other thoughtbot developers around when someone's on a project, typically someone just falls into being the point person. They just happen to be the person that the client talks to and ask questions and goes through the most. And that's something that is okay. But we want to make sure that that's not a bad thing, that everybody is treated equally, that everybody is given equal opportunities and room to grow. And so, in my mind, whenever someone is that point person, or you have fallen into that role, it is your job to then pull other people up. So if you have been given the responsibility of running a particular meeting each week, then go ahead and do it once or twice, so you can demo it and show it to someone else as to how you do this. But then tag somebody else and say, "Hey, I'm going to let you or ask you to run this next time." So then that person can experience it. They can demo their style, and then it continues on to have more people. So I really like that you are highlighting it's not just beneficial for you to then distribute those tasks, but it's empowering for everybody else on the team as well. I'm curious, so what was the final outcome? It sounds like there are some really good things in place, and you're transitioning, handing some things off. But I can't imagine that things have gotten...all of your priorities are still there. So do you think you'll actually code more, or what's the outcome for next week? CHRIS: Short term, maybe probably not, if we're being honest, but trending in that direction. So one of the things that's going on right now is hiring. That is just an activity that takes a lot of time. And I care a lot about doing that well, both for the organization and then for individuals on the other side. I want to be respectful of their time and communicate in reasonable timelines and not leave people without an answer or follow up or those sorts of things. It probably makes sense for that to sit with me as the starting contact. And then from there, folks that are continuing on in our hiring process they're going to talk to many other members of the team, and that won't just be me. But there are a lot of first conversations that I'm having. And so right now, my schedule has a bunch of that, which is fine and good. And that will hopefully, at some point, we'll hire some great people. And then we'll be on the other side of that. And that piece of the work that I have right now goes away. Some of the other outcomes that we named there were a couple of action items. And so I think those will help, but they're sort of we got to work towards that. One is transitioning a meeting, but it's a biweekly meeting. And I'm not going to just not attend the next one. So it'll be me and one of the other developers attending to transition ownership of that meeting moving forward. And then from there, so like, two weeks from now, I will not have that consideration on my calendar. And that's like one 30-minute block that I get back or, depending on how you think about it, one block that that 30-minute broke up. I do want to touch back just on something that you're saying there. I think you're being very kind to me in saying like, no, but you've got so many things, and so it's hard to do that. I think that's true, but that's kind of the work overall, and my version of that is one thing. But everyone sort of has, as a team, we have a version of like, how are we being most productive? Are we making sure we're doing the most important things? And so it was interesting in the moment, but I think it was a very good conversation. And I want to make sure that both we as a team and then me as an individual, wherever that happens to be the case, are open to these sort of constructive things. Like, frankly, to do the work to figure out how to get work off my plate that hasn't felt like the most important thing. It felt like close to the most important thing, but then there were all the other things that I had to do. So I wasn't doing the work to figure out how to not do the work. It is a complicated sentence that I just said. But this was a case where retro, I think, very usefully highlighted that this was a good thing for us collectively to put effort into such that we can be more productive moving forward. It happened to be slightly more focused on me rather than the entirety of the team. But broadly, that kind of thinking is why I'm a huge fan of retro. I think it's a great place to take a step back think about how we're doing the work rather than just being in the work day-to-day. STEPH: So if I'm internalizing what you said correctly, let me know if not, but it sounds like you're in one of those places, and I've witnessed this with other people and myself where someone is overwhelmed. They have a lot to do, and they're very focused in that grind and in that moment of doing all the things that they have to do. And it's very hard to then say, "I'm in the weeds right now. And then I also have to figure out how to get out of the weeds." And that's a very different skill and mental space to be able to do that. Because often, when you're just in that mode, all you can focus on is a bit on survival at that time. And then it may take other people to notice to say, "Hey, you're in the weeds. We need to figure out a way to help you not live there and to find ways to distribute some of the work." Does that sound like a fair assessment? Because I think I say all that because I've just seen people in that position. And then they think back, like, oh, I should have offloaded stuff earlier. And it's like, yeah, true, totally. And it often takes a retro or someone else coming to you and saying, "Hey, I've noticed...I looked at your calendar today; how can I help?" [laughs] CHRIS: I think that's probably the right calibration. And mostly, my emphasis was just I want to make sure that broadly, any team that I'm on has the space for this sort of conversation. And that thing that you're saying exactly that phrasing of like, "Hey, I saw your calendar. How are you doing? How's that going, though? Are you feeling okay? [laughs] You can't sleep and whatnot." That can be a really useful thing to have and to have organizational norms about what are our expectations of how many meetings someone should have in a week. And where do we start to think about different things? You did use the phrase overwhelmed. I want to say that I'm like 101% whelmed. So I'm just ever so slightly overwhelmed, but it is like I'm in the weeds. I need to figure out how to clear some of the weeds so that then I can get out of it. And it was a great conversation that came from that. STEPH: That's awesome. I'm glad you got a good team that, frankly, felt comfortable bringing it up, and then that you could lean on them for ways to talk about how you could code some more and talk about priorities and where you want to focus your time. CHRIS: It will be an interesting thing. As the team grows, I don't expect this to get easier. We talked about this a number of weeks back. And I think for a while; hopefully, we clear a little bit of dust here, and then I get back to being a little bit more on the code, and that's going to happen for a while. But as I think about the longer sort of the future of the company, this is something I'm going to have to revisit a handful of times. And it's a really interesting question that I'm still struggling with internally. And where do I want to be versus what will be needed and whatnot? So it'll be interesting to see how it evolves. But for now, I think I can gain back a little bit of coding time, a little bit of maker time versus manager time, as Paul Graham's essay goes. And yeah, I think that'll be good. STEPH: Yeah, I like how you're already looking forward to the fact that it will probably fluctuate because, yeah, right now, you are sort of paying a tax. You are building up to then where you can have more people on the team. And then that may give you back some of your time where then you can code because you can outsource some of the work to them. But then, as the team grows, so are other responsibilities. And traditionally, being in a CTO role and most CTOs I know will code here and there because they want to, and they enjoy it, but it is not their full-time job. So I think you're really wise to have already noticed that and start thinking about how that's going to trend in the future. And it sounds like you might need to figure out how to throw some architecture at it. So then you can scale horizontally, and then you can just have more time to do all the things. Yeah, that's right. [laughs] CHRIS: You're suggesting microservices, right? That's how my job becomes easy? STEPH: Yeah. Well, I'm thinking more like RSpec Queue, but we'll have RSpec Chris or some version of that. CHRIS: Chris Queue. STEPH: Chris Queue. [laughs] CHRIS: And then I just paralyze my human, and then it'll be great. STEPH: Yeah, that's always worked out well in the movies. Whenever somebody clones themselves, that goes super well. CHRIS: Multiplicity is a fantastic piece of cinema, and I stand by that. STEPH: I haven't seen it, but I feel like it doesn't end well for the main character. CHRIS: I feel like every time I mention a movie, you haven't seen it. I feel like we need to do a movie marathon at some point just to catch up so that we've got shared analogies. But yeah, it's a fun movie. It's fine. It turns out fine in the end. But there are some humorous adventures that happen in the middle. Cloning maybe [laughs] isn't the most direct option to solve productivity problems. STEPH: [laughs] Yeah, I think I've got Labyrinth, Hackers, and Multiplicity now on the watch list. And I appreciate the fact that you know that I'm not likely to watch them, although out of the three, Hackers will probably happen. CHRIS: All right, what if I were to get a bunch of Pop-Tarts, non-frosted? STEPH: Ooh. CHRIS: Does that change -- STEPH: Wait, are you going to send them to me? Because if you just have them, that's no good. [laughter] CHRIS: Eat Pop-Tarts on a video call and be like, "Look at this movie. It's great." [laughter] STEPH: All right, bribery definitely works for me. [laughs] CHRIS: Okay, so got it, noted. And based on the nature of the conversation that we have devolved into here, I think we've probably reached a good point. What do you think? Should we wrap up? STEPH: Let's wrap up. CHRIS: The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at [email protected] via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. All: Byeeeeeeeeeee!!!!! Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.Sponsored By:Scout: Scout APM is leading-edge application performance monitoring designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise-platform feature bloat. With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve performance abnormalities -- like N+1 queries, slow database queries, memory bloat, and more. Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them. Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform. See for yourself why developers worldwide call Scout their best friend and try our error monitoring and APM free for 14-days, no credit card needed! And as an added bonus for Bikeshed listeners: Scout will donate $5 to the open-source project of your choice when you deploy. Learn more at scoutapm.com/bikeshed.Support The Bike Shed