rsense-server 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +14 -0
  4. data/Guardfile +5 -0
  5. data/LICENSE.txt +1 -0
  6. data/README.md +51 -0
  7. data/Rakefile +9 -0
  8. data/bin/_rsense.rb +115 -0
  9. data/config/puma.rb +2 -0
  10. data/lib/rsense/server/code.rb +38 -0
  11. data/lib/rsense/server/command/completion_result.rb +11 -0
  12. data/lib/rsense/server/command/special_meth.rb +18 -0
  13. data/lib/rsense/server/command/type_inference_method.rb +24 -0
  14. data/lib/rsense/server/command.rb +239 -0
  15. data/lib/rsense/server/config.rb +70 -0
  16. data/lib/rsense/server/gem_path.rb +18 -0
  17. data/lib/rsense/server/listeners/find_definition_event_listener.rb +91 -0
  18. data/lib/rsense/server/listeners/where_event_listener.rb +39 -0
  19. data/lib/rsense/server/load_path.rb +62 -0
  20. data/lib/rsense/server/options.rb +85 -0
  21. data/lib/rsense/server/parser.rb +17 -0
  22. data/lib/rsense/server/path_info.rb +17 -0
  23. data/lib/rsense/server/project.rb +24 -0
  24. data/lib/rsense/server/version.rb +5 -0
  25. data/lib/rsense/server.rb +18 -0
  26. data/rsense-server.gemspec +35 -0
  27. data/spec/fixtures/config_fixture/.rsense +4 -0
  28. data/spec/fixtures/deeply/nested/thing.rb +0 -0
  29. data/spec/fixtures/find_def_sample.json +10 -0
  30. data/spec/fixtures/sample.json +10 -0
  31. data/spec/fixtures/test_gem/.gitignore +22 -0
  32. data/spec/fixtures/test_gem/Gemfile +4 -0
  33. data/spec/fixtures/test_gem/LICENSE.txt +22 -0
  34. data/spec/fixtures/test_gem/README.md +29 -0
  35. data/spec/fixtures/test_gem/Rakefile +2 -0
  36. data/spec/fixtures/test_gem/lib/sample/version.rb +3 -0
  37. data/spec/fixtures/test_gem/lib/sample.rb +16 -0
  38. data/spec/fixtures/test_gem/sample.gemspec +23 -0
  39. data/spec/fixtures/test_gem/test.json +10 -0
  40. data/spec/rsense/server/code_spec.rb +44 -0
  41. data/spec/rsense/server/command/special_meth_spec.rb +23 -0
  42. data/spec/rsense/server/command_spec.rb +108 -0
  43. data/spec/rsense/server/config_spec.rb +27 -0
  44. data/spec/rsense/server/gem_path_spec.rb +16 -0
  45. data/spec/rsense/server/load_path_spec.rb +63 -0
  46. data/spec/rsense/server/options_spec.rb +33 -0
  47. data/spec/rsense/server/path_info_spec.rb +11 -0
  48. data/spec/rsense/server/project_spec.rb +18 -0
  49. data/spec/rsense/server_spec.rb +7 -0
  50. data/spec/spec_helper.rb +16 -0
  51. data/vendor/gems/puma-2.8.2-java/COPYING +55 -0
  52. data/vendor/gems/puma-2.8.2-java/DEPLOYMENT.md +92 -0
  53. data/vendor/gems/puma-2.8.2-java/Gemfile +17 -0
  54. data/vendor/gems/puma-2.8.2-java/History.txt +532 -0
  55. data/vendor/gems/puma-2.8.2-java/LICENSE +26 -0
  56. data/vendor/gems/puma-2.8.2-java/Manifest.txt +68 -0
  57. data/vendor/gems/puma-2.8.2-java/README.md +251 -0
  58. data/vendor/gems/puma-2.8.2-java/Rakefile +158 -0
  59. data/vendor/gems/puma-2.8.2-java/bin/puma +10 -0
  60. data/vendor/gems/puma-2.8.2-java/bin/puma-wild +17 -0
  61. data/vendor/gems/puma-2.8.2-java/bin/pumactl +12 -0
  62. data/vendor/gems/puma-2.8.2-java/docs/config.md +0 -0
  63. data/vendor/gems/puma-2.8.2-java/docs/nginx.md +80 -0
  64. data/vendor/gems/puma-2.8.2-java/docs/signals.md +42 -0
  65. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/PumaHttp11Service.java +17 -0
  66. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/ext_help.h +15 -0
  67. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/extconf.rb +8 -0
  68. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.c +1225 -0
  69. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.h +64 -0
  70. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.java.rl +161 -0
  71. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.rl +146 -0
  72. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser_common.rl +54 -0
  73. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/io_buffer.c +155 -0
  74. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/mini_ssl.c +195 -0
  75. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11.java +225 -0
  76. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11Parser.java +488 -0
  77. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/MiniSSL.java +289 -0
  78. data/vendor/gems/puma-2.8.2-java/ext/puma_http11/puma_http11.c +491 -0
  79. data/vendor/gems/puma-2.8.2-java/lib/puma/accept_nonblock.rb +23 -0
  80. data/vendor/gems/puma-2.8.2-java/lib/puma/app/status.rb +59 -0
  81. data/vendor/gems/puma-2.8.2-java/lib/puma/binder.rb +298 -0
  82. data/vendor/gems/puma-2.8.2-java/lib/puma/capistrano.rb +86 -0
  83. data/vendor/gems/puma-2.8.2-java/lib/puma/cli.rb +587 -0
  84. data/vendor/gems/puma-2.8.2-java/lib/puma/client.rb +289 -0
  85. data/vendor/gems/puma-2.8.2-java/lib/puma/cluster.rb +389 -0
  86. data/vendor/gems/puma-2.8.2-java/lib/puma/compat.rb +18 -0
  87. data/vendor/gems/puma-2.8.2-java/lib/puma/configuration.rb +377 -0
  88. data/vendor/gems/puma-2.8.2-java/lib/puma/const.rb +165 -0
  89. data/vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb +251 -0
  90. data/vendor/gems/puma-2.8.2-java/lib/puma/daemon_ext.rb +25 -0
  91. data/vendor/gems/puma-2.8.2-java/lib/puma/delegation.rb +11 -0
  92. data/vendor/gems/puma-2.8.2-java/lib/puma/detect.rb +4 -0
  93. data/vendor/gems/puma-2.8.2-java/lib/puma/events.rb +130 -0
  94. data/vendor/gems/puma-2.8.2-java/lib/puma/io_buffer.rb +7 -0
  95. data/vendor/gems/puma-2.8.2-java/lib/puma/java_io_buffer.rb +45 -0
  96. data/vendor/gems/puma-2.8.2-java/lib/puma/jruby_restart.rb +83 -0
  97. data/vendor/gems/puma-2.8.2-java/lib/puma/minissl.rb +148 -0
  98. data/vendor/gems/puma-2.8.2-java/lib/puma/null_io.rb +34 -0
  99. data/vendor/gems/puma-2.8.2-java/lib/puma/puma_http11.jar +0 -0
  100. data/vendor/gems/puma-2.8.2-java/lib/puma/rack_default.rb +7 -0
  101. data/vendor/gems/puma-2.8.2-java/lib/puma/rack_patch.rb +45 -0
  102. data/vendor/gems/puma-2.8.2-java/lib/puma/reactor.rb +183 -0
  103. data/vendor/gems/puma-2.8.2-java/lib/puma/runner.rb +146 -0
  104. data/vendor/gems/puma-2.8.2-java/lib/puma/server.rb +801 -0
  105. data/vendor/gems/puma-2.8.2-java/lib/puma/single.rb +102 -0
  106. data/vendor/gems/puma-2.8.2-java/lib/puma/tcp_logger.rb +32 -0
  107. data/vendor/gems/puma-2.8.2-java/lib/puma/thread_pool.rb +185 -0
  108. data/vendor/gems/puma-2.8.2-java/lib/puma/util.rb +9 -0
  109. data/vendor/gems/puma-2.8.2-java/lib/puma.rb +14 -0
  110. data/vendor/gems/puma-2.8.2-java/lib/rack/handler/puma.rb +66 -0
  111. data/vendor/gems/puma-2.8.2-java/puma.gemspec +55 -0
  112. data/vendor/gems/puma-2.8.2-java/test/test_app_status.rb +92 -0
  113. data/vendor/gems/puma-2.8.2-java/test/test_cli.rb +173 -0
  114. data/vendor/gems/puma-2.8.2-java/test/test_config.rb +26 -0
  115. data/vendor/gems/puma-2.8.2-java/test/test_http10.rb +27 -0
  116. data/vendor/gems/puma-2.8.2-java/test/test_http11.rb +144 -0
  117. data/vendor/gems/puma-2.8.2-java/test/test_integration.rb +165 -0
  118. data/vendor/gems/puma-2.8.2-java/test/test_iobuffer.rb +38 -0
  119. data/vendor/gems/puma-2.8.2-java/test/test_minissl.rb +25 -0
  120. data/vendor/gems/puma-2.8.2-java/test/test_null_io.rb +31 -0
  121. data/vendor/gems/puma-2.8.2-java/test/test_persistent.rb +238 -0
  122. data/vendor/gems/puma-2.8.2-java/test/test_puma_server.rb +323 -0
  123. data/vendor/gems/puma-2.8.2-java/test/test_rack_handler.rb +10 -0
  124. data/vendor/gems/puma-2.8.2-java/test/test_rack_server.rb +141 -0
  125. data/vendor/gems/puma-2.8.2-java/test/test_tcp_rack.rb +42 -0
  126. data/vendor/gems/puma-2.8.2-java/test/test_thread_pool.rb +156 -0
  127. data/vendor/gems/puma-2.8.2-java/test/test_unix_socket.rb +39 -0
  128. data/vendor/gems/puma-2.8.2-java/test/test_ws.rb +89 -0
  129. data/vendor/gems/puma-2.8.2-java/tools/jungle/README.md +9 -0
  130. data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/README.md +54 -0
  131. data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/puma +332 -0
  132. data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/run-puma +3 -0
  133. data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/README.md +61 -0
  134. data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma-manager.conf +31 -0
  135. data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma.conf +63 -0
  136. data/vendor/gems/puma-2.8.2-java/tools/trickletest.rb +45 -0
  137. metadata +389 -0
