7 Tips To Accelerate Your Code Reviews

One complaint I often hear from software developers is about how long it takes to merge Pull Requests (PR). When I dig deeper, I often find it is all about code reviews. Indeed, code reviews can be a bottleneck, as they require someone to shift the focus from their work to review the PR. The key to faster code reviews is making reviewing PRs as easy as possible. There are several ways to achieve this.

Send clean PRs

You shouldn’t expect to quickly merge a PR with red signals. If your code doesn’t compile, tests fail, or if there are linter warnings you might only hope that someone will notice and ask for a fix. Often this won’t happen. Instead, people will quietly ignore your PR thinking it was sent by mistake.

I wrote a post dedicated to this topic recently

Write a good commit message

The struggle to find someone to review a PR is often a common reason why code reviews take so long. Good commit messages can help with that. A good commit message helps potential reviewers quickly understand if they are the right person to review the change and gives them an idea of how much time and effort the review will need.

Consider these two PR titles as an example: “Fixing a bug” versus “Fixing memory leak caused by retain cycle in X”. Which one do you think will catch more attention? The second title is more likely to attract reviewers because of its specificity. It tells them what the problem is and where in just a few words.

If you would like to learn more, I wrote a detailed post on this very subject.

Ensure good test coverage

“Can you add tests?” might be the first, and the only comment you get on your PR if you haven’t provided sufficient test coverage. It’s easy to understand why people hesitate to review PRs without good test coverage. Adding tests often uncovers issues or gaps in the code. Fixing them might lead to significant changes, that will trigger a complete re-review. Good test coverage not only saves time for the reviewer, who won’t need to go through your changes twice but also for you, as it reduces the number of necessary revisions.

Keep your PRs small

Conducting a thorough review of a huge PR is time-consuming and requires significant effort. Not many team members can commit to such a task. However, most large PRs can be broken down into smaller, logically complete PRs. By doing this, you can distribute the effort to review your changes among more team members, shortening the time needed to merge them.

For a more in-depth discussion on this topic, check out my post.

Address comments quickly

Respond to comments on your PR promptly, to keep the reviewer engaged while the details are still fresh in their mind. Delaying your response can lead to deprioritizing your PR as the reviewer will have to spend time and effort to recall necessary context. Addressing comments doesn’t always mean you need to send a new revision. It is often about providing clarifications or confirming assumptions. However, if the reviewer identifies an issue that requires a fix, you should promptly update your PR.

Ask for reviews

If you did everything possible to make your PR easy to review but it is still not getting traction, you may need to ask for a review directly. If anyone on the team can review your change, consider asking in your team’s chat room. If you would like a specific person to review your PR, contact them individually. However, be cautious not to overdo this. On most teams reviewing code is an expectation, and pinging people for reviews immediately after publishing a PR can be very distracting. In our team, we have a 24-hour rule for non-urgent PRs: we only ask for a review if a PR hasn’t been picked up within a day.

Review your team members’ PRs

If you don’t review your team members’ PRs, don’t expect them to prioritize yours. PRs that are constantly at the end of the queue will inevitably take longer to be reviewed, approved, and merged. That’s why it is important to dedicate a few minutes each day to code reviews. My rule is to review at least as many PRs as I publish. It works wonders – most of the time I can merge my PRs on the same day I submit them. Moreover, if my PRs aren’t getting enough attention, I don’t feel uncomfortable asking to review them.
Here is a post about other benefits of reviewing code.

And when you get your PR reviewed, remember to promptly merge it

What are your tips to speed up code reviews? I’d love to hear them!

 Accelerate your software engineering career by tracking your work

Your manager doesn’t know what you’re doing. They do know about things you should be doing they care about but you’re doing much more than that. You’re probably doing much more than even you think you’re doing. So, if even you don’t know what you’re doing why would you expect your manager to know this?

To know what you’re doing you need to track your work. The reason to do this is to be able to easily answer the following questions:

  • What am I doing? – helps confirm you’re working on the right things
  • What am I not doing? – helps ensure you’re not dropping the ball on important work
  • What I’ve accomplished this year/half/quarter? – makes all career, performance review and promotion discussions much easier

There are many ways to track work. You’ll need to find what works for you. I do it in a very simple way. Each year I create a Google doc for tracking my work for the given year. It has two sections:

  • What I’ve completed
  • A weekly list of tasks or projects I need to work on

Each Monday morning I spend 10-15 minutes to update this doc. I go over last week’s work items and move completed ones to the ‘completed’ section. I strikethrough work items that are no longer needed or I decided not to do. I copy the remaining ones as this week’s tasks. Finally, if there is any new work, I add it.

