async-container 0.16.4 → 0.16.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/async/container.rb +0 -1
  3. data/lib/async/container/best.rb +9 -3
  4. data/lib/async/container/channel.rb +13 -0
  5. data/lib/async/container/controller.rb +49 -25
  6. data/lib/async/container/error.rb +21 -0
  7. data/lib/async/container/forked.rb +5 -1
  8. data/lib/async/container/generic.rb +57 -19
  9. data/lib/async/container/group.rb +19 -2
  10. data/lib/async/container/hybrid.rb +16 -2
  11. data/lib/async/container/keyed.rb +12 -0
  12. data/lib/async/container/notify.rb +4 -5
  13. data/lib/async/container/notify/client.rb +16 -1
  14. data/lib/async/container/notify/console.rb +8 -21
  15. data/lib/async/container/notify/pipe.rb +8 -22
  16. data/lib/async/container/notify/server.rb +0 -1
  17. data/lib/async/container/notify/socket.rb +14 -1
  18. data/lib/async/container/process.rb +28 -2
  19. data/lib/async/container/statistics.rb +16 -0
  20. data/lib/async/container/thread.rb +42 -6
  21. data/lib/async/container/threaded.rb +5 -1
  22. data/lib/async/container/version.rb +1 -1
  23. metadata +13 -88
  24. data/.editorconfig +0 -6
  25. data/.github/workflows/development.yml +0 -36
  26. data/.gitignore +0 -21
  27. data/.rspec +0 -3
  28. data/.travis.yml +0 -21
  29. data/.yardopts +0 -1
  30. data/Gemfile +0 -19
  31. data/Guardfile +0 -14
  32. data/README.md +0 -140
  33. data/Rakefile +0 -8
  34. data/async-container.gemspec +0 -34
  35. data/examples/async.rb +0 -22
  36. data/examples/channel.rb +0 -45
  37. data/examples/channels/client.rb +0 -103
  38. data/examples/container.rb +0 -33
  39. data/examples/isolate.rb +0 -36
  40. data/examples/minimal.rb +0 -94
  41. data/examples/test.rb +0 -51
  42. data/examples/threads.rb +0 -25
  43. data/examples/title.rb +0 -13
  44. data/examples/udppipe.rb +0 -35
  45. data/spec/async/container/controller_spec.rb +0 -105
  46. data/spec/async/container/dots.rb +0 -34
  47. data/spec/async/container/forked_spec.rb +0 -61
  48. data/spec/async/container/hybrid_spec.rb +0 -36
  49. data/spec/async/container/notify/notify.rb +0 -19
  50. data/spec/async/container/notify/pipe_spec.rb +0 -48
  51. data/spec/async/container/notify_spec.rb +0 -56
  52. data/spec/async/container/shared_examples.rb +0 -80
  53. data/spec/async/container/signal_spec.rb +0 -66
  54. data/spec/async/container/threaded_spec.rb +0 -35
  55. data/spec/async/container_spec.rb +0 -41
  56. data/spec/spec_helper.rb +0 -21
@@ -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
@@ -21,20 +21,27 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  require_relative 'channel'
24
+ require_relative 'error'
24
25
  require_relative 'notify/pipe'
25
26
 
26
- require 'async/logger'
27
-
28
27
  module Async
29
28
  module Container
29
+ # Represents a running child thread from the point of view of the parent container.
30
30
  class Thread < Channel
31
+ # Used to propagate the exit status of a child process invoked by {Instance#exec}.
31
32
  class Exit < Exception
33
+ # Initialize the exit status.
34
+ # @parameter status [::Process::Status] The process exit status.
32
35
  def initialize(status)
33
36
  @status = status
34
37
  end
35
38
 
39
+ # The process exit status.
40
+ # @attribute [::Process::Status]
36
41
  attr :status
37
42
 
43
+ # The process exit status if it was an error.
44
+ # @returns [::Process::Status | Nil]
38
45
  def error
39
46
  unless status.success?
40
47
  status
@@ -42,7 +49,10 @@ module Async
42
49
  end
43
50
  end
44
51
 
52
+ # Represents a running child thread from the point of view of the child thread.
45
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.
46
56
  def self.for(thread)
47
57
  instance = self.new(thread.out)
48
58
 
@@ -56,14 +66,20 @@ module Async
56
66
  super
57
67
  end
58
68
 
69
+ # Set the name of the thread.
70
+ # @parameter value [String] The name to set.
59
71
  def name= value
60
72
  @thread.name = value
61
73
  end
62
74
 
75
+ # Get the name of the thread.
76
+ # @returns [String]
63
77
  def name
64
78
  @thread.name
65
79
  end
66
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).
67
83
  def exec(*arguments, ready: true, **options)
68
84
  if ready
69
85
  self.ready!(status: "(spawn)") if ready
@@ -90,6 +106,8 @@ module Async
90
106
  end
91
107
  end
92
108
 
109
+ # Initialize the thread.
110
+ # @parameter name [String] The name to use for the child thread.
93
111
  def initialize(name: nil)
94
112
  super()
95
113
 
@@ -115,18 +133,25 @@ module Async
115
133
  end
116
134
  end
117
135
 
136
+ # Set the name of the thread.
137
+ # @parameter value [String] The name to set.
118
138
  def name= value
119
139
  @thread.name = value
120
140
  end
121
141
 
142
+ # Get the name of the thread.
143
+ # @returns [String]
122
144
  def name
123
145
  @thread.name
124
146
  end
125
147
 
148
+ # A human readable representation of the thread.
149
+ # @returns [String]
126
150
  def to_s
127
151
  "\#<#{self.class} #{@thread.name}>"
128
152
  end
129
153
 
154
+ # Invoke {#terminate!} and then {#wait} for the child thread to exit.
130
155
  def close
131
156
  self.terminate!
132
157
  self.wait
@@ -134,14 +159,18 @@ module Async
134
159
  super
135
160
  end
136
161
 
162
+ # Raise {Interrupt} in the child thread.
137
163
  def interrupt!
138
164
  @thread.raise(Interrupt)
139
165
  end
140
166
 
167
+ # Raise {Terminate} in the child thread.
141
168
  def terminate!
142
169
  @thread.raise(Terminate)
143
170
  end
144
171
 
172
+ # Wait for the thread to exit and return he exit status.
173
+ # @returns [Status]
145
174
  def wait
146
175
  if @waiter
147
176
  @waiter.join
@@ -151,15 +180,21 @@ module Async
151
180
  return @status
152
181
  end
153
182
 
183
+ # A pseudo exit-status wrapper.
154
184
  class Status
155
- def initialize(result = nil)
156
- @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
157
189
  end
158
190
 
191
+ # Whether the status represents a successful outcome.
192
+ # @returns [Boolean]
159
193
  def success?
160
- @result.nil?
194
+ @error.nil?
161
195
  end
162
196
 
197
+ # A human readable representation of the status.
163
198
  def to_s
164
199
  "\#<#{self.class} #{success? ? "success" : "failure"}>"
165
200
  end
@@ -167,9 +202,10 @@ module Async
167
202
 
168
203
  protected
169
204
 
205
+ # Invoked by the @waiter thread to indicate the outcome of the child thread.
170
206
  def finished(error = nil)
171
207
  if error
172
- Async.logger.error(self) {error}
208
+ Console.logger.error(self) {error}
173
209
  end
174
210
 
175
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.4"
25
+ VERSION = "0.16.9"
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-container
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.4
4
+ version: 0.16.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-25 00:00:00.000000000 Z
11
+ date: 2021-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: process-group
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: async
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -67,7 +53,7 @@ dependencies:
67
53
  - !ruby/object:Gem::Version
68
54
  version: '1.1'
69
55
  - !ruby/object:Gem::Dependency
70
- name: covered
56
+ name: bundler
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
59
  - - ">="
@@ -81,7 +67,7 @@ dependencies:
81
67
  - !ruby/object:Gem::Version
82
68
  version: '0'
83
69
  - !ruby/object:Gem::Dependency
84
- name: bundler
70
+ name: covered
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
@@ -108,49 +94,12 @@ dependencies:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
96
  version: '3.6'
111
- - !ruby/object:Gem::Dependency
112
- name: rake
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- description: "\t\tProvides containers for servers which provide concurrency policies,
126
- e.g. threads, processes.\n"
97
+ description:
127
98
  email:
128
- - samuel.williams@oriontransfer.co.nz
129
99
  executables: []
130
100
  extensions: []
131
101
  extra_rdoc_files: []
132
102
  files:
133
- - ".editorconfig"
134
- - ".github/workflows/development.yml"
135
- - ".gitignore"
136
- - ".rspec"
137
- - ".travis.yml"
138
- - ".yardopts"
139
- - Gemfile
140
- - Guardfile
141
- - README.md
142
- - Rakefile
143
- - async-container.gemspec
144
- - examples/async.rb
145
- - examples/channel.rb
146
- - examples/channels/client.rb
147
- - examples/container.rb
148
- - examples/isolate.rb
149
- - examples/minimal.rb
150
- - examples/test.rb
151
- - examples/threads.rb
152
- - examples/title.rb
153
- - examples/udppipe.rb
154
103
  - lib/async/container.rb
155
104
  - lib/async/container/best.rb
156
105
  - lib/async/container/channel.rb
@@ -172,51 +121,27 @@ files:
172
121
  - lib/async/container/thread.rb
173
122
  - lib/async/container/threaded.rb
174
123
  - lib/async/container/version.rb
175
- - spec/async/container/controller_spec.rb
176
- - spec/async/container/dots.rb
177
- - spec/async/container/forked_spec.rb
178
- - spec/async/container/hybrid_spec.rb
179
- - spec/async/container/notify/notify.rb
180
- - spec/async/container/notify/pipe_spec.rb
181
- - spec/async/container/notify_spec.rb
182
- - spec/async/container/shared_examples.rb
183
- - spec/async/container/signal_spec.rb
184
- - spec/async/container/threaded_spec.rb
185
- - spec/async/container_spec.rb
186
- - spec/spec_helper.rb
187
124
  homepage: https://github.com/socketry/async-container
188
125
  licenses:
189
126
  - MIT
190
127
  metadata: {}
191
- post_install_message:
128
+ post_install_message:
192
129
  rdoc_options: []
193
130
  require_paths:
194
131
  - lib
195
132
  required_ruby_version: !ruby/object:Gem::Requirement
196
133
  requirements:
197
- - - "~>"
134
+ - - ">="
198
135
  - !ruby/object:Gem::Version
199
- version: '2.0'
136
+ version: '2.5'
200
137
  required_rubygems_version: !ruby/object:Gem::Requirement
201
138
  requirements:
202
139
  - - ">="
203
140
  - !ruby/object:Gem::Version
204
141
  version: '0'
205
142
  requirements: []
206
- rubygems_version: 3.1.2
207
- signing_key:
143
+ rubygems_version: 3.2.3
144
+ signing_key:
208
145
  specification_version: 4
209
- summary: Async is an asynchronous I/O framework based on nio4r.
210
- test_files:
211
- - spec/async/container/controller_spec.rb
212
- - spec/async/container/dots.rb
213
- - spec/async/container/forked_spec.rb
214
- - spec/async/container/hybrid_spec.rb
215
- - spec/async/container/notify/notify.rb
216
- - spec/async/container/notify/pipe_spec.rb
217
- - spec/async/container/notify_spec.rb
218
- - spec/async/container/shared_examples.rb
219
- - spec/async/container/signal_spec.rb
220
- - spec/async/container/threaded_spec.rb
221
- - spec/async/container_spec.rb
222
- - spec/spec_helper.rb
146
+ summary: Abstract container-based parallelism using threads and processes where appropriate.
147
+ test_files: []
data/.editorconfig DELETED
@@ -1,6 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = tab
5
- indent_size = 2
6
-
@@ -1,36 +0,0 @@
1
- name: Development
2
-
3
- on: [push]
4
-
5
- jobs:
6
- test:
7
- strategy:
8
- matrix:
9
- os:
10
- - ubuntu
11
- - macos
12
-
13
- ruby:
14
- - 2.4
15
- - 2.5
16
- - 2.6
17
- - 2.7
18
-
19
- include:
20
- - os: 'ubuntu'
21
- ruby: '2.6'
22
- env: COVERAGE=PartialSummary,Coveralls
23
-
24
- runs-on: ${{matrix.os}}-latest
25
-
26
- steps:
27
- - uses: actions/checkout@v1
28
- - uses: actions/setup-ruby@v1
29
- with:
30
- ruby-version: ${{matrix.ruby}}
31
- - name: Install dependencies
32
- run: |
33
- command -v bundler || gem install bundler
34
- bundle install
35
- - name: Run tests
36
- run: ${{matrix.env}} bundle exec rspec
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- .tags*
19
- documentation/run/*
20
- documentation/public/code/*
21
- .rspec_status