async 1.16.0 → 1.17.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d32f66a08662551d096e73d45b968db7ba3c1faac364dd30a6727e6b987fc060
4
- data.tar.gz: daaecb80e3223b8fbd31798c6d45f8c7a03ec45544fceea966ffd1cdc075264a
3
+ metadata.gz: 1465ddfc74436e5ec289b69f97b4bb5993ef7bd6ceae9e55d79b8b2f78051829
4
+ data.tar.gz: 1dc342eed7d35d47f0a3ada58b03280a9702fd7307d604d33c3d97f976d398ed
5
5
  SHA512:
6
- metadata.gz: 138843f67fa5d3d700a64d034d8ca70b826f26d48392e2f7bfd404bc77d6045ee7c492f823fb33263a1896a03988e57f9d6d0ba78c6ce7ab48ba48ee29a9460a
7
- data.tar.gz: 3040bffa50775ca7fa3fde5dd1a6d6c4cde77ffcfd079fddc5118310ff9cf0057842b1525b8c9c0ec1b07192af56baf20e6298efaa359b2bb2c0e55bed948e5a
6
+ metadata.gz: bfb65f1ad102472c48e32702294e913285681c0bb3f661571ea00a83bf0a52e2e062deee33ffb18e359199ae287e4022c731032a48125815c7815d6c485dc44f
7
+ data.tar.gz: 7631a181a45af7ca658c4d8a65b3f1d029fc5ce7fba6c730680ca2fb0c7a462a8477f16d614b261b199fa1e7d2925ece05e4f5d94de45074c11c4789a8825aca
@@ -20,6 +20,8 @@ matrix:
20
20
  - rvm: 2.4
21
21
  - rvm: 2.5
22
22
  - rvm: 2.6
23
+ - rvm: 2.6
24
+ gemfile: gems/event.gemfile
23
25
  - rvm: 2.6
24
26
  env: COVERAGE=PartialSummary,Coveralls
25
27
  - rvm: jruby-head
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_runtime_dependency "nio4r", "~> 2.3"
26
26
  spec.add_runtime_dependency "timers", "~> 4.1"
27
- spec.add_runtime_dependency "event", "~> 1.1"
27
+ spec.add_runtime_dependency "event", "~> 1.3"
28
28
 
29
29
  spec.add_development_dependency "async-rspec", "~> 1.1"
30
30
 
@@ -0,0 +1,4 @@
1
+
2
+ eval_gemfile("../Gemfile")
3
+
4
+ gem 'event', '~> 1.1'
@@ -19,7 +19,13 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  require 'event/console'
22
+ require_relative 'task'
22
23
 
23
24
  module Async
24
- extend Event::Console
25
+ # @return the current logger, either the active tasks logger, or the global event console logger.
26
+ def self.logger
27
+ if task = Task.current?
28
+ task.logger
29
+ end || Event::Console.logger
30
+ end
25
31
  end
@@ -42,13 +42,13 @@ module Async
42
42
  # - When invoked at the top level, will create and run a reactor, and invoke
43
43
  # the block as an asynchronous task. Will block until the reactor finishes
44
44
  # running.
45
- def self.run(*args, &block)
45
+ def self.run(*args, **options, &block)
46
46
  if current = Task.current?
47
47
  reactor = current.reactor
48
48
 
49
- return reactor.async(*args, &block)
49
+ return reactor.async(*args, **options, &block)
50
50
  else
51
- reactor = self.new
51
+ reactor = self.new(**options)
52
52
 
53
53
  begin
54
54
  return reactor.run(*args, &block)
@@ -58,11 +58,12 @@ module Async
58
58
  end
59
59
  end
60
60
 
61
- def initialize(parent = nil, selector: NIO::Selector.new)
61
+ def initialize(parent = nil, selector: NIO::Selector.new, logger: nil)
62
62
  super(parent)
63
63
 
64
64
  @selector = selector
65
65
  @timers = Timers::Group.new
66
+ @logger = logger
66
67
 
67
68
  @ready = []
68
69
  @running = []
@@ -70,6 +71,10 @@ module Async
70
71
  @stopped = true
71
72
  end
72
73
 
74
+ def logger
75
+ @logger ||= Event::Console.logger
76
+ end
77
+
73
78
  def to_s
74
79
  "<#{self.description} stopped=#{@stopped}>"
75
80
  end
@@ -91,8 +96,8 @@ module Async
91
96
  #
92
97
  # @yield [Task] Executed within the task.
93
98
  # @return [Task] The task that was scheduled into the reactor.
94
- def async(*args, &block)
95
- task = Task.new(self, &block)
99
+ def async(*args, **options, &block)
100
+ task = Task.new(self, **options, &block)
96
101
 
97
102
  # I want to take a moment to explain the logic of this.
98
103
  # When calling an async block, we deterministically execute it until the
@@ -103,7 +108,7 @@ module Async
103
108
  # - Avoid overhead if no blocking operation is performed.
104
109
  task.run(*args)
105
110
 
106
- # Async.logger.debug "Initial execution of task #{fiber} complete (#{result} -> #{fiber.alive?})..."
111
+ # logger.debug "Initial execution of task #{fiber} complete (#{result} -> #{fiber.alive?})..."
107
112
  return task
108
113
  end
109
114
 
@@ -175,7 +180,7 @@ module Async
175
180
  interval = 0
176
181
  end
177
182
 
178
- # Async.logger.debug(self) {"Updating #{@children.count} children..."}
183
+ # logger.debug(self) {"Updating #{@children.count} children..."}
179
184
  # As timeouts may have been updated, and caused fibers to complete, we should check this.
180
185
 
181
186
  # If there is nothing to do, then finish:
@@ -183,7 +188,7 @@ module Async
183
188
  return initial_task
184
189
  end
185
190
 
186
- # Async.logger.debug(self) {"Selecting with #{@children.count} fibers interval = #{interval.inspect}..."}
191
+ # logger.debug(self) {"Selecting with #{@children.count} fibers interval = #{interval.inspect}..."}
187
192
  if monitors = @selector.select(interval)
188
193
  monitors.each do |monitor|
189
194
  monitor.value.resume
@@ -193,7 +198,7 @@ module Async
193
198
 
194
199
  return initial_task
195
200
  ensure
196
- Async.logger.debug(self) {"Exiting run-loop because #{$! ? $! : 'finished'}."}
201
+ logger.debug(self) {"Exiting run-loop because #{$! ? $! : 'finished'}."}
197
202
 
198
203
  @stopped = true
199
204
  end
@@ -57,8 +57,7 @@ module Async
57
57
  # Create a new task.
58
58
  # @param reactor [Async::Reactor] the reactor this task will run within.
59
59
  # @param parent [Async::Task] the parent task.
60
- # @param propagate_exceptions [Boolean] whether exceptions raised in the task will propagate up the reactor stack.
61
- def initialize(reactor, parent = Task.current?, &block)
60
+ def initialize(reactor, parent = Task.current?, logger: nil, &block)
62
61
  super(parent || reactor)
63
62
 
64
63
  @reactor = reactor
@@ -67,6 +66,8 @@ module Async
67
66
  @result = nil
68
67
  @finished = nil
69
68
 
69
+ @logger = logger
70
+
70
71
  @fiber = make_fiber(&block)
71
72
  end
72
73
 
@@ -74,6 +75,10 @@ module Async
74
75
  "<#{self.description} #{@status}>"
75
76
  end
76
77
 
78
+ def logger
79
+ @logger ||= @parent&.logger
80
+ end
81
+
77
82
  # @attr ios [Reactor] The reactor the task was created within.
78
83
  attr :reactor
79
84
  def_delegators :@reactor, :with_timeout, :timeout, :sleep
@@ -100,8 +105,8 @@ module Async
100
105
  end
101
106
  end
102
107
 
103
- def async(*args, &block)
104
- task = Task.new(@reactor, self, &block)
108
+ def async(*args, **options, &block)
109
+ task = Task.new(@reactor, self, **options, &block)
105
110
 
106
111
  task.run(*args)
107
112
 
@@ -181,9 +186,9 @@ module Async
181
186
  raise
182
187
  elsif @finished.nil?
183
188
  # If no one has called wait, we log this as an error:
184
- Async.logger.error(self) {$!}
189
+ logger.error(self) {$!}
185
190
  else
186
- Async.logger.debug(self) {$!}
191
+ logger.debug(self) {$!}
187
192
  end
188
193
  end
189
194
 
@@ -198,7 +203,7 @@ module Async
198
203
  begin
199
204
  @result = yield(self, *args)
200
205
  @status = :complete
201
- # Async.logger.debug("Task #{self} completed normally.")
206
+ # logger.debug("Task #{self} completed normally.")
202
207
  rescue Stop
203
208
  stop!
204
209
  rescue StandardError => error
@@ -206,7 +211,7 @@ module Async
206
211
  rescue Exception => exception
207
212
  fail!(exception, true)
208
213
  ensure
209
- # Async.logger.debug("Task #{self} closing: #{$!}")
214
+ # logger.debug("Task #{self} closing: #{$!}")
210
215
  finish!
211
216
  end
212
217
  end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Async
22
- VERSION = "1.16.0"
22
+ VERSION = "1.17.0"
23
23
  end
@@ -0,0 +1,63 @@
1
+ # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'async'
22
+ require 'async/logger'
23
+ require 'event/capture'
24
+
25
+ RSpec.describe 'Async.logger' do
26
+ let(:name) {"nested"}
27
+ let(:message) {"Talk is cheap. Show me the code."}
28
+
29
+ let(:capture) {Event::Capture.new}
30
+ let(:logger) {Event::Logger.new(capture, name: name)}
31
+
32
+ it "can use nested logger" do
33
+ Async(logger: logger) do |task|
34
+ expect(task.logger).to be == logger
35
+ logger.warn message
36
+ end.wait
37
+
38
+ expect(capture.events.last).to include({
39
+ severity: :warn,
40
+ name: name,
41
+ subject: message,
42
+ })
43
+ end
44
+
45
+ it "can change nested logger" do
46
+ Async do |parent|
47
+ parent.async(logger: logger) do |task|
48
+ expect(task.logger).to be == logger
49
+ expect(Async.logger).to be == logger
50
+ end.wait
51
+ end.wait
52
+ end
53
+
54
+ it "can use parent logger" do
55
+ Async(logger: logger) do |parent|
56
+ child = parent.async{|task| task.yield}
57
+
58
+ expect(parent.logger).to be == logger
59
+ expect(child.logger).to be == logger
60
+ expect(Async.logger).to be == logger
61
+ end.wait
62
+ end
63
+ end
@@ -86,7 +86,7 @@ RSpec.describe Async::Task do
86
86
  task = nil
87
87
 
88
88
  expect do
89
- task = reactor.async(propagate_exceptions: false) do |task|
89
+ task = reactor.async do |task|
90
90
  raise "boom"
91
91
  end
92
92
  end.to_not raise_exception
@@ -98,7 +98,7 @@ RSpec.describe Async::Task do
98
98
 
99
99
  it "won't consume non-StandardError exceptions" do
100
100
  expect do
101
- reactor.async(propagate_exceptions: false) do |task|
101
+ reactor.async do |task|
102
102
  raise SignalException.new(:TERM)
103
103
  end
104
104
  end.to raise_exception(SignalException, /TERM/)
@@ -300,7 +300,7 @@ RSpec.describe Async::Task do
300
300
  it "will raise exceptions when checking result" do
301
301
  error_task = nil
302
302
 
303
- error_task = reactor.async(propagate_exceptions: false) do |task|
303
+ error_task = reactor.async do |task|
304
304
  raise RuntimeError, "brain not provided"
305
305
  end
306
306
 
@@ -312,7 +312,7 @@ RSpec.describe Async::Task do
312
312
  it "will propagate exceptions after async operation" do
313
313
  error_task = nil
314
314
 
315
- error_task = reactor.async(propagate_exceptions: false) do |task|
315
+ error_task = reactor.async do |task|
316
316
  task.sleep(0.1)
317
317
 
318
318
  raise "boom"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.0
4
+ version: 1.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-14 00:00:00.000000000 Z
11
+ date: 2019-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nio4r
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.1'
47
+ version: '1.3'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.1'
54
+ version: '1.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: async-rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -146,6 +146,7 @@ files:
146
146
  - examples/callback/loop.rb
147
147
  - examples/fibers.rb
148
148
  - examples/sleep_sort.rb
149
+ - gems/event.gemfile
149
150
  - lib/async.rb
150
151
  - lib/async/clock.rb
151
152
  - lib/async/condition.rb
@@ -167,6 +168,7 @@ files:
167
168
  - spec/async/clock_spec.rb
168
169
  - spec/async/condition_examples.rb
169
170
  - spec/async/condition_spec.rb
171
+ - spec/async/logger_spec.rb
170
172
  - spec/async/node_spec.rb
171
173
  - spec/async/notification_spec.rb
172
174
  - spec/async/performance_spec.rb
@@ -197,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
199
  - !ruby/object:Gem::Version
198
200
  version: '0'
199
201
  requirements: []
200
- rubygems_version: 3.0.2
202
+ rubygems_version: 3.0.3
201
203
  signing_key:
202
204
  specification_version: 4
203
205
  summary: Async is an asynchronous I/O framework based on nio4r.
@@ -205,6 +207,7 @@ test_files:
205
207
  - spec/async/clock_spec.rb
206
208
  - spec/async/condition_examples.rb
207
209
  - spec/async/condition_spec.rb
210
+ - spec/async/logger_spec.rb
208
211
  - spec/async/node_spec.rb
209
212
  - spec/async/notification_spec.rb
210
213
  - spec/async/performance_spec.rb