async 1.26.2 → 1.27.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72c4f7456b611f436a18f0d143ba5b4c9bb4c7882ad241f3ba251a139c020945
4
- data.tar.gz: 4270eef8e1de0d08b953eb373a665d3fb8c0b9348e13d99ac6c61e7aead63db5
3
+ metadata.gz: 1d1048beb05a88fed1922f32624f61bf5ed8b1e70c2bd9b0e0c17bfad60aa359
4
+ data.tar.gz: 0eb19742b401a5ffb95286c766cf68e3159e3b94f57b8fd4272f1038c5dabc00
5
5
  SHA512:
6
- metadata.gz: 359f4bcd33b438eca0518a00b77d336c25ab49ed3346180013bc135743d9a5447c178416680e5289085cbd9d75718772d7a06e25d44a0b0303cd35086da0c8f5
7
- data.tar.gz: 420f280a2ed6d2cb4d363c6a4f80a695a1ad963ead1b040daa16ce9a18ceab9b8f3f6bcee707658a946acba3656f54578df9ed36e2bf8ffc0e6d151cdbbc9e9e
6
+ metadata.gz: 9c21be88e7a5eea9e6a0380f49eabd47e06522e204b61bb97fc9085053c3e800182a51a83cec001a1bc8533a3f3ff48d1cb1b0987aa15587fbb53ea9209777b6
7
+ data.tar.gz: 79ed71d369b9bda125239835befe60d2842f33e0cd3ed3b6ebadbf996dccf43cc2605b33119ceaf4ac8bb0e602671efb06665660c20e2702f983cb6a8459208c
@@ -21,7 +21,7 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Async
24
- module Clock
24
+ class Clock
25
25
  # Get the current elapsed monotonic time.
26
26
  def self.now
27
27
  ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
@@ -35,5 +35,37 @@ module Async
35
35
 
36
36
  return self.now - start_time
37
37
  end
38
+
39
+ def self.start
40
+ self.new.tap(&:start!)
41
+ end
42
+
43
+ def initialize(total = 0)
44
+ @total = total
45
+ @started = nil
46
+ end
47
+
48
+ def start!
49
+ @started ||= Clock.now
50
+ end
51
+
52
+ def stop!
53
+ if @started
54
+ @total += (Clock.now - @started)
55
+ @started = nil
56
+ end
57
+
58
+ return @total
59
+ end
60
+
61
+ def total
62
+ total = @total
63
+
64
+ if @started
65
+ total += (Clock.now - @started)
66
+ end
67
+
68
+ return total
69
+ end
38
70
  end
39
71
  end
@@ -24,10 +24,5 @@ require 'console'
24
24
  require_relative 'task'
25
25
 
26
26
  module Async
27
- # @return the current logger, either the active tasks logger, or the global event console logger.
28
- def self.logger
29
- if task = Task.current?
30
- task.logger
31
- end || Console.logger
32
- end
27
+ extend Console
33
28
  end
@@ -217,6 +217,10 @@ module Async
217
217
  end
218
218
  end
219
219
 
220
+ def backtrace(*arguments)
221
+ nil
222
+ end
223
+
220
224
  def to_s
221
225
  "\#<#{description}>"
222
226
  end
@@ -297,9 +301,23 @@ module Async
297
301
  @children&.each(&:stop)
298
302
  end
299
303
 
300
- def print_hierarchy(out = $stdout)
304
+ def print_hierarchy(out = $stdout, backtrace: true)
301
305
  self.traverse do |node, level|
302
- out.puts "#{"\t" * level}#{node}"
306
+ indent = "\t" * level
307
+
308
+ out.puts "#{indent}#{node}"
309
+
310
+ print_backtrace(out, indent, node) if backtrace
311
+ end
312
+ end
313
+
314
+ private
315
+
316
+ def print_backtrace(out, indent, node)
317
+ if backtrace = node.backtrace
318
+ backtrace.each_with_index do |line, index|
319
+ out.puts "#{indent}#{index.zero? ? "→ " : " "}#{line}"
320
+ end
303
321
  end
304
322
  end
305
323
  end
@@ -87,7 +87,7 @@ module Async
87
87
  end
88
88
 
89
89
  def logger
90
- @logger ||= Console.logger
90
+ @logger || Console.logger
91
91
  end