I attach artifacts to most items in the ‘completed’ section. They are a tool I or my manager can use to showcase my work and support my career related discussions. Here are examples of what I include:

  • Links to design docs, posts, roll out plans, etc.
  • References to diffs where I influenced the design or prevented serious issues
  • Other teams’ projects I helped unblock
  • Details about why something I did was hard

There is no one correct answer as to what granularity to track the completed items at. I found including smaller work items is worthwhile. Some of them are too small to matter by themselves but they add up. The secret is to group them in coherent themes. For instance, adding a couple tests will not get you to the next level but if you have done this multiple times you might have significantly increased the test coverage for your team or product which could be an additional argument to support your promotion.

Starting to track my work was one of the best things I’ve done for my career. It takes just a few minutes per week but gives me the clarity I need and saves me a ton of time during performance reviews. If you’re not tracking your work, I strongly encourage you to start.

Accelerate your software engineering career by writing clean diffs

As a software engineer writing diffs (also called PRs – Pull Requests, or CRs – Code Reviews) is your bread and butter. You want to code your changes, have them reviewed, merge them, and start the process again. Repeating these cycles effectively is essential for delivering new features and building products quickly. There are not many things that can slow this process down like low-quality diffs. Some signs of a low-quality diffs are:

  • Compilation errors
  • Tests failures
  • Lint warnings

Low quality diffs leave both the author and the reviewer(s) frustrated. The author is frustrated because there is a lot of back and forth and they fell like they will never be able to merge their changes. The reviewers are frustrated because they feel their time is being wasted on diffs that are clearly not ready for review.

Sending a low-quality diff happens occasionally to everyone (e.g., this new file you forgot to include in your diff or that test you didn’t run due to a typo). However, when done repeatedly, it will have a detrimental effect on your career because your team members will simply try to avoid reviewing your code. This will prevent you from iterating quickly and will make it harder for you to adhere to schedules.

While spending a few minutes to double check your diff is in good shape may seem like a waste of time – especially if timelines are tight, it is an investment that in a long run will save you even more time. And once you build this habit it will become your second nature.

Cloud Enabled Commodore 64: Part V – Do It Yourself

By now many people saw the demo of the Cloud Enabled Commodore 64 project, read posts discussing implementation and the retrospective and some commented that they would like to try it out themselves. This post describes how to do that.

We will start from listing required hardware and then will move to the required software.

Hardware

There are two hardware options to try the project out – you can either use an emulator or use a real Commodore 64. The emulator route is a bit easier as it does not require a working Commodore 64 and additional peripherals. You will still need a Node MCU board like this:

Node MCU Board
Node MCU board

which you can get on ebay for below $5. If you decide to try it out on a real Commodore 64 you will need a C64 WiFi modem. Make sure it is using the NodeMCU module and that the module is accessible. This is how mine looks like:

C-64 WiFi Modem

For the real C-64, you will also need to be able to load the cross-compiled program to your C-64. There are a few possibilities here – I used an SD2IEC floppy drive emulator, and it worked great for my needs.

Software

Before moving to software I would like to start with a disclaimer. I did all the work on MacOS. I will try my best to provide instructions for Windows and Linux, but they might be lacking.

Git

You will need git to clone the project repo. It is very likely that you already have git installed on your machine but if not follow instructions from here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

make

You will need make to build the project and the cc65 toolchain. On MacOS you can get it by installing Apple developer tools. On Linux, you likely already have it. On Windows you would need to install either Cygwin or use WSL (Windows Subsystem for Linux).

cc65

cc65 link is a “cross development package for 6502 systems”. To get it, follow instructions listed on https://cc65.github.io/getting-started.html. Please make sure the tools can be resolved (e.g. run sudo make avail or add them to the path). You can test your installation by running cc65 from command line and verifying that it printed cc65: No input files.

Arduino IDE

We will need to update the NodeMCU board for which we will use the Arduino IDE. It can be downloaded from https://www.arduino.cc/en/software.

VICE emulator

If you are going the emulator route (which I recommend even if you eventually want to use the real C-64) you will need the VICE emulator which you can download from: https://vice-emu.sourceforge.io/index.html#download

Dotnet

You will also need the .NET SDK. It will be used to run the server locally. This makes it easier to test and troubleshoot, if necessary. It is will also be needed if you decide to publish the server to Azure. You can get the .NET SDK from https://dotnet.microsoft.com/en-us/download

