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,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../plugin'
4
-
5
- Puma::Plugin.create do
6
- def start(launcher)
7
- path = File.join("tmp", "restart.txt")
8
-
9
- orig = nil
10
-
11
- # If we can't write to the path, then just don't bother with this plugin
12
- begin
13
- File.write(path, "") unless File.exist?(path)
14
- orig = File.stat(path).mtime
15
- rescue SystemCallError
16
- return
17
- end
18
-
19
- in_background do
20
- while true
21
- sleep 2
22
-
23
- begin
24
- mtime = File.stat(path).mtime
25
- rescue SystemCallError
26
- # If the file has disappeared, assume that means don't restart
27
- else
28
- if mtime > orig
29
- launcher.restart
30
- break
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
data/lib/puma/plugin.rb DELETED
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Puma
4
- class UnknownPlugin < RuntimeError; end
5
-
6
- class PluginLoader
7
- def initialize
8
- @instances = []
9
- end
10
-
11
- def create(name)
12
- if cls = Plugins.find(name)
13
- plugin = cls.new
14
- @instances << plugin
15
- return plugin
16
- end
17
-
18
- raise UnknownPlugin, "File failed to register properly named plugin"
19
- end
20
-
21
- def fire_starts(launcher)
22
- @instances.each do |i|
23
- if i.respond_to? :start
24
- i.start(launcher)
25
- end
26
- end
27
- end
28
- end
29
-
30
- class PluginRegistry
31
- def initialize
32
- @plugins = {}
33
- @background = []
34
- end
35
-
36
- def register(name, cls)
37
- @plugins[name] = cls
38
- end
39
-
40
- def find(name)
41
- name = name.to_s
42
-
43
- if cls = @plugins[name]
44
- return cls
45
- end
46
-
47
- begin
48
- require "puma/plugin/#{name}"
49
- rescue LoadError
50
- raise UnknownPlugin, "Unable to find plugin: #{name}"
51
- end
52
-
53
- if cls = @plugins[name]
54
- return cls
55
- end
56
-
57
- raise UnknownPlugin, "file failed to register a plugin"
58
- end
59
-
60
- def add_background(blk)
61
- @background << blk
62
- end
63
-
64
- def fire_background
65
- @background.each_with_index do |b, i|
66
- Thread.new do
67
- Puma.set_thread_name "plgn bg #{i}"
68
- b.call
69
- end
70
- end
71
- end
72
- end
73
-
74
- Plugins = PluginRegistry.new
75
-
76
- class Plugin
77
- # Matches
78
- # "C:/Ruby22/lib/ruby/gems/2.2.0/gems/puma-3.0.1/lib/puma/plugin/tmp_restart.rb:3:in `<top (required)>'"
79
- # AS
80
- # C:/Ruby22/lib/ruby/gems/2.2.0/gems/puma-3.0.1/lib/puma/plugin/tmp_restart.rb
81
- CALLER_FILE = /
82
- \A # start of string
83
- .+ # file path (one or more characters)
84
- (?= # stop previous match when
85
- :\d+ # a colon is followed by one or more digits
86
- :in # followed by a colon followed by in
87
- )
88
- /x
89
-
90
- def self.extract_name(ary)
91
- path = ary.first[CALLER_FILE]
92
-
93
- m = %r!puma/plugin/([^/]*)\.rb$!.match(path)
94
- m[1]
95
- end
96
-
97
- def self.create(&blk)
98
- name = extract_name(caller)
99
-
100
- cls = Class.new(self)
101
-
102
- cls.class_eval(&blk)
103
-
104
- Plugins.register name, cls
105
- end
106
-
107
- def in_background(&blk)
108
- Plugins.add_background blk
109
- end
110
- end
111
- end
@@ -1,297 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Puma
4
- end
5
-
6
- module Puma::Rack
7
- class Options
8
- def parse!(args)
9
- options = {}
10
- opt_parser = OptionParser.new("", 24, ' ') do |opts|
11
- opts.banner = "Usage: rackup [ruby options] [rack options] [rackup config]"
12
-
13
- opts.separator ""
14
- opts.separator "Ruby options:"
15
-
16
- lineno = 1
17
- opts.on("-e", "--eval LINE", "evaluate a LINE of code") { |line|
18
- eval line, TOPLEVEL_BINDING, "-e", lineno
19
- lineno += 1
20
- }
21
-
22
- opts.on("-b", "--builder BUILDER_LINE", "evaluate a BUILDER_LINE of code as a builder script") { |line|
23
- options[:builder] = line
24
- }
25
-
26
- opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
27
- options[:debug] = true
28
- }
29
- opts.on("-w", "--warn", "turn warnings on for your script") {
30
- options[:warn] = true
31
- }
32
- opts.on("-q", "--quiet", "turn off logging") {
33
- options[:quiet] = true
34
- }
35
-
36
- opts.on("-I", "--include PATH",
37
- "specify $LOAD_PATH (may be used more than once)") { |path|
38
- (options[:include] ||= []).concat(path.split(":"))
39
- }
40
-
41
- opts.on("-r", "--require LIBRARY",
42
- "require the library, before executing your script") { |library|
43
- options[:require] = library
44
- }
45
-
46
- opts.separator ""
47
- opts.separator "Rack options:"
48
- opts.on("-s", "--server SERVER", "serve using SERVER (thin/puma/webrick/mongrel)") { |s|
49
- options[:server] = s
50
- }
51
-
52
- opts.on("-o", "--host HOST", "listen on HOST (default: localhost)") { |host|
53
- options[:Host] = host
54
- }
55
-
56
- opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port|
57
- options[:Port] = port
58
- }
59
-
60
- opts.on("-O", "--option NAME[=VALUE]", "pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run '#{$0} -s SERVER -h' to get a list of options for SERVER") { |name|
61
- name, value = name.split('=', 2)
62
- value = true if value.nil?
63
- options[name.to_sym] = value
64
- }
65
-
66
- opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e|
67
- options[:environment] = e
68
- }
69
-
70
- opts.on("-P", "--pid FILE", "file to store PID") { |f|
71
- options[:pid] = ::File.expand_path(f)
72
- }
73
-
74
- opts.separator ""
75
- opts.separator "Common options:"
76
-
77
- opts.on_tail("-h", "-?", "--help", "Show this message") do
78
- puts opts
79
- puts handler_opts(options)
80
-
81
- exit
82
- end
83
-
84
- opts.on_tail("--version", "Show version") do
85
- puts "Rack #{Rack.version} (Release: #{Rack.release})"
86
- exit
87
- end
88
- end
89
-
90
- begin
91
- opt_parser.parse! args
92
- rescue OptionParser::InvalidOption => e
93
- warn e.message
94
- abort opt_parser.to_s
95
- end
96
-
97
- options[:config] = args.last if args.last
98
- options
99
- end
100
-
101
- def handler_opts(options)
102
- begin
103
- info = []
104
- server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
105
- if server&.respond_to?(:valid_options)
106
- info << ""
107
- info << "Server-specific options for #{server.name}:"
108
-
109
- has_options = false
110
- server.valid_options.each do |name, description|
111
- next if /^(Host|Port)[^a-zA-Z]/.match? name.to_s # ignore handler's host and port options, we do our own.
112
-
113
- info << " -O %-21s %s" % [name, description]
114
- has_options = true
115
- end
116
- return "" if !has_options
117
- end
118
- info.join("\n")
119
- rescue NameError
120
- return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options"
121
- end
122
- end
123
- end
124
-
125
- # Rack::Builder implements a small DSL to iteratively construct Rack
126
- # applications.
127
- #
128
- # Example:
129
- #
130
- # require 'rack/lobster'
131
- # app = Rack::Builder.new do
132
- # use Rack::CommonLogger
133
- # use Rack::ShowExceptions
134
- # map "/lobster" do
135
- # use Rack::Lint
136
- # run Rack::Lobster.new
137
- # end
138
- # end
139
- #
140
- # run app
141
- #
142
- # Or
143
- #
144
- # app = Rack::Builder.app do
145
- # use Rack::CommonLogger
146
- # run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
147
- # end
148
- #
149
- # run app
150
- #
151
- # +use+ adds middleware to the stack, +run+ dispatches to an application.
152
- # You can use +map+ to construct a Rack::URLMap in a convenient way.
153
-
154
- class Builder
155
- def self.parse_file(config, opts = Options.new)
156
- options = {}
157
- if config =~ /\.ru$/
158
- cfgfile = ::File.read(config)
159
- if cfgfile[/^#\\(.*)/] && opts
160
- options = opts.parse! $1.split(/\s+/)
161
- end
162
- cfgfile.sub!(/^__END__\n.*\Z/m, '')
163
- app = new_from_string cfgfile, config
164
- else
165
- require config
166
- app = Object.const_get(::File.basename(config, '.rb').capitalize)
167
- end
168
- [app, options]
169
- end
170
-
171
- def self.new_from_string(builder_script, file="(rackup)")
172
- eval "Puma::Rack::Builder.new {\n" + builder_script + "\n}.to_app",
173
- TOPLEVEL_BINDING, file, 0
174
- end
175
-
176
- def initialize(default_app = nil, &block)
177
- @use, @map, @run, @warmup = [], nil, default_app, nil
178
-
179
- # Conditionally load rack now, so that any rack middlewares,
180
- # etc are available.
181
- begin
182
- require 'rack'
183
- rescue LoadError
184
- end
185
-
186
- instance_eval(&block) if block
187
- end
188
-
189
- def self.app(default_app = nil, &block)
190
- self.new(default_app, &block).to_app
191
- end
192
-
193
- # Specifies middleware to use in a stack.
194
- #
195
- # class Middleware
196
- # def initialize(app)
197
- # @app = app
198
- # end
199
- #
200
- # def call(env)
201
- # env["rack.some_header"] = "setting an example"
202
- # @app.call(env)
203
- # end
204
- # end
205
- #
206
- # use Middleware
207
- # run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
208
- #
209
- # All requests through to this application will first be processed by the middleware class.
210
- # The +call+ method in this example sets an additional environment key which then can be
211
- # referenced in the application if required.
212
- def use(middleware, *args, &block)
213
- if @map
214
- mapping, @map = @map, nil
215
- @use << proc { |app| generate_map app, mapping }
216
- end
217
- @use << proc { |app| middleware.new(app, *args, &block) }
218
- end
219
-
220
- # Takes an argument that is an object that responds to #call and returns a Rack response.
221
- # The simplest form of this is a lambda object:
222
- #
223
- # run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
224
- #
225
- # However this could also be a class:
226
- #
227
- # class Heartbeat
228
- # def self.call(env)
229
- # [200, { "Content-Type" => "text/plain" }, ["OK"]]
230
- # end
231
- # end
232
- #
233
- # run Heartbeat
234
- def run(app)
235
- @run = app
236
- end
237
-
238
- # Takes a lambda or block that is used to warm-up the application.
239
- #
240
- # warmup do |app|
241
- # client = Rack::MockRequest.new(app)
242
- # client.get('/')
243
- # end
244
- #
245
- # use SomeMiddleware
246
- # run MyApp
247
- def warmup(prc=nil, &block)
248
- @warmup = prc || block
249
- end
250
-
251
- # Creates a route within the application.
252
- #
253
- # Rack::Builder.app do
254
- # map '/' do
255
- # run Heartbeat
256
- # end
257
- # end
258
- #
259
- # The +use+ method can also be used here to specify middleware to run under a specific path:
260
- #
261
- # Rack::Builder.app do
262
- # map '/' do
263
- # use Middleware
264
- # run Heartbeat
265
- # end
266
- # end
267
- #
268
- # This example includes a piece of middleware which will run before requests hit +Heartbeat+.
269
- #
270
- def map(path, &block)
271
- @map ||= {}
272
- @map[path] = block
273
- end
274
-
275
- def to_app
276
- app = @map ? generate_map(@run, @map) : @run
277
- fail "missing run or map statement" unless app
278
- app = @use.reverse.inject(app) { |a,e| e[a] }
279
- @warmup&.call app
280
- app
281
- end
282
-
283
- def call(env)
284
- to_app.call(env)
285
- end
286
-
287
- private
288
-
289
- def generate_map(default_app, mapping)
290
- require_relative 'urlmap'
291
-
292
- mapped = default_app ? {'/' => default_app} : {}
293
- mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b).to_app }
294
- URLMap.new(mapped)
295
- end
296
- end
297
- end
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Puma::Rack
4
- # Rack::URLMap takes a hash mapping urls or paths to apps, and
5
- # dispatches accordingly. Support for HTTP/1.1 host names exists if
6
- # the URLs start with <tt>http://</tt> or <tt>https://</tt>.
7
- #
8
- # URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part
9
- # relevant for dispatch is in the SCRIPT_NAME, and the rest in the
10
- # PATH_INFO. This should be taken care of when you need to
11
- # reconstruct the URL in order to create links.
12
- #
13
- # URLMap dispatches in such a way that the longest paths are tried
14
- # first, since they are most specific.
15
-
16
- class URLMap
17
- NEGATIVE_INFINITY = -1.0 / 0.0
18
- INFINITY = 1.0 / 0.0
19
-
20
- def initialize(map = {})
21
- remap(map)
22
- end
23
-
24
- def remap(map)
25
- @mapping = map.map { |location, app|
26
- if location =~ %r{\Ahttps?://(.*?)(/.*)}
27
- host, location = $1, $2
28
- else
29
- host = nil
30
- end
31
-
32
- unless location[0] == ?/
33
- raise ArgumentError, "paths need to start with /"
34
- end
35
-
36
- location = location.chomp('/')
37
- match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", Regexp::NOENCODING)
38
-
39
- [host, location, match, app]
40
- }.sort_by do |(host, location, _, _)|
41
- [host ? -host.size : INFINITY, -location.size]
42
- end
43
- end
44
-
45
- def call(env)
46
- path = env['PATH_INFO']
47
- script_name = env['SCRIPT_NAME']
48
- http_host = env['HTTP_HOST']
49
- server_name = env['SERVER_NAME']
50
- server_port = env['SERVER_PORT']
51
-
52
- is_same_server = casecmp?(http_host, server_name) ||
53
- casecmp?(http_host, "#{server_name}:#{server_port}")
54
-
55
- @mapping.each do |host, location, match, app|
56
- unless casecmp?(http_host, host) \
57
- || casecmp?(server_name, host) \
58
- || (!host && is_same_server)
59
- next
60
- end
61
-
62
- next unless m = match.match(path.to_s)
63
-
64
- rest = m[1]
65
- next unless !rest || rest.empty? || rest[0] == ?/
66
-
67
- env['SCRIPT_NAME'] = (script_name + location)
68
- env['PATH_INFO'] = rest
69
-
70
- return app.call(env)
71
- end
72
-
73
- [404, {'Content-Type' => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]]
74
-
75
- ensure
76
- env['PATH_INFO'] = path
77
- env['SCRIPT_NAME'] = script_name
78
- end
79
-
80
- private
81
- def casecmp?(v1, v2)
82
- # if both nil, or they're the same string
83
- return true if v1 == v2
84
-
85
- # if either are nil... (but they're not the same)
86
- return false if v1.nil?
87
- return false if v2.nil?
88
-
89
- # otherwise check they're not case-insensitive the same
90
- v1.casecmp(v2).zero?
91
- end
92
- end
93
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../rack/handler/puma'
4
-
5
- # rackup was removed in Rack 3, it is now a separate gem
6
- if Object.const_defined? :Rackup
7
- module Rackup
8
- module Handler
9
- def self.default(options = {})
10
- ::Rackup::Handler::Puma
11
- end
12
- end
13
- end
14
- elsif Object.const_defined?(:Rack) && Rack.release < '3'
15
- module Rack
16
- module Handler
17
- def self.default(options = {})
18
- ::Rack::Handler::Puma
19
- end
20
- end
21
- end
22
- else
23
- raise "Rack 3 must be used with the Rackup gem"
24
- end
data/lib/puma/reactor.rb DELETED
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Puma
4
- class UnsupportedBackend < StandardError; end
5
-
6
- # Monitors a collection of IO objects, calling a block whenever
7
- # any monitored object either receives data or times out, or when the Reactor shuts down.
8
- #
9
- # The waiting/wake up is performed with nio4r, which will use the appropriate backend (libev,
10
- # Java NIO or just plain IO#select). The call to `NIO::Selector#select` will
11
- # 'wakeup' any IO object that receives data.
12
- #
13
- # This class additionally tracks a timeout for every added object,
14
- # and wakes up any object when its timeout elapses.
15
- #
16
- # The implementation uses a Queue to synchronize adding new objects from the internal select loop.
17
- class Reactor
18
- # Create a new Reactor to monitor IO objects added by #add.
19
- # The provided block will be invoked when an IO has data available to read,
20
- # its timeout elapses, or when the Reactor shuts down.
21
- def initialize(backend, &block)
22
- require 'nio'
23
- valid_backends = [:auto, *::NIO::Selector.backends]
24
- unless valid_backends.include?(backend)
25
- raise ArgumentError.new("unsupported IO selector backend: #{backend} (available backends: #{valid_backends.join(', ')})")
26
- end
27
-
28
- @selector = ::NIO::Selector.new(NIO::Selector.backends.delete(backend))
29
- @input = Queue.new
30
- @timeouts = []
31
- @block = block
32
- end
33
-
34
- # Run the internal select loop, using a background thread by default.
35
- def run(background=true)
36
- if background
37
- @thread = Thread.new do
38
- Puma.set_thread_name "reactor"
39
- select_loop
40
- end
41
- else
42
- select_loop
43
- end
44
- end
45
-
46
- # Add a new client to monitor.
47
- # The object must respond to #timeout and #timeout_at.
48
- # Returns false if the reactor is already shut down.
49
- def add(client)
50
- @input << client
51
- @selector.wakeup
52
- true
53
- rescue ClosedQueueError, IOError # Ignore if selector is already closed
54
- false
55
- end
56
-
57
- # Shutdown the reactor, blocking until the background thread is finished.
58
- def shutdown
59
- @input.close
60
- begin
61
- @selector.wakeup
62
- rescue IOError # Ignore if selector is already closed
63
- end
64
- @thread&.join
65
- end
66
-
67
- private
68
-
69
- def select_loop
70
- close_selector = true
71
- begin
72
- until @input.closed? && @input.empty?
73
- # Wakeup any registered object that receives incoming data.
74
- # Block until the earliest timeout or Selector#wakeup is called.
75
- timeout = (earliest = @timeouts.first) && earliest.timeout
76
- @selector.select(timeout) {|mon| wakeup!(mon.value)}
77
-
78
- # Wakeup all objects that timed out.
79
- timed_out = @timeouts.take_while {|t| t.timeout == 0}
80
- timed_out.each { |c| wakeup! c }
81
-
82
- unless @input.empty?
83
- until @input.empty?
84
- client = @input.pop
85
- register(client) if client.io_ok?
86
- end
87
- @timeouts.sort_by!(&:timeout_at)
88
- end
89
- end
90
- rescue StandardError => e
91
- STDERR.puts "Error in reactor loop escaped: #{e.message} (#{e.class})"
92
- STDERR.puts e.backtrace
93
-
94
- # NoMethodError may be rarely raised when calling @selector.select, which
95
- # is odd. Regardless, it may continue for thousands of calls if retried.
96
- # Also, when it raises, @selector.close also raises an error.
97
- if NoMethodError === e
98
- close_selector = false
99
- else
100
- retry
101
- end
102
- end
103
- # Wakeup all remaining objects on shutdown.
104
- @timeouts.each(&@block)
105
- @selector.close if close_selector
106
- end
107
-
108
- # Start monitoring the object.
109
- def register(client)
110
- @selector.register(client.to_io, :r).value = client
111
- @timeouts << client
112
- rescue ArgumentError
113
- # unreadable clients raise error when processed by NIO
114
- end
115
-
116
- # 'Wake up' a monitored object by calling the provided block.
117
- # Stop monitoring the object if the block returns `true`.
118
- def wakeup!(client)
119
- if @block.call client
120
- @selector.deregister client.to_io
121
- @timeouts.delete client
122
- end
123
- end
124
- end
125
- end