Planning projects

Once you have a rough idea of what it is you are going to build and you have documented it at some level, you will need to starting working on the project: planning work and moving forward.

Earlier we mentioned Agile. There are lots of definitions of Agile and lots of similar philosophies (including Scrum and extreme programming), but the rough idea is a period of iteration, where after each period, the team regroups, adjusts priorities and plans based on feedback, then gets back to work. As with everything in tech, there are zealots out there who will tell you the right and wrong ways to do Agile. Just remember, if it works for you and your team then ignore the zealots because they cannot tell you what to do. For example, some teams use pair programming exclusively, while other teams cannot because their team is not all in the same time zone or there are people who have to work different schedules because of family obligations. The point isn't to ignore people but rather to evaluate what they are saying and try to figure out if that'll work for your team.

Lots of modern teams use Agile as a way to keep the team organized and to make sure a single team member doesn't get too lost in the weeds. By checking in at a regular interval (once a day, week, or fortnight), you can keep an eye on progress and help coworkers to understand what you're working on and what's blocking you.

When trying to decide on what to work on and how to approach a large project, it is best to break the project into small pieces. Instead of thinking about how you can implement everything, think about which features you want to exist. Then pick a feature and make a list of functions or pieces that you will need to implement to make the feature work.

Then slowly work down the list. By breaking things up, you provide yourself with a to-do list, as well as the ability to see progress in your project as you complete tasks. There are few things more demoralizing than looking at a project and feeling like it's too big for you to be able to complete. By breaking things up, you prove to yourself that you can succeed and that you are making progress.

Some people like following test-driven development (TDD), which takes the idea one step further. You break the project into a series of tests and then work on slowly getting the tests to pass. As each test passes, you get a green check mark showing your improvements. If you graph a history of passing tests, you will be able to visualize your progress. If you want to learn more about TDD, there is a lot of good documentation about the topic. I personally love Kent Beck's Test-Driven Development: By Example. Just be careful, as there are many TDD zealots out there. Remember that these are all tools for you to use, and each situation requires deciding what tool is best for the job.

I prefer to-do lists to tests, just because that's how my brain works. That is not to say that I do not test: I just do not use them as the framework for organizing my future work. Finding a way to break apart projects that works for you is the key because everyone's brain works differently. Along with this, don't be afraid to refactor or admit failure. If you finish a piece of the project and realize that you will have to change it because of things that the next part needs, that is not a failure of planning: instead it is just an opportunity to improve old code. Your ability to plan grows as you learn how best to break apart projects.

Example

To provide an example, I'm going to show how I would break up tasks for building a board game. This isn't a traditional SRE piece of software, but it is something that is transitioning from physical to digital. Professor David Janzen, from California Polytechnic State University, once called it atoms to bits. These sorts of projects often help people to visualize how to break things apart.

We are going to build a Tak server. Tak is a board game that is like chess or checkers. It has a notation for tracking play, which shows how the board's state changes over time. Each line in the notation is a move played by a player. The main difference from chess or checkers is that you start with an empty board and can place a piece each turn or move an existing piece. Pieces are flat colored squares and the goal is to build a road of your colored pieces from one side of the five-by-five board to the other. You can place pieces on top of each other and you can unstack stacks of pieces.

If we think about a normal board game, we can probably come up with the most basic of features. We need to store the current board state. We need to modify the state as someone plays the game. Finally, we will need to provide an external API, so that clients can interact with the server.

Initial features are as follows:

  • Game state storage
  • Game play
  • Web API

For the first feature, we are going to want to create a game state data structure. We are going to need something that returns the history of the state as well. We also are going to need some marker of whose turn it is, and we need to somehow decide if the game is over.

