Skip to content

Commit

Permalink
Ensure ServerProcess is started only once
Browse files Browse the repository at this point in the history
  • Loading branch information
bruno- committed Apr 30, 2024
1 parent 7265220 commit b4879aa
Showing 1 changed file with 62 additions and 12 deletions.
74 changes: 62 additions & 12 deletions lib/tailwindcss/server_process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@ def self.start
new.start
end

def start
def initialize
@server = Server.new(self)
@pid = fork do
monitor_server
exit_hook
# Using IO.popen(command, 'r+') will avoid watch_command read from $stdin.
# If we use system(*command) instead, IRB and Debug can't read from $stdin
# correctly bacause some keystrokes will be taken by watch_command.
IO.popen(Commands.watch_command, 'r+') do |io|
IO.copy_stream(io, $stdout)
end
end
Process.detach pid
end

def start
@pid = existing_process || start_process
server.monitor_process
server.exit_hook
end
Expand All @@ -41,6 +33,37 @@ def dead?

private

def existing_process
if (pid = Pidfile.pid)
begin
Process.kill 0, pid
pid
rescue Errno::ESRCH
# Process does not exist
rescue Errno::EPERM
# Ignore process owned by another user
end
end
end

def start_process
pid = fork do
Pidfile.write
monitor_server
exit_hook
# Using IO.popen(command, 'r+') will avoid watch_command read from $stdin.
# If we use system(*command) instead, IRB and Debug can't read from $stdin
# correctly bacause some keystrokes will be taken by watch_command.
IO.popen(Commands.watch_command, 'r+') do |io|
IO.copy_stream(io, $stdout)
end
ensure
Pidfile.delete
end
Process.detach pid
pid
end

def monitor_server
Thread.new do
loop do
Expand All @@ -60,6 +83,33 @@ def exit_hook
end
end

module Pidfile
def self.path
Rails.root.join("tmp", "pids", "tailwindcss.txt")
end

def self.read
File.read(path, mode: "rb:UTF-8")
rescue Errno::ENOENT
# File does not exist
end

def self.write
File.write(path, Process.pid, mode: "wb:UTF-8")
end

def self.delete
File.exist?(path) && File.delete(path)
end

def self.pid
Integer(read)
rescue ArgumentError, TypeError
# Invalid content
delete
end
end

class Server
attr_reader :process, :pid

Expand Down

0 comments on commit b4879aa

Please sign in to comment.