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.
- checksums.yaml +4 -4
- data/lib/async/container.rb +0 -1
- data/lib/async/container/best.rb +9 -3
- data/lib/async/container/channel.rb +13 -0
- data/lib/async/container/controller.rb +46 -25
- data/lib/async/container/error.rb +21 -0
- data/lib/async/container/forked.rb +5 -1
- data/lib/async/container/generic.rb +58 -17
- data/lib/async/container/group.rb +19 -4
- data/lib/async/container/hybrid.rb +5 -0
- data/lib/async/container/keyed.rb +12 -0
- data/lib/async/container/notify.rb +4 -5
- data/lib/async/container/notify/client.rb +16 -1
- data/lib/async/container/notify/console.rb +8 -21
- data/lib/async/container/notify/pipe.rb +8 -6
- data/lib/async/container/notify/server.rb +0 -1
- data/lib/async/container/notify/socket.rb +14 -1
- data/lib/async/container/process.rb +28 -2
- data/lib/async/container/statistics.rb +16 -0
- data/lib/async/container/thread.rb +41 -6
- data/lib/async/container/threaded.rb +5 -1
- data/lib/async/container/version.rb +1 -1
- metadata +5 -33
@@ -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
|
-
|
157
|
-
|
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
|
-
@
|
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
|
-
|
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
|
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.
|
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:
|
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.
|
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.
|
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.
|