async 1.15.5 → 1.16.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: 9054b68547d0e94b18941009bd5027671653e5b13c9e02ef5cecc02660d03b64
4
- data.tar.gz: 9c2ef872af0bcb90a0bcbfcb757fb4eb1c5a416c52d93176fab13ade58894b2a
3
+ metadata.gz: d32f66a08662551d096e73d45b968db7ba3c1faac364dd30a6727e6b987fc060
4
+ data.tar.gz: daaecb80e3223b8fbd31798c6d45f8c7a03ec45544fceea966ffd1cdc075264a
5
5
  SHA512:
6
- metadata.gz: 0f4b0338a5cda22e46ffff913033d76092225dbec527d35985c477c6bdfa46fda4f38ccb36257994ae675088091abbdc2c1d6bc73a951ecea5d743dfc7c5f007
7
- data.tar.gz: f81dc50f4e9933aacf9132e59651238e5bd40889fdd022551fff024731129d1ea5c5cc07fae03a12594705e941353e5ddb18baec36ad17d40b646fae2e8cfa5e
6
+ metadata.gz: 138843f67fa5d3d700a64d034d8ca70b826f26d48392e2f7bfd404bc77d6045ee7c492f823fb33263a1896a03988e57f9d6d0ba78c6ce7ab48ba48ee29a9460a
7
+ data.tar.gz: 3040bffa50775ca7fa3fde5dd1a6d6c4cde77ffcfd079fddc5118310ff9cf0057842b1525b8c9c0ec1b07192af56baf20e6298efaa359b2bb2c0e55bed948e5a
@@ -19,11 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
21
  spec.require_paths = ["lib"]
22
-
22
+
23
23
  spec.required_ruby_version = ">= 2.2.7"
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
28
 
28
29
  spec.add_development_dependency "async-rspec", "~> 1.1"
29
30
 
@@ -18,191 +18,8 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require_relative 'terminal'
22
-
23
- # Downstream gems often use `Logger:::LEVEL` constants, so we pull this in so they are available. That being said, the code should be fixed.
24
- require 'logger'
21
+ require 'event/console'
25
22
 
26
23
  module Async
