async-container 0.16.5 → 0.16.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) 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 +46 -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 +70 -20
  9. data/lib/async/container/group.rb +19 -4
  10. data/lib/async/container/hybrid.rb +5 -0
  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 +41 -6
  21. data/lib/async/container/threaded.rb +5 -1
  22. data/lib/async/container/version.rb +1 -1
  23. metadata +13 -84
  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/.yardopts +0 -1
  29. data/Gemfile +0 -19
  30. data/Guardfile +0 -14
  31. data/README.md +0 -140
  32. data/async-container.gemspec +0 -34
  33. data/examples/async.rb +0 -22
  34. data/examples/channel.rb +0 -45
  35. data/examples/channels/client.rb +0 -103
  36. data/examples/container.rb +0 -33
  37. data/examples/isolate.rb +0 -36
  38. data/examples/minimal.rb +0 -94
  39. data/examples/test.rb +0 -51
  40. data/examples/threads.rb +0 -25
  41. data/examples/title.rb +0 -13
  42. data/examples/udppipe.rb +0 -35
  43. data/spec/async/container/controller_spec.rb +0 -148
  44. data/spec/async/container/dots.rb +0 -29
  45. data/spec/async/container/forked_spec.rb +0 -61
  46. data/spec/async/container/hybrid_spec.rb +0 -36
  47. data/spec/async/container/notify/notify.rb +0 -19
  48. data/spec/async/container/notify/pipe_spec.rb +0 -48
  49. data/spec/async/container/notify_spec.rb +0 -56
  50. data/spec/async/container/shared_examples.rb +0 -80
  51. data/spec/async/container/threaded_spec.rb +0 -35
  52. data/spec/async/container_spec.rb +0 -41
  53. 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
@@ -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.5"
25
+ VERSION = "0.16.10"
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.5
4
+ version: 0.16.10
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-05-17 00:00:00.000000000 Z
11
+ date: 2021-05-08 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,47 +94,12 @@ dependencies:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
96
  version: '3.6'
111
- - !ruby/object:Gem::Dependency
112
- name: bake-bundler
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
- - ".yardopts"
138
- - Gemfile
139
- - Guardfile
140
- - README.md
141
- - async-container.gemspec
142
- - examples/async.rb
143
- - examples/channel.rb
144
- - examples/channels/client.rb
145
- - examples/container.rb
146
- - examples/isolate.rb
147
- - examples/minimal.rb
148
- - examples/test.rb
149
- - examples/threads.rb
150
- - examples/title.rb
151
- - examples/udppipe.rb
152
103
  - lib/async/container.rb
153
104
  - lib/async/container/best.rb
154
105
  - lib/async/container/channel.rb
@@ -170,49 +121,27 @@ files:
170
121
  - lib/async/container/thread.rb
171
122
  - lib/async/container/threaded.rb
172
123
  - lib/async/container/version.rb
173
- - spec/async/container/controller_spec.rb
174
- - spec/async/container/dots.rb
175
- - spec/async/container/forked_spec.rb
176
- - spec/async/container/hybrid_spec.rb
177
- - spec/async/container/notify/notify.rb
178
- - spec/async/container/notify/pipe_spec.rb
179
- - spec/async/container/notify_spec.rb
180
- - spec/async/container/shared_examples.rb
181
- - spec/async/container/threaded_spec.rb
182
- - spec/async/container_spec.rb
183
- - spec/spec_helper.rb
184
124
  homepage: https://github.com/socketry/async-container
185
125
  licenses:
186
126
  - MIT
187
127
  metadata: {}
188
- post_install_message:
128
+ post_install_message:
189
129
  rdoc_options: []
190
130
  require_paths:
191
131
  - lib
192
132
  required_ruby_version: !ruby/object:Gem::Requirement
193
133
  requirements:
194
- - - "~>"
134
+ - - ">="
195
135
  - !ruby/object:Gem::Version
196
- version: '2.0'
136
+ version: '2.5'
197
137
  required_rubygems_version: !ruby/object:Gem::Requirement
198
138
  requirements:
199
139
  - - ">="
200
140
  - !ruby/object:Gem::Version
201
141
  version: '0'
202
142
  requirements: []
203
- rubygems_version: 3.1.2
204
- signing_key:
143
+ rubygems_version: 3.2.3
144
+ signing_key:
205
145
  specification_version: 4
206
- summary: Async is an asynchronous I/O framework based on nio4r.
207
- test_files:
208
- - spec/async/container/controller_spec.rb
209
- - spec/async/container/dots.rb
210
- - spec/async/container/forked_spec.rb
211
- - spec/async/container/hybrid_spec.rb
212
- - spec/async/container/notify/notify.rb
213
- - spec/async/container/notify/pipe_spec.rb
214
- - spec/async/container/notify_spec.rb
215
- - spec/async/container/shared_examples.rb
216
- - spec/async/container/threaded_spec.rb
217
- - spec/async/container_spec.rb
218
- - 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.5
15
- - 2.6
16
- - 2.7
17
- - jruby
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: ruby/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