Skip to content

Commit 5b161b3

Browse files
committed
Ensure ServerProcess is started only once
1 parent 7265220 commit 5b161b3

File tree

1 file changed

+62
-12
lines changed

1 file changed

+62
-12
lines changed

lib/tailwindcss/server_process.rb

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,12 @@ def self.start
66
new.start
77
end
88

9-
def start
9+
def initialize
1010
@server = Server.new(self)
11-
@pid = fork do
12-
monitor_server
13-
exit_hook
14-
# Using IO.popen(command, 'r+') will avoid watch_command read from $stdin.
15-
# If we use system(*command) instead, IRB and Debug can't read from $stdin
16-
# correctly bacause some keystrokes will be taken by watch_command.
17-
IO.popen(Commands.watch_command, 'r+') do |io|
18-
IO.copy_stream(io, $stdout)
19-
end
20-
end
21-
Process.detach pid
11+
end
2212

13+
def start
14+
@pid = existing_process || start_process
2315
server.monitor_process
2416
server.exit_hook
2517
end
@@ -41,6 +33,64 @@ def dead?
4133

4234
private
4335

36+
def existing_process
37+
if (pid = Pidfile.pid)
38+
begin
39+
Process.kill 0, pid
40+
pid
41+
rescue Errno::ESRCH
42+
# Process does not exist
43+
rescue Errno::EPERM
44+
# Ignore process owned by another user
45+
end
46+
end
47+
end
48+
49+
def start_process
50+
pid = fork do
51+
Pidfile.write
52+
monitor_server
53+
exit_hook
54+
# Using IO.popen(command, 'r+') will avoid watch_command read from $stdin.
55+
# If we use system(*command) instead, IRB and Debug can't read from $stdin
56+
# correctly bacause some keystrokes will be taken by watch_command.
57+
IO.popen(Commands.watch_command, 'r+') do |io|
58+
IO.copy_stream(io, $stdout)
59+
end
60+
ensure
61+
Pidfile.delete
62+
end
63+
Process.detach pid
64+
pid
65+
end
66+
67+
module Pidfile
68+
def self.path
69+
Rails.root.join("tmp", "pids", "tailwindcss.txt")
70+
end
71+
72+
def self.read
73+
File.read(path, mode: "rb:UTF-8")
74+
rescue Errno::ENOENT
75+
# File does not exist
76+
end
77+
78+
def self.write
79+
File.write(path, Process.pid, mode: "wb:UTF-8")
80+
end
81+
82+
def self.delete
83+
File.exist?(path) && File.delete(path)
84+
end
85+
86+
def self.pid
87+
Integer(read)
88+
rescue ArgumentError, TypeError
89+
# Invalid content
90+
delete
91+
end
92+
end
93+
4494
def monitor_server
4595
Thread.new do
4696
loop do

0 commit comments

Comments
 (0)