async-container 0.16.5 → 0.16.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- Process.setproctitle "Preparing for sleep..."
5
-
6
- 10.times do |i|
7
- puts "Counting sheep #{i}"
8
- Process.setproctitle "Counting sheep #{i}"
9
-
10
- sleep 10
11
- end
12
-
13
- puts "Zzzzzzz"
@@ -1,35 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'async/io'
5
- require 'async/io/endpoint'
6
- require 'async/io/unix_endpoint'
7
-
8
- @endpoint = Async::IO::Endpoint.unix("/tmp/notify-test.sock", Socket::SOCK_DGRAM)
9
- # address = Async::IO::Address.udp("127.0.0.1", 6778)
10
- # @endpoint = Async::IO::AddressEndpoint.new(address)
11
-
12
- def server
13
- @endpoint.bind do |server|
14
- puts "Receiving..."
15
- packet, address = server.recvfrom(512)
16
-
17
- puts "Received: #{packet} from #{address}"
18
- end
19
- end
20
-
21
- def client(data = "Hello World!")
22
- @endpoint.connect do |peer|
23
- puts "Sending: #{data}"
24
- peer.send(data)
25
- puts "Sent!"
26
- end
27
- end
28
-
29
- Async do |task|
30
- server_task = task.async do
31
- server
32
- end
33
-
34
- client
35
- end
@@ -1,148 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require "async/container/controller"
24
-
25
- RSpec.describe Async::Container::Controller do
26
- describe '#reload' do
27
- it "can reuse keyed child" do
28
- input, output = IO.pipe
29
-
30
- subject.instance_variable_set(:@output, output)
31
-
32
- def subject.setup(container)
33
- container.spawn(key: "test") do |instance|
34
- instance.ready!
35
-
36
- sleep(0.2 * QUANTUM)
37
-
38
- @output.write(".")
39
- @output.flush
40
-
41
- sleep(0.4 * QUANTUM)
42
- end
43
-
44
- container.spawn do |instance|
45
- instance.ready!
46
-
47
- sleep(0.3 * QUANTUM)
48
-
49
- @output.write(",")
50
- @output.flush
51
- end
52
- end
53
-
54
- subject.start
55
- expect(input.read(2)).to be == ".,"
56
-
57
- subject.reload
58
-
59
- expect(input.read(1)).to be == ","
60
- subject.wait
61
- end
62
- end
63
-
64
- describe '#start' do
65
- it "can start up a container" do
66
- expect(subject).to receive(:setup)
67
-
68
- subject.start
69
-
70
- expect(subject).to be_running
71
- expect(subject.container).to_not be_nil
72
-
73
- subject.stop
74
-
75
- expect(subject).to_not be_running
76
- expect(subject.container).to be_nil
77
- end
78
-
79
- it "can spawn a reactor" do
80
- def subject.setup(container)
81
- container.async do |task|
82
- task.sleep 1
83
- end
84
- end
85
-
86
- subject.start
87
-
88
- statistics = subject.container.statistics
89
-
90
- expect(statistics.spawns).to be == 1
91
-
92
- subject.stop
93
- end
94
-
95
- it "propagates exceptions" do
96
- def subject.setup(container)
97
- raise "Boom!"
98
- end
99
-
100
- expect do
101
- subject.run
102
- end.to raise_exception(Async::Container::InitializationError)
103
- end
104
- end
105
-
106
- context 'with signals' do
107
- let(:controller_path) {File.expand_path("dots.rb", __dir__)}
108
-
109
- let(:pipe) {IO.pipe}
110
- let(:input) {pipe.first}
111
- let(:output) {pipe.last}
112
-
113
- let(:pid) {Process.spawn("bundle", "exec", controller_path, out: output)}
114
-
115
- before do
116
- pid
117
- output.close
118
- end
119
-
120
- after do
121
- Process.kill(:KILL, pid)
122
- end
123
-
124
- it "restarts children when receiving SIGHUP" do
125
- expect(input.read(1)).to be == '.'
126
-
127
- Process.kill(:HUP, pid)
128
-
129
- expect(input.read(2)).to be == 'I.'
130
- end
131
-
132
- it "exits gracefully when receiving SIGINT" do
133
- expect(input.read(1)).to be == '.'
134
-
135
- Process.kill(:INT, pid)
136
-
137
- expect(input.read).to be == 'I'
138
- end
139
-
140
- it "exits gracefully when receiving SIGTERM" do
141
- expect(input.read(1)).to be == '.'
142
-
143
- Process.kill(:TERM, pid)
144
-
145
- expect(input.read).to be == 'T'
146
- end
147
- end
148
- end
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative '../../../lib/async/container/controller'
5
-
6
- # Console.logger.debug!
7
-
8
- class Dots < Async::Container::Controller
9
- def setup(container)
10
- container.run(name: "dots", count: 1, restart: true) do |instance|
11
- instance.ready!
12
-
13
- sleep 1
14
-
15
- $stdout.write "."
16
- $stdout.flush
17
-
18
- sleep
19
- rescue Async::Container::Interrupt
20
- $stdout.write("I")
21
- rescue Async::Container::Terminate
22
- $stdout.write("T")
23
- end
24
- end
25
- end
26
-
27
- controller = Dots.new
28
-
29
- controller.run
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require "async/container"
24
- require "async/container/forked"
25
-
26
- require_relative 'shared_examples'
27
-
28
- RSpec.describe Async::Container::Forked, if: Async::Container.fork? do
29
- subject {described_class.new}
30
-
31
- it_behaves_like Async::Container
32
-
33
- it "can restart child" do
34
- trigger = IO.pipe
35
- pids = IO.pipe
36
-
37
- thread = Thread.new do
38
- subject.async(restart: true) do
39
- trigger.first.gets
40
- pids.last.puts Process.pid.to_s
41
- end
42
-
43
- subject.wait
44
- end
45
-
46
- 3.times do
47
- trigger.last.puts "die"
48
- _child_pid = pids.first.gets
49
- end
50
-
51
- thread.kill
52
- thread.join
53
-
54
- expect(subject.statistics.spawns).to be == 1
55
- expect(subject.statistics.restarts).to be == 2
56
- end
57
-
58
- it "should be multiprocess" do
59
- expect(described_class).to be_multiprocess
60
- end
61
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require 'async/container/hybrid'
24
- require 'async/container/best'
25
-
26
- require_relative 'shared_examples'
27
-
28
- RSpec.describe Async::Container::Hybrid, if: Async::Container.fork? do
29
- subject {described_class.new}
30
-
31
- it_behaves_like Async::Container
32
-
33
- it "should be multiprocess" do
34
- expect(described_class).to be_multiprocess
35
- end
36
- end
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative '../../../../lib/async/container'
5
-
6
- class MyController < Async::Container::Controller
7
- def setup(container)
8
- container.run(restart: false) do |instance|
9
- sleep(rand)
10
-
11
- instance.ready!
12
-
13
- sleep(rand)
14
- end
15
- end
16
- end
17
-
18
- controller = MyController.new
19
- controller.run
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require "async/container/controller"
24
-
25
- RSpec.describe Async::Container::Notify::Pipe do
26
- let(:notify_script) {File.expand_path("notify.rb", __dir__)}
27
-
28
- it "receives notification of child status" do
29
- container = Async::Container.new
30
-
31
- container.spawn(restart: false) do |instance|
32
- instance.exec(
33
- "bundle", "exec", "--keep-file-descriptors",
34
- notify_script, ready: false
35
- )
36
- end
37
-
38
- # Wait for the state to be updated by the child process:
39
- container.sleep
40
-
41
- _child, state = container.state.first
42
- expect(state).to be == {status: "Initializing..."}
43
-
44
- container.wait
45
-
46
- expect(container.statistics).to have_attributes(failures: 0)
47
- end
48
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
-
23
- require "async/container/controller"
24
- require "async/container/notify/server"
25
-
26
- RSpec.describe Async::Container::Notify, if: Async::Container.fork? do
27
- let(:server) {described_class::Server.open}
28
- let(:notify_socket) {server.path}
29
- let(:client) {described_class::Socket.new(notify_socket)}
30
-
31
- describe '#ready!' do
32
- it "should send message" do
33
- begin
34
- context = server.bind
35
-
36
- pid = fork do
37
- client.ready!
38
- end
39
-
40
- messages = []
41
-
42
- Sync do
43
- context.receive do |message, address|
44
- messages << message
45
- break
46
- end
47
- end
48
-
49
- expect(messages.last).to include(ready: true)
50
- ensure
51
- context&.close
52
- Process.wait(pid) if pid
53
- end
54
- end
55
- end
56
- end