Node and npm
The server contains a web client which depends on a few node packages (most notably the @microsoft/signalr package) so you will need npm to install these packages.

Preparing and running the application

With all pre-requisites installed we can get down to business and try to start the application. Here are the steps:

  1. Clone the project repo
    Run git clone https://github.com/moozzyk/SignalR-C64

  2. Start the TestServer
    The test server is the chat server our chat application will be talking to. Note, that the server registers an https endpoint which on will use a developer TLS certificate when running locally. This may result in showing a warning or asking to register the certificate (which you can do by executing dotnet dev-certs https --trust). If you don’t want to see the warning you can remove the https url from this line and just use HTTP. This will work fine for local runs but is not recommended (perhaps not event possible) when running the server on Azure. You will also want to make sure that the server is accessible from outside of your machine (i.e. make sure that other devices on your network can access the application).
    To start the TestServer you need to go (cd) to the TestServer directory and run:
    npm install
    dotnet run

  3. Verify that the test server works
    Connect to the server using a browser. Ideally you would want to connect using an external IP or the name of your machine (i.e. avoid 127.0.0.1 or localhost) or use another device connected to the same network. Once connected try to send a message – if you receive the message you typed, the server is set up correctly. (Note that if you try connecting to the server with HTTPS you may see warnings caused by using the local (dev) TLS certificate.)


  1. Backup the C64 WiFi Modem firmware (optional)
    If you are using the C64 WiFi Modem for this project you may want to back the currently installed firmware up as the next step will overwrite the firmware effectively removing the original functionality provided with the modem (i.e. connect to BBSes). One way to do this is to use the esptool to download the existing firmware and then upload it later to bring back the original functionality. You can install the esptool by running:
    pip install esptool

    To download the firmware connect the modem to your computer and run (remember to update the port to point to your serial device):
    esptool.py --baud 115200 --port /dev/cu.usbserial-1420 read_flash 0x0 0x400000 ~/tmp/C64WiFi-backup-4M.bin

    To upload the firmware back to the board run:
    esptool.py --baud 115200 --port /dev/cu.usbserial-1420 write_flash 0x00000 ~/tmp/C64WiFi-backup-4M.bin

    You can use screen (or Putty on Windows) to test that the firmware has been uploaded correctly. First run:
    screen screen /dev/cu.usbserial-1420 300
    and then type AT? You should see something like this:
    AT?
         cOMMODORE4EVER V2.3 wIFI mODEM
    ...

  1. Upload the firmware to the NodeMCU board
    – Start Arduino IDE and open the EspWs.ino sketch and set the default credentials on this line. (For simplicity, the code running on C-64 does not allow setting credentials – it assumes that the credentials are properly configured and will just initiate WiFi connection.)
    – If you are planing to use real C-64 set the transfer speed to 600 bauds here. Leave 1200 if using the emulator as Vice-64 does not seem to support 600 bauds.
    – Connect your NodeMCU board (or the C64 WiFi Modem) to your computer.
    – Make sure to select the NodeMCU 1.0 (ESP-12E Module) board (If you can’t see this board you may need to add it first using the Board Manager Tools -> Board Manager, search for “esp8266” and then install)

– Select the device

– Upload the firmware to the board

  1. Verify firmware was deployed successfully
    Go to the EspWs directory and run the following command (make sure to provide correct values for the server, device and transfer rate):
    python3 prototype.py 192.168.86.250:5000 /dev/cu.usbserial-1420 1200

    If the firmware has been uploaded correctly you should see the following output:
    b'\x03\x00'
    OK
    b'\x05\x1dws://192.168.86.250:5000/chat'
    WS
    b'Connected'
    b'\x06*{"protocol": "messagepack", "version": 1}\x1e'
    OK
    DATA
    b'{}\x1e'
    DATA
    b'\x02\x91\x06'
    DATA
    b'\x02\x91\x06'

    Note there will be some delay before you will be able to see most of the output as it takes about 10 seconds for the board to connect to WiFi. Another, important thing is that if you stop the script and want to try again, you’ll need to reset the board (press the RST button on the NodeMCU module and wait a few seconds before trying again).
  1. Configure Vice
    This step is only needed if you want to run the app using the Vice emulator.
    Open Vice and go to Settings -> Peripheral devices -> RS232
    Make sure to “Enable Userport RS232 Emulation” and select the device that you want to use. In the RS232 devices you need to provide the device filename and the transfer speed. For the emulator you want to 1200 bauds. Here is how this is configured in my case:

  1. Configure chat server URL
    You will need to set the correct URL to be able to connect to your chat server by modifying the value here.
  2. Build and run
    The application should now be ready to run. Go to the App directory where you will be able to build the application with make. The makefile supports a few targets. The default target (i.e. running make without any arguments) will compile the app to a.prg file. make clean will delete temporary files. make d64 creates a .d64 (disk image) file you can either to attach to the emulator or use to run on a real C-64 (e.g. using SD2IEC). The fastest way to build and run the app on the emulator is to invoke the following command:
    make clean && make && x64sc --autoload signalrdemo.prg
    It will clean temporary files, create a prg file, start the emulator and automatically load the prg. Then you can just type run in the emulator to run the app.
  3. Deploy the server to Azure (or a cloud provider of your choice)
    If the application is working correctly in the local environment you can deploy the server to a cloud provider. You will need to update the URL accordingly and compile with the new settings (steps 8 and 9).

