File tree Expand file tree Collapse file tree 6 files changed +81
-32
lines changed Expand file tree Collapse file tree 6 files changed +81
-32
lines changed Original file line number Diff line number Diff line change 1
1
## Next version
2
2
3
+ * Automatically restart spring after new commands are added. This means
4
+ that you can add spring-commands-rspec to your Gemfile and then
5
+ immediately start using it, without having to run ` spring stop ` .
6
+ (Spring will effectively run ` spring stop ` for you.)
3
7
* Make app reloading work in apps which spew out lots of output on
4
8
startup (previously a buffer would fill up and cause the process to
5
9
hang). Issue #332 .
Original file line number Diff line number Diff line change @@ -218,8 +218,7 @@ speed-up).
218
218
219
219
### Additional commands
220
220
221
- You can add these to your Gemfile for additional commands (run ` spring stop ` afterwards
222
- to pick up the changes):
221
+ You can add these to your Gemfile for additional commands:
223
222
224
223
* [ spring-commands-rspec] ( https://github.com/jonleighton/spring-commands-rspec )
225
224
* [ spring-commands-cucumber] ( https://github.com/jonleighton/spring-commands-cucumber )
Original file line number Diff line number Diff line change @@ -21,27 +21,54 @@ def server
21
21
end
22
22
23
23
def call
24
- boot_server unless env . server_running?
24
+ if env . server_running?
25
+ warm_run
26
+ else
27
+ cold_run
28
+ end
29
+ rescue Errno ::ECONNRESET
30
+ exit 1
31
+ ensure
32
+ server . close if @server
33
+ end
34
+
35
+ def warm_run
36
+ run
37
+ rescue CommandNotFound
38
+ require "spring/commands"
39
+
40
+ if Spring . command? ( args . first )
41
+ # Command installed since spring started
42
+ stop_server
43
+ cold_run
44
+ else
45
+ raise
46
+ end
47
+ end
48
+
49
+ def cold_run
50
+ boot_server
51
+ run
52
+ end
53
+
54
+ def run
25
55
verify_server_version
26
56
27
57
application , client = UNIXSocket . pair
28
58
29
59
queue_signals
30
60
connect_to_application ( client )
31
61
run_command ( client , application )
32
- rescue Errno ::ECONNRESET
33
- exit 1
34
- ensure
35
- server . close if @server
36
62
end
37
63
38
64
def boot_server
39
65
env . socket_path . unlink if env . socket_path . exist?
40
66
41
- pid = fork {
42
- require "spring/server"
43
- Spring ::Server . boot
44
- }
67
+ pid = Process . spawn (
68
+ "ruby" ,
69
+ "-r" , "spring/server" ,
70
+ "-e" , "Spring::Server.boot"
71
+ )
45
72
46
73
until env . socket_path . exist?
47
74
_ , status = Process . waitpid2 ( pid , Process ::WNOHANG )
@@ -50,6 +77,12 @@ def boot_server
50
77
end
51
78
end
52
79
80
+ def stop_server
81
+ server . close
82
+ @server = nil
83
+ env . stop
84
+ end
85
+
53
86
def verify_server_version
54
87
server_version = server . gets . chomp
55
88
if server_version != env . version
Original file line number Diff line number Diff line change 3
3
module Spring
4
4
module Client
5
5
class Stop < Command
6
- TIMEOUT = 2 # seconds
7
-
8
6
def self . description
9
7
"Stop all spring processes for this project."
10
8
end
11
9
12
10
def call
13
- if env . server_running?
14
- timeout = Time . now + TIMEOUT
15
- kill 'TERM'
16
- sleep 0.1 until !env . server_running? || Time . now >= timeout
17
-
18
- if env . server_running?
19
- $stderr. puts "Spring did not stop; killing forcibly."
20
- kill 'KILL'
21
- else
22
- puts "Spring stopped."
23
- end
24
- else
11
+ case env . stop
12
+ when :stopped
13
+ puts "Spring stopped."
14
+ when :killed
15
+ $stderr. puts "Spring did not stop; killing forcibly."
16
+ when :not_running
25
17
puts "Spring is not running"
26
18
end
27
19
end
28
-
29
- def kill ( sig )
30
- pid = env . pid
31
- Process . kill ( sig , pid ) if pid
32
- rescue Errno ::ESRCH
33
- # already dead
34
- end
35
20
end
36
21
end
37
22
end
Original file line number Diff line number Diff line change 9
9
10
10
module Spring
11
11
IGNORE_SIGNALS = %w( INT QUIT )
12
+ STOP_TIMEOUT = 2 # seconds
12
13
13
14
class Env
14
15
attr_reader :log_file
@@ -80,5 +81,29 @@ def log(message)
80
81
log_file . puts "[#{ Time . now } ] [#{ Process . pid } ] #{ message } "
81
82
log_file . flush
82
83
end
84
+
85
+ def stop
86
+ if server_running?
87
+ timeout = Time . now + STOP_TIMEOUT
88
+ kill 'TERM'
89
+ sleep 0.1 until !server_running? || Time . now >= timeout
90
+
91
+ if server_running?
92
+ kill 'KILL'
93
+ :killed
94
+ else
95
+ :stopped
96
+ end
97
+ else
98
+ :not_running
99
+ end
100
+ end
101
+
102
+ def kill ( sig )
103
+ pid = self . pid
104
+ Process . kill ( sig , pid ) if pid
105
+ rescue Errno ::ESRCH
106
+ # already dead
107
+ end
83
108
end
84
109
end
Original file line number Diff line number Diff line change @@ -157,6 +157,9 @@ def self.omg
157
157
end
158
158
159
159
test "custom commands" do
160
+ # Start spring before setting up the command, to test that it gracefully upgrades itself
161
+ assert_success "bin/rails runner ''"
162
+
160
163
File . write ( app . spring_config , <<-CODE )
161
164
class CustomCommand
162
165
def call
You can’t perform that action at this time.
0 commit comments