async-container 0.16.6 → 0.16.11

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.
@@ -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.