async-container 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/development.yml +36 -0
  3. data/.travis.yml +3 -3
  4. data/Gemfile +0 -3
  5. data/README.md +76 -9
  6. data/examples/async.rb +21 -0
  7. data/examples/channel.rb +44 -0
  8. data/examples/channels/client.rb +103 -0
  9. data/examples/container.rb +1 -1
  10. data/examples/isolate.rb +35 -0
  11. data/examples/minimal.rb +93 -0
  12. data/examples/test.rb +50 -0
  13. data/{title.rb → examples/title.rb} +0 -0
  14. data/examples/udppipe.rb +34 -0
  15. data/lib/async/container/best.rb +1 -1
  16. data/lib/async/container/channel.rb +57 -0
  17. data/lib/async/container/controller.rb +112 -21
  18. data/lib/async/container/error.rb +10 -0
  19. data/lib/async/container/forked.rb +3 -65
  20. data/lib/async/container/generic.rb +179 -8
  21. data/lib/async/container/group.rb +98 -93
  22. data/lib/async/container/hybrid.rb +2 -3
  23. data/lib/async/container/keyed.rb +53 -0
  24. data/lib/async/container/notify.rb +41 -0
  25. data/lib/async/container/notify/client.rb +61 -0
  26. data/lib/async/container/notify/pipe.rb +115 -0
  27. data/lib/async/container/notify/server.rb +111 -0
  28. data/lib/async/container/notify/socket.rb +86 -0
  29. data/lib/async/container/process.rb +167 -0
  30. data/lib/async/container/thread.rb +182 -0
  31. data/lib/async/container/threaded.rb +4 -90
  32. data/lib/async/container/version.rb +1 -1
  33. data/spec/async/container/controller_spec.rb +40 -0
  34. data/spec/async/container/forked_spec.rb +3 -1
  35. data/spec/async/container/hybrid_spec.rb +4 -1
  36. data/spec/async/container/notify/notify.rb +18 -0
  37. data/spec/async/container/notify/pipe_spec.rb +46 -0
  38. data/spec/async/container/notify_spec.rb +54 -0
  39. data/spec/async/container/shared_examples.rb +18 -6
  40. data/spec/async/container/threaded_spec.rb +2 -0
  41. metadata +27 -4
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Async
22
22
  module Container
23
- VERSION = "0.15.0"
23
+ VERSION = "0.16.0"
24
24
  end
25
25
  end
@@ -21,16 +21,56 @@
21
21
  require "async/container/controller"
22
22
 
23
23
  RSpec.describe Async::Container::Controller do
24
+ describe '#reload' do
25
+ it "can reuse keyed child" do
26
+ input, output = IO.pipe
27
+
28
+ subject.instance_variable_set(:@output, output)
29
+
30
+ def subject.setup(container)
31
+ container.spawn(key: "test") do |instance|
32
+ instance.ready!
33
+
34
+ sleep(0.1)
35
+
36
+ @output.write(".")
37
+ @output.flush
38
+
39
+ sleep(0.2)
40
+ end
41
+
42
+ container.spawn do |instance|
43
+ instance.ready!
44
+
45
+ sleep(0.2)
46
+
47
+ @output.write(",")
48
+ @output.flush
49
+ end
50
+ end
51
+
52
+ subject.start
53
+ expect(input.read(2)).to be == ".,"
54
+
55
+ subject.reload
56
+
57
+ expect(input.read(1)).to be == ","
58
+ subject.wait
59
+ end
60
+ end
61
+
24
62
  describe '#start' do
25
63
  it "can start up a container" do
26
64
  expect(subject).to receive(:setup)
27
65
 
28
66
  subject.start
29
67
 
68
+ expect(subject).to be_running
30
69
  expect(subject.container).to_not be_nil
31
70
 
32
71
  subject.stop
33
72
 
73
+ expect(subject).to_not be_running
34
74
  expect(subject.container).to be_nil
35
75
  end
36
76
 
@@ -24,6 +24,8 @@ require "async/container/forked"
24
24
  require_relative 'shared_examples'
25
25
 
26
26
  RSpec.describe Async::Container::Forked, if: Async::Container.fork? do
