UNIXServer#listen fails with Errno::EADDRINUSE error under Windows 10 / WSL Ubuntu 18.04
When running the following script under Windows 10 / WSL Ubuntu 18.04, an Errno::EADDRINUSE error is thrown. Expected result is that the script would run and simply exit.
#!/usr/bin/env ruby # This script establishes a UNIX server socket. # # Expected result: Script should run and immediately exit. # # Actual result: Script fails with Errno::EADDRINUSE error. # # Environment: Windows 10 Pro, WSL, Ubuntu 18.04.2, ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux-gnu] # # To reproduce: Create a tmp folder, copy this script there, and execute. require 'socket' path = File.expand_path('listen.sock') backlog = 5 s = UNIXServer.new(path) if backlog s.listen backlog else s.listen end File.delete(path) if File.exists?(path)
The bug was discoverd as part of Puma (gem) issue #1521: https://github.com/puma/puma/issues/1521.
Updated by shyouhei (Shyouhei Urabe) over 2 years ago
This is very nuanced. I'm not sure who is in charge of the exception.
UNIXServer.new's return value socket is already listened inside of the method. Calling
listen again on a socket that is already listening, might or might not error depending on OS. That's why you see exceptions on WSL and not on Linux.
The problem I see is why at the beginning you want to listen again a socket returned from
UNIXServer.new. I guess you want to change (maybe increase) the backlog? Then there seems to be no way for
UNIXServer.new to change backlog than listening again. Is it possible for a WSL-hosted application to dynamically change the backlog per-socket? If not (== there is no way but to specify enough backlog at the birth), I guess this is a misfeature of UNIXServer.