How Ruby 2.6 allowed me to do another open source contribution

TLDR;¬†Ruby 2.6.0 added support for setting write timeout within Net::HTTP class. To make it available to users of httparty gem I had opened a pull request which was merged into master branch. As a result, the gem supports setting open, read and write timeouts ūüôā

Every minor Ruby release brings some new features to the language. Few interesting articles describing Ruby 2.6.0 changelog have already been published, so describing them is not the goal of this article. However, one of them allowed me to do another open source contribution, and in my opinion, that is something worth sharing. Maybe it will inspire you to do the same.

Introduction

There are multiple HTTP clients available to Ruby developers. Some of them wrap Ruby built-in classed to provide more friendly API (like HTTParty wrapping Net::HTTP). Some are written in pure Ruby (like Excon) and others take usage of libcurl C library (like typhoeus). As always, each of them has its own pros and cons. I am not going to discuss them, though.

I have used HTTParty several times, but also tried faraday + typhoeus combo when I wanted to achieve parallelism by making multiple requests at once.

The change

One of the Ruby 2.6.0 changes that made me curious in the context of HTTP communication were #write_timeout & #write_timeout= methods added to the Net::HTTP class.  To give you some more background, the class had supported the below (among some others) timeouts, until 2.6.0 was released:

  1. open_timeout Number of seconds to wait for the connection to open. Any number may be used, including Floats for fractional seconds. If the HTTP object cannot open a connection in this many seconds, it raises a Net::OpenTimeout exception. The default value is 60 seconds.
  2. read_timeout Number of seconds to wait for one block to be read (via one read(2) call). Any number may be used, including Floats for fractional seconds. If the HTTP object cannot read data in this many seconds, it raises a Net::ReadTimeout exception. The default value is 60 seconds.

Simply speaking, the first one determines how long a client (e.g. Ruby app) should wait for a TCP connection to be opened. The second one regulates how long a client should wait for receiving one block of data1 from a server (e.g. another Ruby app).

What about the write_timeout? According to the documentation:

Number of seconds to wait for one block to be written (via one write(2) call). Any number may be used, including Floats for fractional seconds. If the HTTP object cannot write data in this many seconds, it raises a Net::WriteTimeout exception. The default value is 60 seconds. Net::WriteTimeout is not raised on Windows.

It determines how much time a client can spend on writing one block of data 2. The value is important especially when dealing with large amount of data like uploading video files.

Did you know that Ruby 2.6.0 had involved 6437 files changed, 231471 insertions(+), 98498 deletions(-) since Ruby 2.5.0?

How did I contribute?

As I mentioned earlier, I am quite familiar with HTTParty¬†gem. I had already contributed to its source code.¬†I knew that it supported setting the open and read timeouts. The new one was missing, though. I checked if somebody hadn’t already opened a pull request providing support for it to avoid duplicated work. I didn’t find such a PR, so I started working on it.

I spent a few hours over the last few days to write required code. I had to remember that the code should work only with Ruby 2.6.0 or higher.¬†That’s the beauty of maintaining open source libraries ūüôā After the code had been ready, I prepared a descriptive commit which was a base for a description of a pull request I opened.

Providing descriptive commit messages and opening pull requests with well-suited description is even more important in open source projects than private ones. The reasoning behind each change should be easy-to-understand by other developers willing to use the gem within their projects.

It didn’t take longer than two hours to receive feedback from both the author and a collaborator of the gem. Thanks to them, I pushed some additional commits making the gems’ code even better. I killed two birds with one stone. The pull request was merged on 20th of March 2019. I published this article on the same day.

Summary

The more code I write the more I enjoy open source contribution. It doesn’t need to be an enormous change in Ruby source code written in C, making the language ten times faster ūüôā There are a lot¬†of gems you use on a¬†daily basis that you can contribute to. You never know when open-source find you ūüôā

Footnotes

  1. As long as a server does not return a response in chunks, it basically means how long the client waits for a response, after establishing a connection, before raising the exception.
  2. A quite important difference when sending data in chunks.
 

Igor Springer

I build web apps. From time to time I put my thoughts on paper. I hope that some of them will be valuable for you. To teach is to learn twice.