rsense-server 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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