jun-puma 1.0.1-java → 1.0.2-java

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/lib/puma/puma_http11.jar +0 -0
  3. metadata +3 -81
  4. data/bin/puma-wild +0 -25
  5. data/docs/architecture.md +0 -74
  6. data/docs/compile_options.md +0 -55
  7. data/docs/deployment.md +0 -102
  8. data/docs/fork_worker.md +0 -31
  9. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  10. data/docs/images/puma-connection-flow.png +0 -0
  11. data/docs/images/puma-general-arch.png +0 -0
  12. data/docs/jungle/README.md +0 -9
  13. data/docs/jungle/rc.d/README.md +0 -74
  14. data/docs/jungle/rc.d/puma +0 -61
  15. data/docs/jungle/rc.d/puma.conf +0 -10
  16. data/docs/kubernetes.md +0 -78
  17. data/docs/nginx.md +0 -80
  18. data/docs/plugins.md +0 -38
  19. data/docs/rails_dev_mode.md +0 -28
  20. data/docs/restart.md +0 -64
  21. data/docs/signals.md +0 -98
  22. data/docs/stats.md +0 -142
  23. data/docs/systemd.md +0 -244
  24. data/docs/testing_benchmarks_local_files.md +0 -150
  25. data/docs/testing_test_rackup_ci_files.md +0 -36
  26. data/ext/puma_http11/PumaHttp11Service.java +0 -17
  27. data/ext/puma_http11/ext_help.h +0 -15
  28. data/ext/puma_http11/http11_parser.c +0 -1057
  29. data/ext/puma_http11/http11_parser.h +0 -65
  30. data/ext/puma_http11/http11_parser.java.rl +0 -145
  31. data/ext/puma_http11/http11_parser.rl +0 -149
  32. data/ext/puma_http11/http11_parser_common.rl +0 -54
  33. data/ext/puma_http11/mini_ssl.c +0 -832
  34. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -15
  35. data/ext/puma_http11/org/jruby/puma/Http11.java +0 -226
  36. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +0 -455
  37. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +0 -508
  38. data/ext/puma_http11/puma_http11.c +0 -492
  39. data/lib/puma/app/status.rb +0 -96
  40. data/lib/puma/binder.rb +0 -501
  41. data/lib/puma/cli.rb +0 -243
  42. data/lib/puma/client.rb +0 -632
  43. data/lib/puma/cluster/worker.rb +0 -182
  44. data/lib/puma/cluster/worker_handle.rb +0 -97
  45. data/lib/puma/cluster.rb +0 -562
  46. data/lib/puma/commonlogger.rb +0 -115
  47. data/lib/puma/configuration.rb +0 -391
  48. data/lib/puma/const.rb +0 -289
  49. data/lib/puma/control_cli.rb +0 -316
  50. data/lib/puma/detect.rb +0 -45
  51. data/lib/puma/dsl.rb +0 -1204
  52. data/lib/puma/error_logger.rb +0 -113
  53. data/lib/puma/events.rb +0 -57
  54. data/lib/puma/io_buffer.rb +0 -46
  55. data/lib/puma/jruby_restart.rb +0 -27
  56. data/lib/puma/json_serialization.rb +0 -96
  57. data/lib/puma/launcher/bundle_pruner.rb +0 -104
  58. data/lib/puma/launcher.rb +0 -484
  59. data/lib/puma/log_writer.rb +0 -147
  60. data/lib/puma/minissl/context_builder.rb +0 -95
  61. data/lib/puma/minissl.rb +0 -458
  62. data/lib/puma/null_io.rb +0 -61
  63. data/lib/puma/plugin/systemd.rb +0 -90
  64. data/lib/puma/plugin/tmp_restart.rb +0 -36
  65. data/lib/puma/plugin.rb +0 -111
  66. data/lib/puma/rack/builder.rb +0 -297
  67. data/lib/puma/rack/urlmap.rb +0 -93
  68. data/lib/puma/rack_default.rb +0 -24
  69. data/lib/puma/reactor.rb +0 -125
  70. data/lib/puma/request.rb +0 -671
  71. data/lib/puma/runner.rb +0 -213
  72. data/lib/puma/sd_notify.rb +0 -149
  73. data/lib/puma/server.rb +0 -664
  74. data/lib/puma/single.rb +0 -69
  75. data/lib/puma/state_file.rb +0 -68
  76. data/lib/puma/thread_pool.rb +0 -434
  77. data/lib/puma/util.rb +0 -141
  78. data/lib/puma.rb +0 -78
  79. data/lib/rack/handler/puma.rb +0 -141
  80. data/tools/Dockerfile +0 -16
  81. data/tools/trickletest.rb +0 -44