27
+ subject {described_class.new}
28
+
27
29
  it_behaves_like Async::Container
28
30
 
29
31
  it "can restart child" do
@@ -47,7 +49,7 @@ RSpec.describe Async::Container::Forked, if: Async::Container.fork? do
47
49
  thread.kill
48
50
  thread.join
49
51
 
50
- expect(subject.statistics.spawns).to be == 3
52
+ expect(subject.statistics.spawns).to be == 1
51
53
  expect(subject.statistics.restarts).to be == 2
52
54
  end
53
55
 
@@ -18,11 +18,14 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require "async/container/hybrid"
21
+ require 'async/container/hybrid'
22
+ require 'async/container/best'
22
23
 
23
24
  require_relative 'shared_examples'
24
25
 
25
26
  RSpec.describe Async::Container::Hybrid, if: Async::Container.fork? do
27
+ subject {described_class.new}
28
+
26
29
  it_behaves_like Async::Container
27
30
 
28
31
  it "should be multiprocess" do
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../../../lib/async/container'
4
+
5
+ class MyController < Async::Container::Controller
6
+ def setup(container)
7
+ container.run(restart: false) do |instance|
8
+ sleep(rand)
9
+
10
+ instance.ready!
11
+
12
+ sleep(rand)
13
+ end
14
+ end
15
+ end
16
+
17
+ controller = MyController.new
18
+ controller.run
@@ -0,0 +1,46 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require "async/container/controller"
22
+
23
+ RSpec.describe Async::Container::Notify::Pipe do
24
+ let(:notify_script) {File.expand_path("notify.rb", __dir__)}
25
+
26
+ it "receives notification of child status" do
27
+ container = Async::Container.new
28
+
29
+ container.spawn(restart: false) do |instance|
30
+ instance.exec(
31
+ "bundle", "exec", "--keep-file-descriptors",
32
+ notify_script, ready: false
33
+ )
34
+ end
35
+
36
+ # Wait for the state to be updated by the child process:
37
+ container.sleep
38
+
39
+ child, state = container.state.first
40
+ expect(state).to be == {status: "Initializing..."}
41
+
42
+ container.wait
43
+
44
+ expect(container.statistics).to have_attributes(failures: 0)
45
+ end
46
+ end
@@ -0,0 +1,54 @@
1
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require "async/container/controller"
22
+ require "async/container/notify/server"
23
+
24
+ RSpec.describe Async::Container::Notify, if: Async::Container.fork? do
25
+ let(:server) {described_class::Server.open}
26
+ let(:notify_socket) {server.path}
27
+ let(:client) {described_class::Socket.new(notify_socket)}
28
+
29
+ describe '#ready!' do
30
+ it "should send message" do
31
+ begin
32
+ context = server.bind
33
+
34
+ pid = fork do
35
+ client.ready!
36
+ end
37
+
38
+ messages = []
39
+
40
+ Sync do
41
+ context.receive do |message, address|
42
+ messages << message
43
+ break
44
+ end
45
+ end
46
+
47
+ expect(messages.last).to include(ready: true)
48
+ ensure
49
+ context&.close
50
+ Process.wait(pid) if pid
51
+ end
52
+ end
53
+ end
54
+ end
@@ -37,7 +37,6 @@ RSpec.shared_examples_for Async::Container do
37
37
  it "can run concurrently" do
38
38
  subject.async(name: "Sleepy Jerry") do |task, instance|
39
39
  3.times do |i|
40
- puts "Counting Sheep #{i}"
41
40
  instance.name = "Counting Sheep #{i}"
42
41
 
43
42
  sleep 0.01
@@ -50,17 +49,30 @@ RSpec.shared_examples_for Async::Container do
50
49
  describe '#sleep' do
51
50
  it "can sleep for a short time" do
52
51
  subject.spawn do
53
- sleep(2)
52
+ sleep(0.2)
54
53
  raise "Boom"
55
54
  end
56
55
 
57
- subject.sleep(1)
58
-
59
- expect(subject.statistics.failures).to be_zero
56
+ subject.sleep(0.1)
57
+ expect(subject.statistics).to have_attributes(failures: 0)
60
58
 
