Currently there know there are two possible paths.
(1) Add some Fiber.yield
in cpu intensive loops. Essentially making everything interruptible. But will penalize a bit some parts of your system.
(2) Change how HTTP::Server#listen
delegates to a fiber how a request is processed. With @waj we checked on different alternatives to contemplate this scenario but for non cpu-intensive web servers the performance was a bit worse. The idea is to ensure the are one worker fiber per crystal worker that will accept
socket connections. Currently there is no way to ensure a set of fibers work on different crystal workers, but due to the current scheduler round robin logic, a loop is very likely to distribute fibers among workers. So monkey-patching HTTP::Server#listen
might help you test how this strategy can work on your scenario.
If you want to have more granular control you might need to play with Channels. Communicating some fibers that accepts connections with others that run the handlers might work. But for simple scenarios it will have, again, some penalties.