Compile Crystal Lang with SO_REUSEPORT

Crystal lang is a fast language that generate LLVM IR. We will compile it with SO_REUSEPORT socket option. On Linux, this socket option allows multiple sockets on the same host to bind to the same port. This is available on Linux > 3.9 .

Compile Crystal

First, you need to compile Crystal. You can follow this tutorial to compile it from sources. Once done, test the fresh Crystal compiler and go to the next step.

Test without SO_REUSEPORT

Create a file spawn.cr and write this in it :

require "http/server"
spawn do
  server = HTTP::Server.new(8080) do |context|
    context.response.content_type = "text/plain"
    context.response.print "Hello world, got #{context.request.path}!"
  end
  puts "Listening on http://127.0.0.1:8080"
  server.listen
end

spawn do
  server = HTTP::Server.new(8080) do |context|
    context.response.content_type = "text/plain"
    context.response.print "Hello world, got #{context.request.path}!"
  end
  puts "Listening on http://127.0.0.1:8080"
  server.listen
end

sleep

Launch this with Crystal, you should get this error :

Unhandled exception in spawn:
Error binding TCP server at 127.0.0.1:8080: Address already in use (Errno)

Let's add SO_REUSEPORT to spawn multiple HTTP server

Add SO_REUSEPORT

Go to the Crystal sources directory.

Open

src/socket/tcp_server.cr

and add

self.reuse_port = true

under

self.reuse_address = true

Next, depending on your system, go the target lib_c folder. For an Intel x86_64 with debian, it's :

lib_c/x86_64-linux-gnu

Then, open the file

c/sys/socket.cr

and add the SO_REUSEPORT value according to your system under SO_REUSEADDR (15 for Linux). You can use this command to get the correct value :

grep -r SO_REUSEPORT /usr/include/

And add it :

SO_REUSEPORT = 15

Finally , open the file src/socket.cr and add reuse_port def under reuse_address :

def reuse_port?
  getsockopt_bool LibC::SO_REUSEPORT
end

def reuse_port=(val : Bool)
  setsockopt_bool LibC::SO_REUSEPORT, val
end

Compile and test

You can now recompiler Crystal :

cd /path/to/crystal
make

And test the spawn.cr program :

./crystal spawn.cr

If all is good, you shouldn't have an error.

Problem

If you get a problem to add SO_REUSEPORT to Crystal, don't hesitate to contact us via comments.