92
92
 
93
93
  def to_s
@@ -98,9 +98,6 @@ module Async
98
98
  @children.nil?
99
99
  end
100
100
 
101
- # TODO Remove these in next major release. They are too confusing to use correctly.
102
- def_delegators :@timers, :every, :after
103
-
104
101
  # Start an asynchronous task within the specified reactor. The task will be
105
102
  # executed until the first blocking call, at which point it will yield and
106
103
  # and this method will return.
@@ -266,7 +263,7 @@ module Async
266
263
  def sleep(duration)
267
264
  fiber = Fiber.current
268
265
 
269
- timer = self.after(duration) do
266
+ timer = @timers.after(duration) do
270
267
  if fiber.alive?
271
268
  fiber.resume
272
269
  end
@@ -283,7 +280,7 @@ module Async
283
280
  def with_timeout(timeout, exception = TimeoutError)
284
281
  fiber = Fiber.current
285
282
 
286
- timer = self.after(timeout) do
283
+ timer = @timers.after(timeout) do
287
284
  if fiber.alive?
288
285
  error = exception.new("execution expired")
289
286
  fiber.resume error
@@ -86,16 +86,23 @@ module Async
86
86
  @fiber = make_fiber(&block)
87
87
  end
88
88
 
89
+ if Fiber.current.respond_to?(:backtrace)
90
+ def backtrace(*arguments)
91
+ @fiber.backtrace(*arguments)
92
+ end
93
+ end
94
+
89
95
  def to_s
90
96
  "\#<#{self.description} (#{@status})>"
91
97
  end
92
98
 
93
99
  def logger
94
- @logger ||= @parent&.logger
100
+ @logger || Console.logger
95
101
  end
96
102
 
97
103
  # @attr ios [Reactor] The reactor the task was created within.
98
104
  attr :reactor
105
+
99
106
  def_delegators :@reactor, :with_timeout, :timeout, :sleep
100
107
 
101
108
  # Yield back to the reactor and allow other fibers to execute.
@@ -226,7 +233,7 @@ module Async
226
233
  private
227
234
 
228
235
  # This is a very tricky aspect of tasks to get right. I've modelled it after `Thread` but it's slightly different in that the exception can propagate back up through the reactor. If the user writes code which raises an exception, that exception should always be visible, i.e. cause a failure. If it's not visible, such code fails silently and can be very difficult to debug.
229
- # As an explcit choice, the user can start a task which doesn't propagate exceptions. This only applies to `StandardError` and derived tasks. This allows tasks to internally capture their error state which is raised when invoking `Task#result` similar to how `Thread#join` works. This mode makes `Async::Task` behave more like a promise, and you would need to ensure that someone calls `Task#result` otherwise you might miss important errors.
236
+ # As an explcit choice, the user can start a task which doesn't propagate exceptions. This only applies to `StandardError` and derived tasks. This allows tasks to internally capture their error state which is raised when invoking `Task#result` similar to how `Thread#join` works. This mode makes {ruby Async::Task} behave more like a promise, and you would need to ensure that someone calls `Task#result` otherwise you might miss important errors.
230
237
  def fail!(exception = nil, propagate = true)
231
238
  @status = :failed
232
239
  @result = exception
@@ -289,6 +296,7 @@ module Async
289
296
  def set!
290
297
  # This is actually fiber-local:
291
298
  Thread.current[:async_task] = self
299
+ Console.logger = @logger if @logger
292
300
  end
293
301
  end
294
302
  end
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module Async
24
- VERSION = "1.26.2"
24
+ VERSION = "1.27.0"
25
25
  end
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.26.2
4
+ version: 1.27.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: 2020-06-11 00:00:00.000000000 Z
11
+ date: 2020-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: console
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.10'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '1.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nio4r
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.1'
69
69
  - !ruby/object:Gem::Dependency
70
- name: bake-bundler
70
+ name: bake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: bake-modernize
84
+ name: benchmark-ips
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -122,20 +122,6 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.10'
125
- - !ruby/object:Gem::Dependency
126
- name: benchmark-ips
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
125
  - !ruby/object:Gem::Dependency
140
126
  name: rspec
141
127
  requirement: !ruby/object:Gem::Requirement