This post concludes the Cloud Enabled Commodore-64 mini series. I hope this project brought back some good memories for you as it did for me.

Cloud enabled Commodore 64: Part II – Development Environment

After devising a high-level design for my idea, I needed to take care of more mundane things, starting with setting up the development environment. First, I had to find out if using a Commodore 64 emulator for testing and development was an option. I wanted to rely on the emulator as much as possible to speed up the development time. The main two concerns I had were:

  • would the emulator even support external devices?
  • if, the above was true and my idea worked on the emulator, would it work on real hardware

Vice-64 was the most advanced and mature Commodore 64 emulator I knew of. I used it previously in some of my projects (e.g. Vintage Studio) and to occasionally play some of my favorite games but never with any external hardware. Looking at Settings gave me hope – I found that there were at least controls allowing to configure serial communication. After playing with the settings for a bit I was able to make Nova Term connect to a BBS via the C64-WIFI modem connected to my laptop via USB. This answered my first concern and assured that I would be able to code and test the entire solution on my laptop with maybe some additional debugging on the real C-64 at the very end. Another benefit of using Vice was access to the built-in debugging tools. They allow setting breakpoints and stepping through the code and the support for labels makes debugging much easier.

Next, I had to decide on which 6502 assembler to use. I found ca65 (a part of cc65 suite https://github.com/cc65) to be the best option. It has a lot of great features, has been around for a long time and has a lot of documentation as well as source code available on github. I was almost sure that VS Code was the safest bet to serve as my 6502 assembly editor as it has a ton of extensions. The main thing I was looking for was syntax highlighting and I quickly found the CA65 extension which did exactly what I was after. The extension also provides build tasks but I have not used them as I decided to go with make. Overall, the combination of Vice, VS Code, ca65 and make ended up making quite a productive environment where I could quickly build, launch and debug my project.

To handle the NodeMCU part I decided to stick to Arduino Studio. I knew that VSCode had an Arduino extension (heck, I even created one long time ago before Microsoft decided to occupy this space) but it tried to reformat my code the way I did not like and I didn’t want to spend the time on adjusting it to my liking. I also think I had some issues with uploading my sketch to the board while everything worked fine from Arduino Studio.

At the beginning I was able to test my NodeMCU code using screen. It was possible because the protocol I implemented was text based. Later, I switched to a fully binary protocol and using any general purpose solution was not an option, so I created a simple terminal in Python that was able to interpret and translate my commands and the responses from the module.

I used a standalone NodeMCU module for most development but occasionally tested my code against the C-64 WiFi’s NodeMCU module. Surprisingly, I found some slight differences between how the boards behaved immediately after booting and had to implement a simple workaround which ignored first few bytes received from the module.

For the SignalR part I just took the chat server I created for my other project. I ran it locally during the implementation and then deployed to Microsoft Azure for final testing and demo.

The final missing piece of my environment was actual hardware. I had a Commodore 64 that I know was working the last time I turned it on because it was when I fixed it. I also had a 1084S-D2 monitor which stopped working when I was testing my C-64. Fortunately, it turned out to be only the power switch. Replacing the switch brought the monitor back to life. I decided to go fully retro and had to acquire a 1541 disk drive – luckily I found a working one in decent condition on craigslist. I received a bunch of disks used with Commodore 64 from a colleague many years ago. Despite all these years in a closet almost all of them worked just fine. The only thing remaining was to transfer the compiled program to a disk which I did using a SD2IEC module.

Looking back I am really amazed how many technologies – both hardware and software – were involved in putting my solution together. Four programming languages, vintage and modern hardware, embedded programing, Cloud technologies and a variety of, mostly open source, tools. All this made this project a lot of fun. Next time we will take a closer look at the implementation.