61
59
  subject.wait
62
60
 
63
- expect(subject.statistics.failures).to_not be_zero
61
+ expect(subject.statistics).to have_attributes(failures: 1)
62
+ end
63
+ end
64
+
65
+ describe '#stop' do
66
+ it 'can stop the child process' do
67
+ subject.spawn do
68
+ sleep(1)
69
+ end
70
+
71
+ is_expected.to be_running
72
+
73
+ subject.stop
74
+
75
+ is_expected.to_not be_running
64
76
  end
65
77
  end
66
78
  end
@@ -23,6 +23,8 @@ require "async/container/threaded"
23
23
  require_relative 'shared_examples'
24
24
 
25
25
  RSpec.describe Async::Container::Threaded do
26
+ subject {described_class.new}
27
+
26
28
  it_behaves_like Async::Container
27
29
 
28
30
  it "should not be multiprocess" do
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.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-19 00:00:00.000000000 Z
11
+ date: 2020-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: process-group
@@ -131,6 +131,7 @@ extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
133
  - ".editorconfig"
134
+ - ".github/workflows/development.yml"
134
135
  - ".gitignore"
135
136
  - ".rspec"
136
137
  - ".travis.yml"
@@ -140,27 +141,46 @@ files:
140
141
  - README.md
141
142
  - Rakefile
142
143
  - async-container.gemspec
144
+ - examples/async.rb
145
+ - examples/channel.rb
146
+ - examples/channels/client.rb
143
147
  - examples/container.rb
148
+ - examples/isolate.rb
149
+ - examples/minimal.rb
150
+ - examples/test.rb
144
151
  - examples/threads.rb
152
+ - examples/title.rb
153
+ - examples/udppipe.rb
145
154
  - lib/async/container.rb
146
155
  - lib/async/container/best.rb
156
+ - lib/async/container/channel.rb
147
157
  - lib/async/container/controller.rb
148
158
  - lib/async/container/error.rb
149
159
  - lib/async/container/forked.rb
150
160
  - lib/async/container/generic.rb
151
161
  - lib/async/container/group.rb
152
162
  - lib/async/container/hybrid.rb
163
+ - lib/async/container/keyed.rb
164
+ - lib/async/container/notify.rb
165
+ - lib/async/container/notify/client.rb
166
+ - lib/async/container/notify/pipe.rb
167
+ - lib/async/container/notify/server.rb
168
+ - lib/async/container/notify/socket.rb
169
+ - lib/async/container/process.rb
153
170
  - lib/async/container/statistics.rb
171
+ - lib/async/container/thread.rb
154
172
  - lib/async/container/threaded.rb
155
173
  - lib/async/container/version.rb
156
174
  - spec/async/container/controller_spec.rb
157
175
  - spec/async/container/forked_spec.rb
158
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
159
180
  - spec/async/container/shared_examples.rb
160
181
  - spec/async/container/threaded_spec.rb
161
182
  - spec/async/container_spec.rb
162
183
  - spec/spec_helper.rb
163
- - title.rb
164
184
  homepage: https://github.com/socketry/async-container
165
185
  licenses:
166
186
  - MIT
@@ -180,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
200
  - !ruby/object:Gem::Version
181
201
  version: '0'
182
202
  requirements: []
183
- rubygems_version: 3.0.4
203
+ rubygems_version: 3.1.2
184
204
  signing_key:
185
205
  specification_version: 4
186
206
  summary: Async is an asynchronous I/O framework based on nio4r.
@@ -188,6 +208,9 @@ test_files:
188
208
  - spec/async/container/controller_spec.rb
189
209
  - spec/async/container/forked_spec.rb
190
210
  - spec/async/container/hybrid_spec.rb
211
+ - spec/async/container/notify/notify.rb
212
+ - spec/async/container/notify/pipe_spec.rb
213
+ - spec/async/container/notify_spec.rb
191
214
  - spec/async/container/shared_examples.rb
192
215
  - spec/async/container/threaded_spec.rb
193
216
  - spec/async/container_spec.rb