Zach Peters

Tasks, lists, and

The content below is converted from an old website, it may not be rendered perfectly

created: 2022-05-21T14:27:26 (UTC -05:00) tags: #good-articles source: author:

Tasks, lists, and promises


Not everything at a big company involves writing code. Sometimes, you have to do a bunch of meta stuff in order to manage the projects. These are two stories of doing exactly that.

Not everything at a big company involves writing code. Sometimes, you have to do a bunch of meta stuff in order to manage the projects. These are two stories of doing exactly that.

Have you ever seen what happens when a team has a long list of “to-do” items and has no idea where to start? Have you had to sit there and witness the circular conversations of people trying to attach priority values like P0, P1, P2 to those items? Did they then still have no idea where to begin?

“AB-123 is a P0…”

“Oh yeah, definitely” “Yep” “Absolutely is”

“But we can’t do that because XX-996 isn’t done yet…”

“XX-996 is a P2 so it can’t be done before a P0…”

… sound familiar?

I went through something like this indirectly. There was a nearby team which was closely affiliated with what I was doing but wasn’t plugged into my management chain. They were stuck on this sort of thing, and their manager asked if I would join them in sorting out their priorities.

This was one of those situations where you had a bunch of people trying to improve reliability for a service. For whatever reason, they couldn’t crack this particular organizational nut. This is what ended up happening in the meeting room that day.

Since we had everyone in the same room at the same time (a luxury these days, I admit), I just asked if I could take a whack at the problem, grabbed a marker and headed for the board. I asked for someone to give me one of the things they wanted to see happen. It went up on the board with a short yet memorable title and had a circle drawn around it. I asked for another, and it too went on the board somewhere else.

This kept going until we had 10 or 15 items up there that people thought the team should be doing for one reason or another. Then I started from one end of the board, picked an item, and asked if it depended on any of the others. It turned out that this one did in fact have a dependency, so it was “blocked” by some other item on the board. I drew an arrow from the first one to the second.

This kept going until we had visited all of the “nodes” on the board, and we had something interesting to look at. There were definitely some nodes which were blocked by all kinds of other things, but there were also several which were blocked by nothing. This was completely independent of whatever P-this, P-that values people had been attaching to these tasks. I hinted that their priorities don’t mean anything if you can’t make progress, so take the ones which are possible to do right now, and go work on them. If you keep doing this, you will eventually get to your supposed P0 and it will happen.

Really, the situation unfolded like a giant Makefile to me. This is where you say, okay, to build my_project, I need to build httpclient.o and logging.o. To build httpclient.o, I need to have libcurl on the system. I don’t have libcurl on the system yet, so I can’t build httpclient yet. But I *can* build logging, since it doesn’t depend on anything. So you can either work on logging, or get libcurl going. Or, if you have two workers, do both at the same time. Hooray.

To me, the “priorities” were largely ornamental. It seemed like you might use them as a tie-breaker. For example, let’s say you had one chain of dependencies blocking a so-called P0 task (highest priority, supposedly), and another blocking a P3 (good luck). You might try to put more effort into getting the former done rather than the latter, and maybe start on that first. It’s a hinting system, not a mandate.

There’s another fun thing a few of us did at that same job around the same time. Several like-minded people had decided we needed a better way to ship the corporate-built system software which ran on every machine in the fleet - the “Widely Distributed Binaries”, if you will. Three of us decided to just go for it.

Since nobody had really done this before, we knew there was no way we’d ever get a “road map” laid out up front. We knew what success looked like, but we also knew that we’d have to adapt to the conditions encountered along the way. For that reason, we started off by shipping binaries by hand, then kept notes of what parts of the process were awful. Once we thought we had a handle on what it was and how it could be made better, we’d automate that step. Then we’d move one level up the stack and do it again. This continued until the thing pretty much ran itself… and we had a halfway-decent list of “stuff you need to have to ship WDBs sanely”.