Next, for gameplay, we will need methods to change the state. We will need logic to validate moves, so that clients cannot modify the state illegally, where an illegal state modification is equivalent to an illegal board game move (such as robbing the bank in Monopoly, moving another person's pieces in checkers, or moving a pawn four spaces in chess).

These two features will cover the basics of gameplay. They will be easy enough to test because we can list most of the valid inputs and thankfully there are a lot of game notations on Reddit that we can download and test with, although we need to write a notation parser to be able to do that.

Our rough to-do list is as follows:

  • Game storage
    • Game state storage
    • Board
    • Pieces
    • Players
    • Game state history
    • Current state
    • Moves made
  • Gameplay
    • Game move input
    • Game move validation
    • Game completion checking
    • Game notation parsing
  • Tests using real game notations

Once that is all done, we can move on to the next feature: a REST API using JSON for playing. This will add the idea of user and game identifiers because clients will have to say which player is making a move in which game. We will need to make sure that the players don't change during a game and provide reasonable errors to users if they make illegal moves. When a game is finished, we will want to return the game history, so that people can keep it for their records.

The following is a possible to-do list for the JSON API. Notice that we include routes that we want to define:

  • JSON API
    • GET /game/$id
    • Returns a game of ID $id with the most recent state
    • GET /game/$id/$move
    • Returns a game of ID $id after move $move
    • POST /game/$id/move
    • Client sends a move for a game of $id. The request must include a valid player ID and a valid move
    • POST /game/new
    • Creates a new game and returns a game ID. This must provide player IDs

    After we have this done, maybe we will add some sort of authentication as the next feature. Then a follow-up feature could be some matchmaking to pair two random people together. Other features that I would want to break down include the following:

  • Scoring
  • Authentication
  • Player ranking
  • Sharing of game histories between friends
  • A gallery of well-played games
  • A simple AI to play against if no one else is around

Building a board game at a high level could seem scary, but by breaking down the project, we can come up with a reasonable plan. It might not work fully, and we may find pieces that we need to add or break up into smaller parts, but at least we have a plan to move forward.

Retrospectives and standups

Two aspects that we haven't talked about from Agile, that I really enjoy, are retrospectives and standups. A standup is a daily meeting for everyone on your team to mention what they worked on yesterday, what they are doing today, and what they are blocked on. This is a great way to keep people updated on a project and informed of any changes. Even if everyone is working on different stuff, it allows people to stay in the loop. It can be held over chat, email, or in person, whatever works for your team.

Retrospectives are a way to continue looking back on the plans from the previous week or month or fortnight or whatever. They are regular meetings where people share what has gone well, gone poorly, and gone just okay. The most successful of these meetings I have been part of were held at four in the afternoon on a Friday, with a whiteboard with three headings: Yay! Meh! Blargh! Each team member would go and put post-it notes in the columns to match their moods about things. It was a good way to rant and to express feelings about projects that were ongoing.

Another tool for retrospectives is the 4Ls. Like the above idea, you create a board with four categories: Liked, Learned, Lacked, and Longed For. Then members of the team put post-it notes in each category. Afterwards, the post-it notes are grouped by topic and discussed. Similar is the Glad Mad Sad framework for retrospectives. Users put post-it notes in each of the three categories. The interesting thing that this framework proposes is giving each team member a number of points that they can vote with on post-it notes. This means that they can show support for a post-it, saying that they agree with the sentiment expressed.

These are just tools, so you do not have to use them and there are many more frameworks you can look at, but they can be useful in organizing thoughts and removing problems when working. It should be mentioned that standups and retrospectives are not only important for looking at work but also for evaluating the mood of the team and possible issues inside the team's dynamic.

Allocation

We should also talk about allocating this work. There is a danger in software, which outside of engineering is rare and due to physical limitations does not exist in many other fields of engineering. This danger is the fact that a single engineer can, if they want to, develop the entire system by themselves. A single developer has all of the tools to complete the same amount of work as a larger team, just on a different timescale.

This is dangerous for a variety of reasons. The first is that humans are fallible, as we have been saying time and time again through this book. So, because humans make mistakes, there is a higher chance of introducing bugs or creating errors in code when a person works alone. The second danger is if a person leaves the organization. When someone leaves, often they take all of their knowledge with them. If a software project is poorly documented, as most projects owned by a single person are, then when a bug appears in the software that the person who left maintained, someone on your team will have to dig deep to figure out how it worked. This will take far more time than if you had two people working on the software.

Note

Having only one person know something is often called having a bus factor of one. Bus factor describes how many employees can be hit by a bus before the project falls apart.

One solution to this is to have one person dedicated to code reviewing a project that a single person is working on. This way, every line of code that is committed to a project is reviewed by the same person, and two people can discuss the project and bounce ideas off each other. Another solution is to just have multiple people working on the project. Divide the work up between the developers, then have them collaborate and code review each other's work. However, once the work is allocated, make sure not to overcommit an individual.

Try to figure out how much work a person can handle per time period, and make sure that they feel like they can complete the amount of work assigned. Talk to your team members and understand their feelings around their workload. The goal is not to burn people out, the chance of which is very high because SREs are often involved in some sort of on-call rotation. As mentioned in earlier chapters, on-call rotations can cause people to be overwhelmed and tired. Switching from a reactionary role like that to long-term creative work, such as designing and writing code, can be jarring and exacerbate those feelings.

On top of those feelings, people may feel overcommitted. You run into the possibility that people will start feeling ineffective in their job because they constantly will not be able to finish the work assigned. This ineffectual feeling, plus feelings of physical and emotional exhaustion, are signs of chronic stress and burnout, which can have a negative impact on an employee's wellbeing and may lead them to quit.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset