FSWatch + Kemal => Deadlock? Hung process?

I have been using minimal this hot reload websocket in Kemal which watches for changes to CSS/Javascript files and reloads the browser. It works well! Mostly.

Once in a while something goes awry and I get myself stuck in a loop of a hung kemal process, which won’t respond to any web requests, and won’t exit on SIGINT, and even if SIGINT does return me to my shell, it’s a zombie process and I have to go search and SIGQUIT or SIGKILL it before I can have my Kemal port back to try again.

Today I’m able to reproduce the issue and reduced it down to this:

require "kemal"
require "fswatch"

FSWatch.watch "." do |event|
  puts "got event for #{event.path}"
end

get "/" do |env|
  "Hello World!"
end

Kemal.run

Then:

  • Install Kemal and @bcardiff’s FSWatch
  • Run the file with crystal – shards run or crystal run or whatever.
  • With the server running, re-save the server file.
  • The Kemal server is now unresponsive.

I’m using watch -n 1 curl http://localhost:3000 in a background tab to trigger requests once per second, and I can observe that the kemal server responds to the request many times until an fsevent is received. At that time the server will receive connections but not respond with anything – the browser just hangs.

I’m not really sure if this is a bug with Kemal, FSWatch, Crystal, My Computer … or some unique collision of the four. I’m happy to continue debugging it, but I’m out of my depth. I don’t know how to inspect the running processes well enough to observe what threads are waiting on what, etc.

Am I crazy? Can anyone else reproduce this? If so, does anyone have any idea what the problem might be?

I tried on Mac and find FSWatch is causing that. One can easily reproduce that on M1 via running the sample provided in FSWatch README

I installed fswatch on M1 via homebrew brew install fswatch

require "fswatch"

FSWatch.watch "." do |event|
  pp! event
end

sleep 10 # keep main fiber busy to prevent exiting

Build and/or run the script (with or without mt_preview), make any change to the folder being watched to hang the process.

1 Like

Issue: BUG: Process hang on M1 · Issue #5 · bcardiff/crystal-fswatch · GitHub