I’ve talked about that before, but what I haven’t shared is how we dealt with the “oh, what about if we did this thing” ideas that came up along the way. We came up with a method of handling those, and I like to think it was quite humane and didn’t make any promises we couldn’t keep. Here’s how it worked.

Since there were three of us working on the project, and our unixnames (which were also our IRC nicknames) were three different initials (A, B, and R), we used that to our advantage. We’d hop on IRC and chat about things, and as we came up with ideas, we’d add another item from our own set. That is, my first idea was R1, then R2, then R3, while Mr. B’s ideas went B1, B2, B3, and Mr. A’s ideas were A1, A2, A3, and so on.

This let us all pitch ideas out there while giving them a unique identifier so they didn’t get lost, and without having to coordinate with each other in order to not collide while incrementing the counter. All of the ideas went onto our Wiki page, and that’s about as concrete as they got for a while. We were then all able to see what everyone else was thinking about, look for duplicated ideas, overlap, and generally look for things that would help (or hurt) other things.

None of these items were commitments. They were simply ideas. Also, just because you had the idea didn’t mean you had to do anything with it. The only reason we tagged them the way we did is so they could be uniquely identified, assigned in a non-blocking fashion, and so you’d know who to ask for clarification if the gist of it wasn’t clear from the wiki page and/or IRC chat logs.

“Hey B, on B5, where were you thinking about storing that thing?”

“Yeah I wanted that in svn.”

“Oh yeah right, that makes much more sense to me now, thanks!”

… you get the idea.

At some point, we started stitching them together, such that A1 might depend on A5, but then A5 depended on R2. After doing this for a while, we ended up with several different types of list items.

Some items didn’t block anything and weren’t blocked. You could pick one and go on hack on it at any time, but at the same time, you weren’t going to unblock anyone or anything else by doing it. It might make for a nice afternoon of work on a self-contained project.

There were items which were blocked by one or more other items. They tended to be rather large.

Then there were items which themselves blocked one or more items.

The ones which were blockers but which were not themselves blocked were the obvious places to start working on stuff if you were looking for something to do. This is because if you started on something that was blocked, you’d hit the blocker! Pretty obvious if you think about it, right?

By drawing this out as a bunch of chains (think labeled circles with arrows pointing at other circles) courtesy of the Wiki’s built-in “dot”/graphviz renderer, we could just look at the ends of them to figure out what was possible to crank on *right now*. We could also see which items would have the most impact in terms of unblocking future work.

At the point that someone decided they were going to do something, we’d create a task for it. A “task” was the unit of currency in this company’s bug tracking software. That meant it got a number and a nice little shortcut URL, and so the wiki would be updated to link to it. Anyone who was curious could follow that link into the tasks tool to see what was up.

I will note that the graph had been arranged to show things with different colors and rendering styles based on whether they were blocked or not, and whether they had been completed or not.

From time to time, we’d go through and prune back the graph in order to remove the nodes which had been completed and were just taking up space. Watching things get struck through and then disappear from the list and the graph felt great.

One important bit here: some of those items never left the list. For all I know, they might still be there on some corporate wiki page buried inside the belly of that company. Those items were just ideas that someone had one day, but as the service went into production, it turned out we didn’t need it that badly, or had the wrong idea altogether. Then, that was the end of that. Some of them were actually struck through on the list without being completed along with a note explaining why, just so we didn’t have to keep thinking about them.

This system of doing things made me happy because it didn’t leave us holding a bag full of promises. Just talking about something didn’t commit us to spending time on it later. By disconnecting the talk from the commitment, this gave us the freedom to talk about all kinds of stuff without worry of somehow ending up with tons of stupid and useless items down the road. We did still make commitments, of course - that’s what the tasks were for.

How do you keep from having a soul-crushing load of tasks/tickets/whatever that will never go away? You don’t create one until you are damn sure that it needs to exist.

Caveat: if you have so many things going on that you run the risk of “losing” something due to it only being a line item on a wiki page somewhere, you probably don’t want to try this on your project. (You probably also want to run away from that project, since there’s far too much going on there.)