While improving a build script by parallelising actions, I realised that Ruby’s puts
is not atomic.
Looks like puts
is calling the underlying write
function twice - Once to actually print the variable given to it, and once again to print the newline character. This leads to a race condition in puts
, as observed above.
I confirmed this by taking a look at the source code for puts
in Rubinius and MRI.
Annotated source code for puts in MRI, Rubinius
There is an open issue to fix this in MRI to fix this by using writev
instead of write
— https://bugs.ruby-lang.org/issues/9420
I worked around this by creating a safe_puts
function in our code, it looked like this:
By supplying ‘\n’ explicitly at the end, the whole string gets printed at once
This seems to be a problem with Python too, according to this StackOverflow post.