diff --git a/README.md b/README.md index 4c540e8c..76aa66e2 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,13 @@ The inline version also works:
Has the image as it's background
``` +## Puma plugin +We provide a Puma plugin if you want to run the Tailwind watcher together with Puma and have Puma monitor and manage it. You just need to add +```ruby +plugin :tailwindcss +``` +to your `puma.rb` configuration. + ## License Tailwind for Rails is released under the [MIT License](https://opensource.org/licenses/MIT). diff --git a/lib/puma/plugin/tailwindcss.rb b/lib/puma/plugin/tailwindcss.rb new file mode 100644 index 00000000..cb6b5bce --- /dev/null +++ b/lib/puma/plugin/tailwindcss.rb @@ -0,0 +1,65 @@ +require "puma/plugin" + +Puma::Plugin.create do + attr_reader :puma_pid, :tailwind_pid, :log_writer + + def start(launcher) + return unless Rails.env.development? + + @log_writer = launcher.log_writer + @puma_pid = $$ + @tailwind_pid = fork do + Thread.new { monitor_puma } + system(*Tailwindcss::Commands.watch_command) + end + + launcher.events.on_stopped { stop_solid_queue } + + in_background do + monitor_tailwind + end + end + + private + def stop_solid_queue + Process.waitpid(tailwind_pid, Process::WNOHANG) + log "Stopping tailwind..." + Process.kill(:INT, tailwind_pid) if tailwind_pid + Process.wait(tailwind_pid) + rescue Errno::ECHILD, Errno::ESRCH + end + + def monitor_puma + monitor(:puma_dead?, "Detected Puma has gone away, stopping tailwind...") + end + + def monitor_tailwind + monitor(:tailwind_dead?, "Detected tailwind has gone away, stopping Puma...") + end + + def monitor(process_dead, message) + loop do + if send(process_dead) + log message + Process.kill(:INT, $$) + break + end + sleep 2 + end + end + + def tailwind_dead? + Process.waitpid(tailwind_pid, Process::WNOHANG) + false + rescue Errno::ECHILD, Errno::ESRCH + true + end + + def puma_dead? + Process.ppid != puma_pid + end + + def log(...) + log_writer.log(...) + end +end