Skip to content

Commit b4879aa

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

File tree

1 file changed

+62
-12
lines changed

1 file changed

+62
-12
lines changed

lib/tailwindcss/server_process.rb

+62-12
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,37 @@ 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+
4467
def monitor_server
4568
Thread.new do
4669
loop do
@@ -60,6 +83,33 @@ def exit_hook
6083
end
6184
end
6285

86+
module Pidfile
87+
def self.path
88+
Rails.root.join("tmp", "pids", "tailwindcss.txt")
89+
end
90+
91+
def self.read
92+
File.read(path, mode: "rb:UTF-8")
93+
rescue Errno::ENOENT
94+
# File does not exist
95+
end
96+
97+
def self.write
98+
File.write(path, Process.pid, mode: "wb:UTF-8")
99+
end
100+
101+
def self.delete
102+
File.exist?(path) && File.delete(path)
103+
end
104+
105+
def self.pid
106+
Integer(read)
107+
rescue ArgumentError, TypeError
108+
# Invalid content
109+
delete
110+
end
111+
end
112+
63113
class Server
64114
attr_reader :process, :pid
65115

0 commit comments

Comments
 (0)