27
- class Logger
28
- class Buffer < StringIO
29
- def initialize(prefix = nil)
30
- @prefix = prefix
31
-
32
- super()
33
- end
34
-
35
- def puts(*args, prefix: @prefix)
36
- args.each do |arg|
37
- self.write(prefix) if prefix
38
-
39
- super(arg)
40
- end
41
- end
42
- end
43
-
44
- LEVELS = {debug: 0, info: 1, warn: 2, error: 3, fatal: 4}
45
-
46
- LEVELS.each do |name, level|
47
- const_set(name.to_s.upcase, level)
48
-
49
- define_method(name) do |subject = nil, *arguments, &block|
50
- enabled = @subjects[subject.class]
51
-
52
- if enabled == true or (enabled != false and level >= @level)
53
- self.format(subject, *arguments, &block)
54
- end
55
- end
56
-
57
- define_method("#{name}!") do
58
- @level = level
59
- end
60
- end
61
-
62
- def initialize(output, level: 1)
63
- @output = output
64
- @level = level
65
- @start = Time.now
66
-
67
- @terminal = Terminal.new(output)
68
- @reset_style = @terminal.reset
69
- @prefix_style = @terminal.color(Terminal::Colors::CYAN)
70
- @subject_style = @terminal.color(nil, nil, Terminal::Attributes::BOLD)
71
- @exception_title_style = @terminal.color(Terminal::Colors::RED, nil, Terminal::Attributes::BOLD)
72
- @exception_details_style = @terminal.color(Terminal::Colors::YELLOW)
73
- @exception_line_style = @terminal.color(Terminal::Colors::RED)
74
-
75
- @subjects = {}
76
- end
77
-
78
- attr :level
79
-
80
- def level= value
81
- if value.is_a? Symbol
82
- @level = LEVELS[value]
83
- else
84
- @level = value
85
- end
86
- end
87
-
88
- def enabled?(subject)
89
- @subjects[subject.class] == true
90
- end
91
-
92
- def enable(subject)
93
- @subjects[subject.class] = true
94
- end
95
-
96
- def disable(subject)
97
- @subjects[subject.class] = false
98
- end
99
-
100
- def log(level, *arguments, &block)
101
- unless level.is_a? Symbol
102
- level = LEVELS[level]
103
- end
104
-
105
- self.send(level, *arguments, &block)
106
- end
107
-
108
- def format(subject = nil, *arguments, &block)
109
- prefix = time_offset_prefix
110
- indent = " " * prefix.size
111
-
112
- buffer = Buffer.new("#{indent}| ")
113
-
114
- if subject
115
- format_subject(prefix, subject, output: buffer)
116
- end
117
-
118
- arguments.each do |argument|
119
- format_argument(argument, output: buffer)
120
- end
121
-
122
- if block_given?
123
- if block.arity.zero?
124
- format_argument(yield, output: buffer)
125
- else
126
- yield(buffer, @terminal)
127
- end
128
- end
129
-
130
- @output.write buffer.string
131
- end
132
-
133
- def format_argument(argument, output: @output)
134
- if argument.is_a? Exception
135
- format_exception(argument, output: output)
136
- else
137
- format_value(argument, output: output)
138
- end
139
- end
140
-
141
- def format_exception(exception, prefix = nil, pwd: Dir.pwd, output: @output)
142
- lines = exception.message.lines.map(&:chomp)
143
-
144
- output.puts " #{prefix}#{@exception_title_style}#{exception.class}#{@reset_style}: #{lines.shift}"
145
-
146
- lines.each do |line|
147
- output.puts " #{@exception_details_style}" + line + @reset_style
148
- end
149
-
150
- exception.backtrace.each_with_index do |line, index|
151
- path, offset, message = line.split(":")
152
-
153
- # Make the path a bit more readable
154
- path.gsub!(/^#{pwd}\//, "./")
155
-
156
- output.puts " #{index == 0 ? "→" : " "} #{@exception_line_style}#{path}:#{offset}#{@reset_style} #{message}"
157
- end
158
-
159
- if exception.cause
160
- format_exception(exception.cause, "Caused by ", pwd: pwd, output: output)
161
- end
162
- end
163
-
164
- def format_subject(prefix, subject, output: @output)
165
- output.puts "#{@subject_style}#{subject}#{@reset_style}", prefix: "#{@prefix_style}#{prefix}: "
166
- end
167
-
168
- def format_value(value, output: @output)
169
- string = value.to_s
170
-
171
- string.each_line do |line|
172
- output.puts "#{line}"
173
- end
174
- end
175
-
176
- def time_offset_prefix
177
- offset = Time.now - @start
178
- minutes = (offset/60).floor
179
- seconds = (offset - (minutes*60))
180
-
181
- if minutes > 0
182
- "#{minutes}m#{seconds.floor}s"
183
- else
184
- "#{seconds.round(2)}s"
185
- end.rjust(6)
186
- end
187
- end
188
-
189
- # The Async Logger class.
190
- class << self
191
- # @attr logger [Logger] the global logger instance used by `Async`.
192
- attr :logger
193
-
194
- # Set the default log level based on `$DEBUG` and `$VERBOSE`.
195
- def default_log_level
196
- if $DEBUG
197
- Logger::DEBUG
198
- elsif $VERBOSE
199
- Logger::INFO
200
- else
201
- Logger::WARN
202
- end
203
- end
204
- end
205
-
206
- # Create the logger instance.
207
- @logger = Logger.new($stderr, level: self.default_log_level)
24
+ extend Event::Console
208
25
  end
@@ -51,7 +51,7 @@ module Async
51
51
  super()
52
52
 
53
53
  @limit = limit
54
- @full = Async::Condition.new
54
+ @full = Async::Queue.new
55
55
  end
56
56
 
57
57
  attr :limit
@@ -63,7 +63,7 @@ module Async
63
63
 
64
64
  def enqueue item
65
65
  if limited?
66
- @full.wait
66
+ @full.dequeue
67
67
  end
68
68
 
69
69
  super
@@ -72,7 +72,7 @@ module Async
72
72
  def dequeue
73
73
  item = super
74
74
 
75
- @full.signal unless @full.empty?
75
+ @full.enqueue(nil) unless @full.empty?
76
76
 
77
77
  return item
78
78
  end
@@ -193,7 +193,8 @@ module Async
193
193
 
194
194
  return initial_task
195
195
  ensure
196
- Async.logger.debug(self) {"Exiting run-loop because #{$! ? $!.inspect : 'finished'}."}
196
+ Async.logger.debug(self) {"Exiting run-loop because #{$! ? $! : 'finished'}."}
197
+
197
198
  @stopped = true
198
199
  end
199
200
 
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Async
22
- VERSION = "1.15.5"
22
+ VERSION = "1.16.0"
23
23
  end
@@ -53,4 +53,25 @@ RSpec.describe Async::LimitedQueue do
53
53
  subject.enqueue(10)
54
54
  expect(subject).to be_limited
55
55
  end
56
+
57
+ it 'should resume waiting tasks in order' do
58
+ total_resumed = 0
59
+ total_dequeued = 0
60
+ Async do |producer|
61
+ 10.times do
62
+ producer.async do
63
+ subject.enqueue('foo')
64
+ total_resumed += 1
65
+ end
66
+ end
67
+ end
68
+ Async do |consumer|
69
+ 10.times do
70
+ subject.dequeue
71
+ total_dequeued += 1
72
+
73
+ expect(total_resumed).to be == total_dequeued
74
+ end
75
+ end
76
+ end
56
77
  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.15.5
4
+ version: 1.16.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-03 00:00:00.000000000 Z
11
+ date: 2019-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nio4r
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: event
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: async-rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -144,7 +158,6 @@ files:
144
158
  - lib/async/reactor.rb
145
159
  - lib/async/semaphore.rb
146
160
  - lib/async/task.rb
147
- - lib/async/terminal.rb
148
161
  - lib/async/version.rb
149
162
  - lib/async/wrapper.rb
150
163
  - logo.png
@@ -154,7 +167,6 @@ files:
154
167
  - spec/async/clock_spec.rb
155
168
  - spec/async/condition_examples.rb
156
169
  - spec/async/condition_spec.rb
157
- - spec/async/logger_spec.rb
158
170
  - spec/async/node_spec.rb
159
171
  - spec/async/notification_spec.rb
160
172
  - spec/async/performance_spec.rb
@@ -193,7 +205,6 @@ test_files:
193
205
  - spec/async/clock_spec.rb
194
206
  - spec/async/condition_examples.rb
195
207
  - spec/async/condition_spec.rb
196
- - spec/async/logger_spec.rb
197
208
  - spec/async/node_spec.rb
198
209
  - spec/async/notification_spec.rb
199
210
  - spec/async/performance_spec.rb
@@ -1,99 +0,0 @@
1
- # Copyright, 2019, 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
- module Async
22
- # Styled terminal output. **Internal Use Only**
23
- class Terminal
24
- module Attributes
25
- NORMAL = 0
26
- BOLD = 1
27
- FAINT = 2
28
- ITALIC = 3
29
- UNDERLINE = 4
30
- BLINK = 5
31
- REVERSE = 7
32
- HIDDEN = 8
33
- end
34
-
35
- module Colors
36
- BLACK = 0
37
- RED = 1
38
- GREEN = 2
39
- YELLOW = 3
40
- BLUE = 4
41
- MAGENTA = 5
42
- CYAN = 6
43
- WHITE = 7
44
- DEFAULT = 9
45
- end
46
-
47
- def initialize(output)
48
- @output = output
49
- end
50
-
51
- def tty?
52
- @output.isatty
53
- end
54
-
55
- def color(foreground, background = nil, attributes = nil)
56
- return nil unless tty?
57
-
58
- buffer = String.new
59
-
60
- buffer << "\e["
61
- first = true
62
-
63
- if attributes
64
- buffer << (attributes).to_s
65
- first = false
66
- end
67
-
68
- if foreground
69
- if !first
70
- buffer << ";"
71
- else
72
- first = false
73
- end
74
-
75
- buffer << (30 + foreground).to_s
76
- end
77
-
78
- if background
79
- if !first
80
- buffer << ";"
81
- else
82
- first = false
83
- end
84
-
85
- buffer << (40 + background).to_s
86
- end
87
-
88
- buffer << 'm'
89
-
90
- return buffer
91
- end
92
-
93
- def reset
94
- return nil unless tty?
95
-
96
- return "\e[0m"
97
- end
98
- end
99
- end
@@ -1,101 +0,0 @@
1
- # Copyright, 2018, 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
- RSpec.describe Async::Logger do
22
- let(:output) {StringIO.new}
23
- subject{described_class.new(output)}
24
-
25
- let(:message) {"Hello World"}
26
-
27
- context "default log level" do
28
- it "logs info" do
29
- subject.info(message)
30
-
31
- expect(output.string).to include message
32
- end
33
-
34
- it "doesn't log debug" do
35
- subject.debug(message)
36
-
37
- expect(output.string).to_not include message
38
- end
39
-
40
- it "can log to buffer" do
41
- subject.info do |buffer|
42
- buffer << message
43
- end
44
-
45
- expect(output.string).to include message
46
- end
47
- end
48
-
49
- described_class::LEVELS.each do |name, level|
50
- it "can log #{name} messages" do
51
- subject.level = level
52
- subject.log(name, message)
53
-
54
- expect(output.string).to include message
55
- end
56
- end
57
-
58
- describe '#enable' do
59
- let(:object) {Async::Node.new}
60
-
61
- it "can enable specific subjects" do
62
- subject.warn!
63
-
64
- subject.enable(object)
65
- expect(subject).to be_enabled(object)
66
-
67
- subject.debug(object, message)
68
- expect(output.string).to include message
69
- end
70
- end
71
- end
72
-
73
- RSpec.describe Async.logger do
74
- describe 'default_log_level' do
75
- let!(:debug) {$DEBUG}
76
- after {$DEBUG = debug}
77
-
78
- let!(:verbose) {$VERBOSE}
79
- after {$VERBOSE = verbose}
80
-
81
- it 'should set default log level' do
82
- $DEBUG = false
83
- $VERBOSE = false
84
-
85
- expect(Async.default_log_level).to be == Async::Logger::WARN
86
- end
87
-
88
- it 'should set default log level based on $DEBUG' do
89
- $DEBUG = true
90
-
91
- expect(Async.default_log_level).to be == Async::Logger::DEBUG
92
- end
93
-
94
- it 'should set default log level based on $VERBOSE' do
95
- $DEBUG = false
96
- $VERBOSE = true
97
-
98
- expect(Async.default_log_level).to be == Async::Logger::INFO
99
- end
100
- end
101
- end