@@ -1,95 +0,0 @@
1
- module Puma
2
- module MiniSSL
3
- class ContextBuilder
4
- def initialize(params, log_writer)
5
- @params = params
6
- @log_writer = log_writer
7
- end
8
-
9
- def context
10
- ctx = MiniSSL::Context.new
11
-
12
- if defined?(JRUBY_VERSION)
13
- unless params['keystore']
14
- log_writer.error "Please specify the Java keystore via 'keystore='"
15
- end
16
-
17
- ctx.keystore = params['keystore']
18
-
19
- unless params['keystore-pass']
20
- log_writer.error "Please specify the Java keystore password via 'keystore-pass='"
21
- end
22
-
23
- ctx.keystore_pass = params['keystore-pass']
24
- ctx.keystore_type = params['keystore-type']
25
-
26
- if truststore = params['truststore']
27
- ctx.truststore = truststore.eql?('default') ? :default : truststore
28
- ctx.truststore_pass = params['truststore-pass']
29
- ctx.truststore_type = params['truststore-type']
30
- end
31
-
32
- ctx.cipher_suites = params['cipher_suites'] || params['ssl_cipher_list']
33
- ctx.protocols = params['protocols'] if params['protocols']
34
- else
35
- if params['key'].nil? && params['key_pem'].nil?
36
- log_writer.error "Please specify the SSL key via 'key=' or 'key_pem='"
37
- end
38
-
39
- ctx.key = params['key'] if params['key']
40
- ctx.key_pem = params['key_pem'] if params['key_pem']
41
- ctx.key_password_command = params['key_password_command'] if params['key_password_command']
42
-
43
- if params['cert'].nil? && params['cert_pem'].nil?
44
- log_writer.error "Please specify the SSL cert via 'cert=' or 'cert_pem='"
45
- end
46
-
47
- ctx.cert = params['cert'] if params['cert']
48
- ctx.cert_pem = params['cert_pem'] if params['cert_pem']
49
-
50
- if ['peer', 'force_peer'].include?(params['verify_mode'])
51
- unless params['ca']
52
- log_writer.error "Please specify the SSL ca via 'ca='"
53
- end
54
- # needed for Puma::MiniSSL::Socket#peercert, env['puma.peercert']
55
- require 'openssl'
56
- end
57
-
58
- ctx.ca = params['ca'] if params['ca']
59
- ctx.ssl_cipher_filter = params['ssl_cipher_filter'] if params['ssl_cipher_filter']
60
-
61
- ctx.reuse = params['reuse'] if params['reuse']
62
- end
63
-
64
- ctx.no_tlsv1 = params['no_tlsv1'] == 'true'
65
- ctx.no_tlsv1_1 = params['no_tlsv1_1'] == 'true'
66
-
67
- if params['verify_mode']
68
- ctx.verify_mode = case params['verify_mode']
69
- when "peer"
70
- MiniSSL::VERIFY_PEER
71
- when "force_peer"
72
- MiniSSL::VERIFY_PEER | MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT
73
- when "none"
74
- MiniSSL::VERIFY_NONE
75
- else
76
- log_writer.error "Please specify a valid verify_mode="
77
- MiniSSL::VERIFY_NONE
78
- end
79
- end
80
-
81
- if params['verification_flags']
82
- ctx.verification_flags = params['verification_flags'].split(',').
83
- map { |flag| MiniSSL::VERIFICATION_FLAGS.fetch(flag) }.
84
- inject { |sum, flag| sum ? sum | flag : flag }
85
- end
86
-
87
- ctx
88
- end
89
-
90
- private
91
-
92
- attr_reader :params, :log_writer
93
- end
94
- end
95
- end
data/lib/puma/minissl.rb DELETED
@@ -1,458 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- begin
4
- require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
5
- rescue LoadError
6
- end
7
-
8
- require 'open3'
9
- # need for Puma::MiniSSL::OPENSSL constants used in `HAS_TLS1_3`
10
- # use require, see https://github.com/puma/puma/pull/2381
11
- require 'puma/puma_http11'
12
-
13
- module Puma
14
- module MiniSSL
15
- # Define constant at runtime, as it's easy to determine at built time,
16
- # but Puma could (it shouldn't) be loaded with an older OpenSSL version
17
- # @version 5.0.0
18
- HAS_TLS1_3 = IS_JRUBY ||
19
- ((OPENSSL_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) != -1 &&
20
- (OPENSSL_LIBRARY_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) !=-1)
21
-
22
- class Socket
23
- def initialize(socket, engine)
24
- @socket = socket
25
- @engine = engine
26
- @peercert = nil
27
- @reuse = nil
28
- end
29
-
30
- # @!attribute [r] to_io
31
- def to_io
32
- @socket
33
- end
34
-
35
- def closed?
36
- @socket.closed?
37
- end
38
-
39
- # Returns a two element array,
40
- # first is protocol version (SSL_get_version),
41
- # second is 'handshake' state (SSL_state_string)
42
- #
43
- # Used for dropping tcp connections to ssl.
44
- # See OpenSSL ssl/ssl_stat.c SSL_state_string for info
45
- # @!attribute [r] ssl_version_state
46
- # @version 5.0.0
47
- #
48
- def ssl_version_state
49
- IS_JRUBY ? [nil, nil] : @engine.ssl_vers_st
50
- end
51
-
52
- # Used to check the handshake status, in particular when a TCP connection
53
- # is made with TLSv1.3 as an available protocol
54
- # @version 5.0.0
55
- def bad_tlsv1_3?
56
- HAS_TLS1_3 && ssl_version_state == ['TLSv1.3', 'SSLERR']
57
- end
58
- private :bad_tlsv1_3?
59
-
60
- def readpartial(size)
61
- while true
62
- output = @engine.read
63
- return output if output
64
-
65
- data = @socket.readpartial(size)
66
- @engine.inject(data)
67
- output = @engine.read
68
-
69
- return output if output
70
-
71
- while neg_data = @engine.extract
72
- @socket.write neg_data
73
- end
74
- end
75
- end
76
-
77
- def engine_read_all
78
- output = @engine.read
79
- while output and additional_output = @engine.read
80
- output << additional_output
81
- end
82
- output
83
- end
84
-
85
- def read_nonblock(size, *_)
86
- # *_ is to deal with keyword args that were added
87
- # at some point (and being used in the wild)
88
- while true
89
- output = engine_read_all
90
- return output if output
91
-
92
- data = @socket.read_nonblock(size, exception: false)
93
- if data == :wait_readable || data == :wait_writable
94
- # It would make more sense to let @socket.read_nonblock raise
95
- # EAGAIN if necessary but it seems like it'll misbehave on Windows.
96
- # I don't have a Windows machine to debug this so I can't explain
97
- # exactly whats happening in that OS. Please let me know if you
98
- # find out!
99
- #
100
- # In the meantime, we can emulate the correct behavior by
101
- # capturing :wait_readable & :wait_writable and raising EAGAIN
102
- # ourselves.
103
- raise IO::EAGAINWaitReadable
104
- elsif data.nil?
105
- raise SSLError.exception "HTTP connection?" if bad_tlsv1_3?
106
- return nil
107
- end
108
-
109
- @engine.inject(data)
110
- output = engine_read_all
111
-
112
- return output if output
113
-
114
- while neg_data = @engine.extract
115
- @socket.write neg_data
116
- end
117
- end
118
- end
119
-
120
- def write(data)
121
- return 0 if data.empty?
122
-
123
- data_size = data.bytesize
124
- need = data_size
125
-
126
- while true
127
- wrote = @engine.write data
128
-
129
- enc_wr = +''
130
- while (enc = @engine.extract)
131
- enc_wr << enc
132
- end
133
- @socket.write enc_wr unless enc_wr.empty?
134
-
135
- need -= wrote
136
-
137
- return data_size if need == 0
138
-
139
- data = data.byteslice(wrote..-1)
140
- end
141
- end
142
-
143
- alias_method :syswrite, :write
144
- alias_method :<<, :write
145
-
146
- # This is a temporary fix to deal with websockets code using
147
- # write_nonblock.
148
-
149
- # The problem with implementing it properly
150
- # is that it means we'd have to have the ability to rewind
151
- # an engine because after we write+extract, the socket
152
- # write_nonblock call might raise an exception and later
153
- # code would pass the same data in, but the engine would think
154
- # it had already written the data in.
155
- #
156
- # So for the time being (and since write blocking is quite rare),
157
- # go ahead and actually block in write_nonblock.
158
- #
159
- def write_nonblock(data, *_)
160
- write data
161
- end
162
-
163
- def flush
164
- @socket.flush
165
- end
166
-
167
- def close
168
- begin
169
- unless @engine.shutdown
170
- while alert_data = @engine.extract
171
- @socket.write alert_data
172
- end
173
- end
174
- rescue IOError, SystemCallError
175
- Puma::Util.purge_interrupt_queue
176
- # nothing
177
- ensure
178
- @socket.close
179
- end
180
- end
181
-
182
- # @!attribute [r] peeraddr
183
- def peeraddr
184
- @socket.peeraddr
185
- end
186
-
187
- # OpenSSL is loaded in `MiniSSL::ContextBuilder` when
188
- # `MiniSSL::Context#verify_mode` is not `VERIFY_NONE`.
189
- # When `VERIFY_NONE`, `MiniSSL::Engine#peercert` is nil, regardless of
190
- # whether the client sends a cert.
191
- # @return [OpenSSL::X509::Certificate, nil]
192
- # @!attribute [r] peercert
193
- def peercert
194
- return @peercert if @peercert
195
-
196
- raw = @engine.peercert
197
- return nil unless raw
198
-
199
- @peercert = OpenSSL::X509::Certificate.new raw
200
- end
201
- end
202
-
203
- if IS_JRUBY
204
- OPENSSL_NO_SSL3 = false
205
- OPENSSL_NO_TLS1 = false
206
- end
207
-
208
- class Context
209
- attr_accessor :verify_mode
210
- attr_reader :no_tlsv1, :no_tlsv1_1
211
-
212
- def initialize
213
- @no_tlsv1 = false
214
- @no_tlsv1_1 = false
215
- @key = nil
216
- @cert = nil
217
- @key_pem = nil
218
- @cert_pem = nil
219
- @reuse = nil
220
- @reuse_cache_size = nil
221
- @reuse_timeout = nil
222
- end
223
-
224
- def check_file(file, desc)
225
- raise ArgumentError, "#{desc} file '#{file}' does not exist" unless File.exist? file
226
- raise ArgumentError, "#{desc} file '#{file}' is not readable" unless File.readable? file
227
- end
228
-
229
- if IS_JRUBY
230
- # jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
231
- attr_reader :keystore
232
- attr_reader :keystore_type
233
- attr_accessor :keystore_pass
234
- attr_reader :truststore
235
- attr_reader :truststore_type
236
- attr_accessor :truststore_pass
237
- attr_reader :cipher_suites
238
- attr_reader :protocols
239
-
240
- def keystore=(keystore)
241
- check_file keystore, 'Keystore'
242
- @keystore = keystore
243
- end
244
-
245
- def truststore=(truststore)
246
- # NOTE: historically truststore was assumed the same as keystore, this is kept for backwards
247
- # compatibility, to rely on JVM's trust defaults we allow setting `truststore = :default`
248
- unless truststore.eql?(:default)
249
- raise ArgumentError, "No such truststore file '#{truststore}'" unless File.exist?(truststore)
250
- end
251
- @truststore = truststore
252
- end
253
-
254
- def keystore_type=(type)
255
- raise ArgumentError, "Invalid keystore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type)
256
- @keystore_type = type
257
- end
258
-
259
- def truststore_type=(type)
260
- raise ArgumentError, "Invalid truststore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type)
261
- @truststore_type = type
262
- end
263
-
264
- def cipher_suites=(list)
265
- list = list.split(',').map(&:strip) if list.is_a?(String)
266
- @cipher_suites = list
267
- end
268
-
269
- # aliases for backwards compatibility
270
- alias_method :ssl_cipher_list, :cipher_suites
271
- alias_method :ssl_cipher_list=, :cipher_suites=
272
-
273
- def protocols=(list)
274
- list = list.split(',').map(&:strip) if list.is_a?(String)
275
- @protocols = list
276
- end
277
-
278
- def check
279
- raise "Keystore not configured" unless @keystore
280
- # @truststore defaults to @keystore due backwards compatibility
281
- end
282
-
283
- else
284
- # non-jruby Context properties
285
- attr_reader :key
286
- attr_reader :key_password_command
287
- attr_reader :cert
288
- attr_reader :ca
289
- attr_reader :cert_pem
290
- attr_reader :key_pem
291
- attr_accessor :ssl_cipher_filter
292
- attr_accessor :verification_flags
293
-
294
- attr_reader :reuse, :reuse_cache_size, :reuse_timeout
295
-
296
- def key=(key)
297
- check_file key, 'Key'
298
- @key = key
299
- end
300
-
301
- def key_password_command=(key_password_command)
302
- @key_password_command = key_password_command
303
- end
304
-
305
- def cert=(cert)
306
- check_file cert, 'Cert'
307
- @cert = cert
308
- end
309
-
310
- def ca=(ca)
311
- check_file ca, 'ca'
312
- @ca = ca
313
- end
314
-
315
- def cert_pem=(cert_pem)
316
- raise ArgumentError, "'cert_pem' is not a String" unless cert_pem.is_a? String
317
- @cert_pem = cert_pem
318
- end
319
-
320
- def key_pem=(key_pem)
321
- raise ArgumentError, "'key_pem' is not a String" unless key_pem.is_a? String
322
- @key_pem = key_pem
323
- end
324
-
325
- def check
326
- raise "Key not configured" if @key.nil? && @key_pem.nil?
327
- raise "Cert not configured" if @cert.nil? && @cert_pem.nil?
328
- end
329
-
330
- # Executes the command to return the password needed to decrypt the key.
331
- def key_password
332
- raise "Key password command not configured" if @key_password_command.nil?
333
-
334
- stdout_str, stderr_str, status = Open3.capture3(@key_password_command)
335
-
336
- return stdout_str.chomp if status.success?
337
-
338
- raise "Key password failed with code #{status.exitstatus}: #{stderr_str}"
339
- end
340
-
341
- # Controls session reuse. Allowed values are as follows:
342
- # * 'off' - matches the behavior of Puma 5.6 and earlier. This is included
343
- # in case reuse 'on' is made the default in future Puma versions.
344
- # * 'dflt' - sets session reuse on, with OpenSSL default cache size of
345
- # 20k and default timeout of 300 seconds.
346
- # * 's,t' - where s and t are integer strings, for size and timeout.
347
- # * 's' - where s is an integer strings for size.
348
- # * ',t' - where t is an integer strings for timeout.
349
- #
350
- def reuse=(reuse_str)
351
- case reuse_str
352
- when 'off'
353
- @reuse = nil
354
- when 'dflt'
355
- @reuse = true
356
- when /\A\d+\z/
357
- @reuse = true
358
- @reuse_cache_size = reuse_str.to_i
359
- when /\A\d+,\d+\z/
360
- @reuse = true
361
- size, time = reuse_str.split ','
362
- @reuse_cache_size = size.to_i
363
- @reuse_timeout = time.to_i
364
- when /\A,\d+\z/
365
- @reuse = true
366
- @reuse_timeout = reuse_str.delete(',').to_i
367
- end
368
- end
369
- end
370
-
371
- # disables TLSv1
372
- # @!attribute [w] no_tlsv1=
373
- def no_tlsv1=(tlsv1)
374
- raise ArgumentError, "Invalid value of no_tlsv1=" unless ['true', 'false', true, false].include?(tlsv1)
375
- @no_tlsv1 = tlsv1
376
- end
377
-
378
- # disables TLSv1 and TLSv1.1. Overrides `#no_tlsv1=`
379
- # @!attribute [w] no_tlsv1_1=
380
- def no_tlsv1_1=(tlsv1_1)
381
- raise ArgumentError, "Invalid value of no_tlsv1_1=" unless ['true', 'false', true, false].include?(tlsv1_1)
382
- @no_tlsv1_1 = tlsv1_1
383
- end
384
-
385
- end
386
-
387
- VERIFY_NONE = 0
388
- VERIFY_PEER = 1
389
- VERIFY_FAIL_IF_NO_PEER_CERT = 2
390
-
391
- # https://github.com/openssl/openssl/blob/master/include/openssl/x509_vfy.h.in
392
- # /* Certificate verify flags */
393
- VERIFICATION_FLAGS = {
394
- "USE_CHECK_TIME" => 0x2,
395
- "CRL_CHECK" => 0x4,
396
- "CRL_CHECK_ALL" => 0x8,
397
- "IGNORE_CRITICAL" => 0x10,
398
- "X509_STRICT" => 0x20,
399
- "ALLOW_PROXY_CERTS" => 0x40,
400
- "POLICY_CHECK" => 0x80,
401
- "EXPLICIT_POLICY" => 0x100,
402
- "INHIBIT_ANY" => 0x200,
403
- "INHIBIT_MAP" => 0x400,
404
- "NOTIFY_POLICY" => 0x800,
405
- "EXTENDED_CRL_SUPPORT" => 0x1000,
406
- "USE_DELTAS" => 0x2000,
407
- "CHECK_SS_SIGNATURE" => 0x4000,
408
- "TRUSTED_FIRST" => 0x8000,
409
- "SUITEB_128_LOS_ONLY" => 0x10000,
410
- "SUITEB_192_LOS" => 0x20000,
411
- "SUITEB_128_LOS" => 0x30000,
412
- "PARTIAL_CHAIN" => 0x80000,
413
- "NO_ALT_CHAINS" => 0x100000,
414
- "NO_CHECK_TIME" => 0x200000
415
- }.freeze
416
-
417
- class Server
418
- def initialize(socket, ctx)
419
- @socket = socket
420
- @ctx = ctx
421
- @eng_ctx = IS_JRUBY ? @ctx : SSLContext.new(ctx)
422
- end
423
-
424
- def accept
425
- @ctx.check
426
- io = @socket.accept
427
- engine = Engine.server @eng_ctx
428
- Socket.new io, engine
429
- end
430
-
431
- def accept_nonblock
432
- @ctx.check
433
- io = @socket.accept_nonblock
434
- engine = Engine.server @eng_ctx
435
- Socket.new io, engine
436
- end
437
-
438
- # @!attribute [r] to_io
439
- def to_io
440
- @socket
441
- end
442
-
443
- # @!attribute [r] addr
444
- # @version 5.0.0
445
- def addr
446
- @socket.addr
447
- end
448
-
449
- def close
450
- @socket.close unless @socket.closed? # closed? call is for Windows
451
- end
452
-
453
- def closed?
454
- @socket.closed?
455
- end
456
- end
457
- end
458
- end
data/lib/puma/null_io.rb DELETED
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Puma
4
- # Provides an IO-like object that always appears to contain no data.
5
- # Used as the value for rack.input when the request has no body.
6
- #
7
- class NullIO
8
- def gets
9
- nil
10
- end
11
-
12
- def string
13
- ""
14
- end
15
-
16
- def each
17
- end
18
-
19
- # Mimics IO#read with no data.
20
- #
21
- def read(count = nil, _buffer = nil)
22
- count && count > 0 ? nil : ""
23
- end
24
-
25
- def rewind
26
- end
27
-
28
- def close
29
- end
30
-
31
- def size
32
- 0
33
- end
34
-
35
- def eof?
36
- true
37
- end
38
-
39
- def sync
40
- true
41
- end
42
-
43
- def sync=(v)
44
- end
45
-
46
- def puts(*ary)
47
- end
48
-
49
- def write(*ary)
50
- end
51
-
52
- def flush
53
- self
54
- end
55
-
56
- # This is used as singleton class, so can't have state.
57
- def closed?
58
- false
59
- end
60
- end
61
- end
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../plugin'
4
-
5
- # Puma's systemd integration allows Puma to inform systemd:
6
- # 1. when it has successfully started
7
- # 2. when it is starting shutdown
8
- # 3. periodically for a liveness check with a watchdog thread
9
- # 4. periodically set the status
10
- Puma::Plugin.create do
11
- def start(launcher)
12
- require_relative '../sd_notify'
13
-
14
- launcher.log_writer.log "* Enabling systemd notification integration"
15
-
16
- # hook_events
17
- launcher.events.on_booted { Puma::SdNotify.ready }
18
- launcher.events.on_stopped { Puma::SdNotify.stopping }
19
- launcher.events.on_restart { Puma::SdNotify.reloading }
20
-
21
- # start watchdog
22
- if Puma::SdNotify.watchdog?
23
- ping_f = watchdog_sleep_time
24
-
25
- in_background do
26
- launcher.log_writer.log "Pinging systemd watchdog every #{ping_f.round(1)} sec"
27
- loop do
28
- sleep ping_f
29
- Puma::SdNotify.watchdog
30
- end
31
- end
32
- end
33
-
34
- # start status loop
35
- instance = self
36
- sleep_time = 1.0
37
- in_background do
38
- launcher.log_writer.log "Sending status to systemd every #{sleep_time.round(1)} sec"
39
-
40
- loop do
41
- sleep sleep_time
42
- # TODO: error handling?
43
- Puma::SdNotify.status(instance.status)
44
- end
45
- end
46
- end
47
-
48
- def status
49
- if clustered?
50
- messages = stats[:worker_status].map do |worker|
51
- common_message(worker[:last_status])
52
- end.join(',')
53
-
54
- "Puma #{Puma::Const::VERSION}: cluster: #{booted_workers}/#{workers}, worker_status: [#{messages}]"
55
- else
56
- "Puma #{Puma::Const::VERSION}: worker: #{common_message(stats)}"
57
- end
58
- end
59
-
60
- private
61
-
62
- def watchdog_sleep_time
63
- usec = Integer(ENV["WATCHDOG_USEC"])
64
-
65
- sec_f = usec / 1_000_000.0
66
- # "It is recommended that a daemon sends a keep-alive notification message
67
- # to the service manager every half of the time returned here."
68
- sec_f / 2
69
- end
70
-
71
- def stats
72
- Puma.stats_hash
73
- end
74
-
75
- def clustered?
76
- stats.has_key?(:workers)
77
- end
78
-
79
- def workers
80
- stats.fetch(:workers, 1)
81
- end
82
-
83
- def booted_workers
84
- stats.fetch(:booted_workers, 1)
85
- end
86
-
87
- def common_message(stats)
88
- "{ #{stats[:running]}/#{stats[:max_threads]} threads, #{stats[:pool_capacity]} available, #{stats[:backlog]} backlog }"
89
- end
90
- end