async-container 0.16.6 → 0.16.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,6 +24,7 @@ require 'async/reactor'
24
24
 
25
25
  module Async
26
26
  module Container
27
+ # Tracks various statistics relating to child instances in a container.
27
28
  class Statistics
28
29
  def initialize
29
30
  @spawns = 0
@@ -31,26 +32,41 @@ module Async
31
32
  @failures = 0
32
33
  end
33
34
 
35
+ # How many child instances have been spawned.
36
+ # @attribute [Integer]
34
37
  attr :spawns
38
+
39
+ # How many child instances have been restarted.
40
+ # @attribute [Integer]
35
41
  attr :restarts
42
+
43
+ # How many child instances have failed.
44
+ # @attribute [Integer]
36
45
  attr :failures
37
46
 
47
+ # Increment the number of spawns by 1.
38
48
  def spawn!
39
49
  @spawns += 1
40
50
  end
41
51
 
52
+ # Increment the number of restarts by 1.
42
53
  def restart!
43
54
  @restarts += 1
44
55
  end
45
56
 
57
+ # Increment the number of failures by 1.
46
58
  def failure!
47
59
  @failures += 1
48
60
  end
49
61
 
62
+ # Whether there have been any failures.
63
+ # @returns [Boolean] If the failure count is greater than 0.
50
64
  def failed?
51
65
  @failures > 0
52
66
  end
53
67
 
68
+ # Append another statistics instance into this one.
69
+ # @parameter other [Statistics] The statistics to append.
54
70
  def << other
55
71
  @spawns += other.spawns
56
72
  @restarts += other.restarts
@@ -24,18 +24,24 @@ require_relative 'channel'
24
24
  require_relative 'error'
25
25
  require_relative 'notify/pipe'
26
26
 
27
- require 'async/logger'
28
-
29
27
  module Async
30
28
  module Container
29
+ # Represents a running child thread from the point of view of the parent container.
31
30
  class Thread < Channel
31
+ # Used to propagate the exit status of a child process invoked by {Instance#exec}.
32
32
  class Exit < Exception
33
+ # Initialize the exit status.
34
+ # @parameter status [::Process::Status] The process exit status.
33
35
  def initialize(status)
34
36
  @status = status
35
37
  end
36
38
 
39
+ # The process exit status.
40
+ # @attribute [::Process::Status]
37
41
  attr :status
38
42
 
43
+ # The process exit status if it was an error.
44
+ # @returns [::Process::Status | Nil]
39
45
  def error
40
46
  unless status.success?
41
47
  status
@@ -43,7 +49,10 @@ module Async
43
49
  end
44
50
  end
45
51
 
52
+ # Represents a running child thread from the point of view of the child thread.
46
53
  class Instance < Notify::Pipe
54
+ # Wrap an instance around the {Thread} instance from within the threaded child.
55
+ # @parameter thread [Thread] The thread intance to wrap.
47
56
  def self.for(thread)
48
57
  instance = self.new(thread.out)
49
58
 
@@ -57,14 +66,20 @@ module Async
57
66
  super
58
67
  end
59
68
 
69
+ # Set the name of the thread.
70
+ # @parameter value [String] The name to set.
60
71
  def name= value
61
72
  @thread.name = value
62
73
  end
63
74
 
75
+ # Get the name of the thread.
76
+ # @returns [String]
64
77
  def name
65
78
  @thread.name
66
79
  end
67
80
 
81
+ # Execute a child process using {::Process.spawn}. In order to simulate {::Process.exec}, an {Exit} instance is raised to propagage exit status.
82
+ # This creates the illusion that this method does not return (normally).
68
83
  def exec(*arguments, ready: true, **options)
69
84
  if ready
70
85
  self.ready!(status: "(spawn)") if ready
@@ -91,6 +106,8 @@ module Async
91
106
  end
92
107
  end
93
108
 
109
+ # Initialize the thread.
110
+ # @parameter name [String] The name to use for the child thread.
94
111
  def initialize(name: nil)
95
112
  super()
96
113
 
@@ -116,18 +133,25 @@ module Async
116
133
  end
117
134
  end
118
135
 
136
+ # Set the name of the thread.
137
+ # @parameter value [String] The name to set.
119
138
  def name= value
120
139
  @thread.name = value