@@ -0,0 +1,587 @@
1
+ require 'optparse'
2
+ require 'uri'
3
+
4
+ require 'puma/server'
5
+ require 'puma/const'
6
+ require 'puma/configuration'
7
+ require 'puma/binder'
8
+ require 'puma/detect'
9
+ require 'puma/daemon_ext'
10
+ require 'puma/util'
11
+ require 'puma/single'
12
+ require 'puma/cluster'
13
+
14
+ require 'rack/commonlogger'
15
+ require 'rack/utils'
16
+
17
+ module Puma
18
+ # Handles invoke a Puma::Server in a command line style.
19
+ #
20
+ class CLI
21
+ # Create a new CLI object using +argv+ as the command line
22
+ # arguments.
23
+ #
24
+ # +stdout+ and +stderr+ can be set to IO-like objects which
25
+ # this object will report status on.
26
+ #
27
+ def initialize(argv, events=Events.stdio)
28
+ @debug = false
29
+ @argv = argv
30
+
31
+ @events = events
32
+
33
+ @status = nil
34
+ @runner = nil
35
+
36
+ @config = nil
37
+
38
+ ENV['NEWRELIC_DISPATCHER'] ||= "puma"
39
+
40
+ setup_options
41
+ generate_restart_data
42
+
43
+ @binder = Binder.new(@events)
44
+ @binder.import_from_env
45
+ end
46
+
47
+ # The Binder object containing the sockets bound to.
48
+ attr_reader :binder
49
+
50
+ # The Configuration object used.
51
+ attr_reader :config
52
+
53
+ # The Hash of options used to configure puma.
54
+ attr_reader :options
55
+
56
+ # The Events object used to output information.
57
+ attr_reader :events
58
+
59
+ # Delegate +log+ to +@events+
60
+ #
61
+ def log(str)
62
+ @events.log str
63
+ end
64
+
65
+ # Delegate +error+ to +@events+
66
+ #
67
+ def error(str)
68
+ @events.error str
69
+ end
70
+
71
+ def debug(str)
72
+ if @options[:debug]
73
+ @events.log "- #{str}"
74
+ end
75
+ end
76
+
77
+ def jruby?
78
+ IS_JRUBY
79
+ end
80
+
81
+ def windows?
82
+ RUBY_PLATFORM =~ /mswin32|ming32/
83
+ end
84
+
85
+ def unsupported(str, cond=true)
86
+ return unless cond
87
+ @events.error str
88
+ raise UnsupportedOption
89
+ end
90
+
91
+ # Build the OptionParser object to handle the available options.
92
+ #
93
+ def setup_options
94
+ @options = {
95
+ :min_threads => 0,
96
+ :max_threads => 16,
97
+ :quiet => false,
98
+ :debug => false,
99
+ :binds => [],
100
+ :workers => 0,
101
+ :daemon => false,
102
+ :before_worker_boot => [],
103
+ :after_worker_boot => []
104
+ }
105
+
106
+ @parser = OptionParser.new do |o|
107
+ o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg|
108
+ @options[:binds] << arg
109
+ end
110
+
111
+ o.on "-C", "--config PATH", "Load PATH as a config file" do |arg|
112
+ @options[:config_file] = arg
113
+ end
114
+
115
+ o.on "--control URL", "The bind url to use for the control server",
116
+ "Use 'auto' to use temp unix server" do |arg|
117
+ if arg
118
+ @options[:control_url] = arg
119
+ elsif jruby?
120
+ unsupported "No default url available on JRuby"
121
+ end
122
+ end
123
+
124
+ o.on "--control-token TOKEN",
125
+ "The token to use as authentication for the control server" do |arg|
126
+ @options[:control_auth_token] = arg
127
+ end
128
+
129
+ o.on "-d", "--daemon", "Daemonize the server into the background" do
130
+ @options[:daemon] = true
131
+ @options[:quiet] = true
132
+ end
133
+
134
+ o.on "--debug", "Log lowlevel debugging information" do
135
+ @options[:debug] = true
136
+ end
137
+
138
+ o.on "--dir DIR", "Change to DIR before starting" do |d|
139
+ @options[:directory] = d.to_s
140
+ @options[:worker_directory] = d.to_s
141
+ end
142
+
143
+ o.on "-e", "--environment ENVIRONMENT",
144
+ "The environment to run the Rack app on (default development)" do |arg|
145
+ @options[:environment] = arg
146
+ end
147
+
148
+ o.on "-I", "--include PATH", "Specify $LOAD_PATH directories" do |arg|
149
+ $LOAD_PATH.unshift(*arg.split(':'))
150
+ end
151
+
152
+ o.on "-p", "--port PORT", "Define the TCP port to bind to",
153
+ "Use -b for more advanced options" do |arg|
154
+ @options[:binds] << "tcp://#{Configuration::DefaultTCPHost}:#{arg}"
155
+ end
156
+
157
+ o.on "--pidfile PATH", "Use PATH as a pidfile" do |arg|
158
+ @options[:pidfile] = arg
159
+ end
160
+
161
+ o.on "--preload", "Preload the app. Cluster mode only" do
162
+ @options[:preload_app] = true
163
+ end
164
+
165
+ o.on "--prune-bundler", "Prune out the bundler env if possible" do
166
+ @options[:prune_bundler] = true
167
+ end
168
+
169
+ o.on "-q", "--quiet", "Quiet down the output" do
170
+ @options[:quiet] = true
171
+ end
172
+
173
+ o.on "-R", "--restart-cmd CMD",
174
+ "The puma command to run during a hot restart",
175
+ "Default: inferred" do |cmd|
176
+ @options[:restart_cmd] = cmd
177
+ end
178
+
179
+ o.on "-S", "--state PATH", "Where to store the state details" do |arg|
180
+ @options[:state] = arg
181
+ end
182
+
183
+ o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg|
184
+ min, max = arg.split(":")
185
+ if max
186
+ @options[:min_threads] = min
187
+ @options[:max_threads] = max
188
+ else
189
+ @options[:min_threads] = 0
190
+ @options[:max_threads] = arg
191
+ end
192
+ end
193
+
194
+ o.on "--tcp-mode", "Run the app in raw TCP mode instead of HTTP mode" do
195
+ @options[:mode] = :tcp
196
+ end
197
+
198
+ o.on "-V", "--version", "Print the version information" do
199
+ puts "puma version #{Puma::Const::VERSION}"
200
+ exit 1
201
+ end
202
+
203
+ o.on "-w", "--workers COUNT",
204
+ "Activate cluster mode: How many worker processes to create" do |arg|
205
+ @options[:workers] = arg.to_i
206
+ end
207
+
208
+ o.on "--tag NAME", "Additional text to display in process listing" do |arg|
209
+ @options[:tag] = arg
210
+ end
211
+ end
212
+
213
+ @parser.banner = "puma <options> <rackup file>"
214
+
215
+ @parser.on_tail "-h", "--help", "Show help" do
216
+ log @parser
217
+ exit 1
218
+ end
219
+ end
220
+
221
+ def write_state
222
+ write_pid
223
+
224
+ require 'yaml'
225
+
226
+ if path = @options[:state]
227
+ state = { "pid" => Process.pid }
228
+
229
+ cfg = @config.dup
230
+
231
+ [ :logger, :before_worker_boot, :after_worker_boot, :on_restart ].each { |o| cfg.options.delete o }
232
+
233
+ state["config"] = cfg
234
+
235
+ File.open(path, "w") do |f|
236
+ f.write state.to_yaml
237
+ end
238
+ end
239
+ end
240
+
241
+ # If configured, write the pid of the current process out
242
+ # to a file.
243
+ #
244
+ def write_pid
245
+ if path = @options[:pidfile]
246
+ File.open(path, "w") do |f|
247
+ f.puts Process.pid
248
+ end
249
+
250
+ cur = Process.pid
251
+
252
+ at_exit do
253
+ if cur == Process.pid
254
+ delete_pidfile
255
+ end
256
+ end
257
+ end
258
+ end
259
+
260
+ def env
261
+ # Try the user option first, then the environment variable,
262
+ # finally default to development
263
+ @options[:environment] || ENV['RACK_ENV'] || 'development'
264
+ end
265
+
266
+ def set_rack_environment
267
+ @options[:environment] = env
268
+ ENV['RACK_ENV'] = env
269
+ end
270
+
271
+ def delete_pidfile
272
+ if path = @options[:pidfile]
273
+ File.unlink path if File.exist? path
274
+ end
275
+ end
276
+
277
+ def find_config
278
+ if cfg = @options[:config_file]
279
+ # Allow - to disable config finding
280
+ if cfg == "-"
281
+ @options[:config_file] = nil
282
+ return
283
+ end
284
+
285
+ return
286
+ end
287
+
288
+ pos = ["config/puma/#{env}.rb", "config/puma.rb"]
289
+ @options[:config_file] = pos.find { |f| File.exist? f }
290
+ end
291
+
292
+ # :nodoc:
293
+ def parse_options
294
+ @parser.parse! @argv
295
+
296
+ if @argv.last
297
+ @options[:rackup] = @argv.shift
298
+ end
299
+
300
+ find_config
301
+
302
+ @config = Puma::Configuration.new @options
303
+
304
+ # Advertise the Configuration
305
+ Puma.cli_config = @config
306
+
307
+ @config.load
308
+
309
+ if clustered?
310
+ unsupported "worker mode not supported on JRuby or Windows",
311
+ jruby? || windows?
312
+ end
313
+
314
+ if @options[:daemon] and windows?
315
+ unsupported "daemon mode not supported on Windows"
316
+ end
317
+ end
318
+
319
+ def clustered?
320
+ @options[:workers] > 0
321
+ end
322
+
323
+ def graceful_stop
324
+ @runner.stop_blocked
325
+ log "- Goodbye!"
326
+ end
327
+
328
+ def generate_restart_data
329
+ # Use the same trick as unicorn, namely favor PWD because
330
+ # it will contain an unresolved symlink, useful for when
331
+ # the pwd is /data/releases/current.
332
+ if dir = ENV['PWD']
333
+ s_env = File.stat(dir)
334
+ s_pwd = File.stat(Dir.pwd)
335
+
336
+ if s_env.ino == s_pwd.ino and s_env.dev == s_pwd.dev
337
+ @restart_dir = dir
338
+ @options[:worker_directory] = dir
339
+ end
340
+ end
341
+
342
+ @restart_dir ||= Dir.pwd
343
+
344
+ @original_argv = ARGV.dup
345
+
346
+ if defined? Rubinius::OS_ARGV
347
+ @restart_argv = Rubinius::OS_ARGV
348
+ else
349
+ require 'rubygems'
350
+
351
+ # if $0 is a file in the current directory, then restart
352
+ # it the same, otherwise add -S on there because it was
353
+ # picked up in PATH.
354
+ #
355
+ if File.exist?($0)
356
+ arg0 = [Gem.ruby, $0]
357
+ else
358
+ arg0 = [Gem.ruby, "-S", $0]
359
+ end
360
+
361
+ # Detect and reinject -Ilib from the command line
362
+ lib = File.expand_path "lib"
363
+ arg0[1,0] = ["-I", lib] if $:[0] == lib
364
+
365
+ @restart_argv = arg0 + ARGV
366
+ end
367
+ end
368
+
369
+ def restart_args
370
+ if cmd = @options[:restart_cmd]
371
+ cmd.split(' ') + @original_argv
372
+ else
373
+ @restart_argv
374
+ end
375
+ end
376
+
377
+ def jruby_daemon_start
378
+ require 'puma/jruby_restart'
379
+ JRubyRestart.daemon_start(@restart_dir, restart_args)
380
+ end
381
+
382
+ def restart!
383
+ @options[:on_restart].each do |block|
384
+ block.call self
385
+ end
386
+
387
+ if jruby?
388
+ @binder.listeners.each_with_index do |(str,io),i|
389
+ io.close
390
+
391
+ # We have to unlink a unix socket path that's not being used
392
+ uri = URI.parse str
393
+ if uri.scheme == "unix"
394
+ path = "#{uri.host}#{uri.path}"
395
+ File.unlink path
396
+ end
397
+ end
398
+
399
+ require 'puma/jruby_restart'
400
+ JRubyRestart.chdir_exec(@restart_dir, restart_args)
401
+
402
+ elsif windows?
403
+ @binder.listeners.each_with_index do |(str,io),i|
404
+ io.close
405
+
406
+ # We have to unlink a unix socket path that's not being used
407
+ uri = URI.parse str
408
+ if uri.scheme == "unix"
409
+ path = "#{uri.host}#{uri.path}"
410
+ File.unlink path
411
+ end
412
+ end
413
+
414
+ argv = restart_args
415
+
416
+ Dir.chdir @restart_dir
417
+
418
+ argv += [redirects] unless RUBY_VERSION < '1.9'
419
+ Kernel.exec(*argv)
420
+
421
+ else
422
+ redirects = {:close_others => true}
423
+ @binder.listeners.each_with_index do |(l,io),i|
424
+ ENV["PUMA_INHERIT_#{i}"] = "#{io.to_i}:#{l}"
425
+ redirects[io.to_i] = io.to_i
426
+ end
427
+
428
+ argv = restart_args
429
+
430
+ Dir.chdir @restart_dir
431
+
432
+ argv += [redirects] unless RUBY_VERSION < '1.9'
433
+ Kernel.exec(*argv)
434
+ end
435
+ end
436
+
437
+ def prune_bundler?
438
+ @options[:prune_bundler] && clustered? && !@options[:preload_app]
439
+ end
440
+
441
+ # Parse the options, load the rackup, start the server and wait
442
+ # for it to finish.
443
+ #
444
+ def run
445
+ begin
446
+ parse_options
447
+ rescue UnsupportedOption
448
+ exit 1
449
+ end
450
+
451
+ if prune_bundler? && defined?(Bundler)
452
+ puma = Bundler.rubygems.loaded_specs("puma")
453
+
454
+ dirs = puma.require_paths.map { |x| File.join(puma.full_gem_path, x) }
455
+
456
+ puma_lib_dir = dirs.detect { |x| File.exist? File.join(x, "../bin/puma-wild") }
457
+
458
+ deps = puma.runtime_dependencies.map { |d|
459
+ spec = Bundler.rubygems.loaded_specs(d.name)
460
+ "#{d.name}:#{spec.version.to_s}"
461
+ }.join(",")
462
+
463
+ if puma_lib_dir
464
+ log "* Pruning Bundler environment"
465
+ Bundler.with_clean_env do
466
+
467
+ wild = File.expand_path(File.join(puma_lib_dir, "../bin/puma-wild"))
468
+
469
+ args = [Gem.ruby] + dirs.map { |x| ["-I", x] }.flatten +
470
+ [wild, deps] + @original_argv
471
+
472
+ Kernel.exec(*args)
473
+ end
474
+ end
475
+
476
+ log "! Unable to prune Bundler environment, continuing"
477
+ end
478
+
479
+ if dir = @options[:directory]
480
+ Dir.chdir dir
481
+ end
482
+
483
+ set_rack_environment
484
+
485
+ if clustered?
486
+ @events = PidEvents.new STDOUT, STDERR
487
+ @options[:logger] = @events
488
+
489
+ @runner = Cluster.new(self)
490
+ else
491
+ @runner = Single.new(self)
492
+ end
493
+
494
+ setup_signals
495
+ set_process_title
496
+
497
+ @status = :run
498
+
499
+ @runner.run
500
+
501
+ case @status
502
+ when :halt
503
+ log "* Stopping immediately!"
504
+ when :run, :stop
505
+ graceful_stop
506
+ when :restart
507
+ log "* Restarting..."
508
+ @runner.before_restart
509
+ restart!
510
+ when :exit
511
+ # nothing
512
+ end
513
+ end
514
+
515
+ def setup_signals
516
+ begin
517
+ Signal.trap "SIGUSR2" do
518
+ restart
519
+ end
520
+ rescue Exception
521
+ log "*** SIGUSR2 not implemented, signal based restart unavailable!"
522
+ end
523
+
524
+ begin
525
+ Signal.trap "SIGUSR1" do
526
+ phased_restart
527
+ end
528
+ rescue Exception
529
+ log "*** SIGUSR1 not implemented, signal based restart unavailable!"
530
+ end
531
+
532
+ begin
533
+ Signal.trap "SIGTERM" do
534
+ stop
535
+ end
536
+ rescue Exception
537
+ log "*** SIGTERM not implemented, signal based gracefully stopping unavailable!"
538
+ end
539
+
540
+ if jruby?
541
+ Signal.trap("INT") do
542
+ @status = :exit
543
+ graceful_stop
544
+ exit
545
+ end
546
+ end
547
+ end
548
+
549
+ def stop
550
+ @status = :stop
551
+ @runner.stop
552
+ end
553
+
554
+ def restart
555
+ @status = :restart
556
+ @runner.restart
557
+ end
558
+
559
+ def phased_restart
560
+ unless @runner.respond_to?(:phased_restart) and @runner.phased_restart
561
+ log "* phased-restart called but not available, restarting normally."
562
+ return restart
563
+ end
564
+ true
565
+ end
566
+
567
+ def stats
568
+ @runner.stats
569
+ end
570
+
571
+ def halt
572
+ @status = :halt
573
+ @runner.halt
574
+ end
575
+
576
+ private
577
+ def title
578
+ buffer = "puma #{Puma::Const::VERSION} (#{@options[:binds].join(',')})"
579
+ buffer << " [#{@options[:tag]}]" if @options[:tag]
580
+ buffer
581
+ end
582
+
583
+ def set_process_title
584
+ Process.respond_to?(:setproctitle) ? Process.setproctitle(title) : $0 = title
585
+ end
586
+ end
587
+ end