121
140
  end
122
141
 
142
+ # Get the name of the thread.
143
+ # @returns [String]
123
144
  def name
124
145
  @thread.name
125
146
  end
126
147
 
148
+ # A human readable representation of the thread.
149
+ # @returns [String]
127
150
  def to_s
128
151
  "\#<#{self.class} #{@thread.name}>"
129
152
  end
130
153
 
154
+ # Invoke {#terminate!} and then {#wait} for the child thread to exit.
131
155
  def close
132
156
  self.terminate!
133
157
  self.wait
@@ -135,14 +159,18 @@ module Async
135
159
  super
136
160
  end
137
161
 
162
+ # Raise {Interrupt} in the child thread.
138
163
  def interrupt!
139
164
  @thread.raise(Interrupt)
140
165
  end
141
166
 
167
+ # Raise {Terminate} in the child thread.
142
168
  def terminate!
143
169
  @thread.raise(Terminate)
144
170
  end
145
171
 
172
+ # Wait for the thread to exit and return he exit status.
173
+ # @returns [Status]
146
174
  def wait
147
175
  if @waiter
148
176
  @waiter.join
@@ -152,15 +180,21 @@ module Async
152
180
  return @status
153
181
  end
154
182
 
183
+ # A pseudo exit-status wrapper.
155
184
  class Status
156
- def initialize(result = nil)
157
- @result = result
185
+ # Initialise the status.
186
+ # @parameter error [::Process::Status] The exit status of the child thread.
187
+ def initialize(error = nil)
188
+ @error = error
158
189
  end
159
190
 
191
+ # Whether the status represents a successful outcome.
192
+ # @returns [Boolean]
160
193
  def success?
161
- @result.nil?
194
+ @error.nil?
162
195
  end
163
196
 
197
+ # A human readable representation of the status.
164
198
  def to_s
165
199
  "\#<#{self.class} #{success? ? "success" : "failure"}>"
166
200
  end
@@ -168,9 +202,10 @@ module Async
168
202
 
169
203
  protected
170
204
 
205
+ # Invoked by the @waiter thread to indicate the outcome of the child thread.
171
206
  def finished(error = nil)
172
207
  if error
173
- Async.logger.error(self) {error}
208
+ Console.logger.error(self) {error}
174
209
  end
175
210
 
176
211
  @status = Status.new(error)
@@ -24,13 +24,17 @@ require_relative 'generic'
24
24
  require_relative 'thread'
25
25
 
26
26
  module Async
27
- # Manages a reactor within one or more threads.
28
27
  module Container
28
+ # A multi-thread container which uses {Thread.fork}.
29
29
  class Threaded < Generic
30
+ # Indicates that this is not a multi-process container.
30
31
  def self.multiprocess?
31
32
  false
32
33
  end
33
34
 
35
+ # Start a named child thread and execute the provided block in it.
36
+ # @parameter name [String] The name (title) of the child process.
37
+ # @parameter block [Proc] The block to execute in the child process.
34
38
  def start(name, &block)
35
39
  Thread.fork(name: name, &block)
36
40
  end
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Async
24
24
  module Container
25
- VERSION = "0.16.6"
25
+ VERSION = "0.16.11"
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-container
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.6
4
+ version: 0.16.11
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-06 00:00:00.000000000 Z
11
+ date: 2021-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -52,34 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.1'
55
- - !ruby/object:Gem::Dependency
56
- name: bake-bundler
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: bake-modernize
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: bundler
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -159,16 +131,16 @@ require_paths:
159
131
  - lib
160
132
  required_ruby_version: !ruby/object:Gem::Requirement
161
133
  requirements:
162
- - - "~>"
134
+ - - ">="
163
135
  - !ruby/object:Gem::Version
164
- version: '2.0'
136
+ version: '2.5'
165
137
  required_rubygems_version: !ruby/object:Gem::Requirement
166
138
  requirements:
167
139
  - - ">="
168
140
  - !ruby/object:Gem::Version
169
141
  version: '0'
170
142
  requirements: []
171
- rubygems_version: 3.1.2
143
+ rubygems_version: 3.2.3
172
144
  signing_key:
173
145
  specification_version: 4
174
146
  summary: Abstract container-based parallelism using threads and processes where appropriate.