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,34 +0,0 @@
1
-
2
- require_relative 'lib/async/container/version'
3
-
4
- Gem::Specification.new do |spec|
5
- spec.name = "async-container"
6
- spec.version = Async::Container::VERSION
7
- spec.authors = ["Samuel Williams"]
8
- spec.email = ["samuel.williams@oriontransfer.co.nz"]
9
- spec.description = <<-EOF
10
- Provides containers for servers which provide concurrency policies, e.g. threads, processes.
11
- EOF
12
- spec.summary = "Async is an asynchronous I/O framework based on nio4r."
13
- spec.homepage = "https://github.com/socketry/async-container"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.required_ruby_version = "~> 2.0"
22
-
23
- spec.add_runtime_dependency "process-group"
24
-
25
- spec.add_runtime_dependency "async", "~> 1.0"
26
- spec.add_runtime_dependency "async-io", "~> 1.26"
27
-
28
- spec.add_development_dependency "async-rspec", "~> 1.1"
29
-
30
- spec.add_development_dependency "covered"
31
- spec.add_development_dependency "bundler"
32
- spec.add_development_dependency "rspec", "~> 3.6"
33
- spec.add_development_dependency "bake-bundler"
34
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'kernel/sync'
4
-
5
- class Worker
6
- def initialize(&block)
7
-
8
- end
9
- end
10
-
11
- Sync do
12
- count.times do
13
- worker = Worker.new(&block)
14
-
15
- status = worker.wait do |message|
16
-
17
- end
18
-
19
- status.success?
20
- status.failed?
21
- end
22
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
-
5
- class Channel
6
- def initialize
7
- @in, @out = IO.pipe
8
- end
9
-
10
- def after_fork
11
- @out.close
12
- end
13
-
14
- def receive
15
- if data = @in.gets
16
- JSON.parse(data, symbolize_names: true)
17
- end
18
- end
19
-
20
- def send(**message)
21
- data = JSON.dump(message)
22
-
23
- @out.puts(data)
24
- end
25
- end
26
-
27
- status = Channel.new
28
-
29
- pid = fork do
30
- status.send(ready: false, status: "Initializing...")
31
-
32
- # exit(-1) # crash
33
-
34
- status.send(ready: true, status: "Initialization Complete!")
35
- end
36
-
37
- status.after_fork
38
-
39
- while message = status.receive
40
- pp message
41
- end
42
-
43
- pid, status = Process.waitpid2(pid)
44
-
45
- puts "Status: #{status}"
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'msgpack'
4
- require 'async/io'
5
- require 'async/io/stream'
6
- require 'async/container'
7
-
8
- # class Bus
9
- # def initialize
10
- #
11
- # end
12
- #
13
- # def << object
14
- # :object
15
- # end
16
- #
17
- # def [] key
18
- # return
19
- # end
20
- # end
21
- #
22
- # class Proxy < BasicObject
23
- # def initialize(bus, name)
24
- # @bus = bus
25
- # @name = name
26
- # end
27
- #
28
- # def inspect
29
- # "[Proxy #{method_missing(:inspect)}]"
30
- # end
31
- #
32
- # def method_missing(*args, &block)
33
- # @bus.invoke(@name, args, &block)
34
- # end
35
- #
36
- # def respond_to?(*args)
37
- # @bus.invoke(@name, ["respond_to?", *args])
38
- # end
39
- # end
40
- #
41
- # class Wrapper < MessagePack::Factory
42
- # def initialize(bus)
43
- # super()
44
- #
45
- # self.register_type(0x00, Object,
46
- # packer: @bus.method(:<<),
47
- # unpacker: @bus.method(:[])
48
- # )
49
- #
50
- # self.register_type(0x01, Symbol)
51
- # self.register_type(0x02, Exception,
52
- # packer: ->(exception){Marshal.dump(exception)},
53
- # unpacker: ->(data){Marshal.load(data)},
54
- # )
55
- #
56
- # self.register_type(0x03, Class,
57
- # packer: ->(klass){Marshal.dump(klass)},
58
- # unpacker: ->(data){Marshal.load(data)},
59
- # )
60
- # end
61
- # end
62
- #
63
- # class Channel
64
- # def self.pipe
65
- # input, output = Async::IO.pipe
66
- # end
67
- #
68
- # def initialize(input, output)
69
- # @input = input
70
- # @output = output
71
- # end
72
- #
73
- # def read
74
- # @input.read
75
- # end
76
- #
77
- # def write
78
- # end
79
- # end
80
-
81
- container = Async::Container.new
82
- input, output = Async::IO.pipe
83
-
84
- container.async do |instance|
85
- stream = Async::IO::Stream.new(input)
86
- output.close
87
-
88
- while message = stream.gets
89
- puts "Hello World from #{instance}: #{message}"
90
- end
91
-
92
- puts "exiting"
93
- end
94
-
95
- stream = Async::IO::Stream.new(output)
96
-
97
- 5.times do |i|
98
- stream.puts "#{i}"
99
- end
100
-
101
- stream.close
102
-
103
- container.wait
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require '../lib/async/container/controller'
5
- require '../lib/async/container/forked'
6
-
7
- Async.logger.debug!
8
-
9
- Async.logger.debug(self, "Starting up...")
10
-
11
- controller = Async::Container::Controller.new do |container|
12
- Async.logger.debug(self, "Setting up container...")
13
-
14
- container.run(count: 1, restart: true) do
15
- Async.logger.debug(self, "Child process started.")
16
-
17
- while true
18
- sleep 1
19
-
20
- if rand < 0.1
21
- exit(1)
22
- end
23
- end
24
- ensure
25
- Async.logger.debug(self, "Child process exiting:", $!)
26
- end
27
- end
28
-
29
- begin
30
- controller.run
31
- ensure
32
- Async.logger.debug(controller, "Parent process exiting:", $!)
33
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # We define end of life-cycle in terms of "Interrupt" (SIGINT), "Terminate" (SIGTERM) and "Kill" (SIGKILL, does not invoke user code).
4
- class Terminate < Interrupt
5
- end
6
-
7
- class Isolate
8
- def initialize(&block)
9
-
10
- end
11
- end
12
-
13
-
14
- parent = Isolate.new do |parent|
15
- preload_user_code
16
- server = bind_socket
17
- children = 4.times.map do
18
- Isolate.new do |worker|
19
- app = load_user_application
20
- worker.ready!
21
- server.accept do |peer|
22
- app.handle_request(peer)
23
- end
24
- end
25
- end
26
- while status = parent.wait
27
- # Status is not just exit status of process but also can be `:ready` or something else.
28
- end
29
- end
30
-
31
- # Similar to Process.wait(pid)
32
- status = parent.wait
33
- # Life cycle controls
34
- parent.interrupt!
35
- parent.terminate!
36
- parent.kill!
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Threaded
4
- def initialize(&block)
5
- @channel = Channel.new
6
- @thread = Thread.new(&block)
7
-
8
- @waiter = Thread.new do
9
- begin
10
- @thread.join
11
- rescue Exception => error
12
- finished(error)
13
- else
14
- finished
15
- end
16
- end
17
- end
18
-
19
- attr :channel
20
-
21
- def close
22
- self.terminate!
23
- self.wait
24
- ensure
25
- @channel.close
26
- end
27
-
28
- def interrupt!
29
- @thread.raise(Interrupt)
30
- end
31
-
32
- def terminate!
33
- @thread.raise(Terminate)
34
- end
35
-
36
- def wait
37
- if @waiter
38
- @waiter.join
39
- @waiter = nil
40
- end
41
-
42
- @status
43
- end
44
-
45
- protected
46
-
47
- def finished(error = nil)
48
- @status = Status.new(error)
49
- @channel.out.close
50
- end
51
- end
52
-
53
- class Forked
54
- def initialize(&block)
55
- @channel = Channel.new
56
- @status = nil
57
-
58
- @pid = Process.fork do
59
- Signal.trap(:INT) {raise Interrupt}
60
- Signal.trap(:INT) {raise Terminate}
61
-
62
- @channel.in.close
63
-
64
- yield
65
- end
66
-
67
- @channel.out.close
68
- end
69
-
70
- attr :channel
71
-
72
- def close
73
- self.terminate!
74
- self.wait
75
- ensure
76
- @channel.close
77
- end
78
-
79
- def interrupt!
80
- Process.kill(:INT, @pid)
81
- end
82
-
83
- def terminate!
84
- Process.kill(:TERM, @pid)
85
- end
86
-
87
- def wait
88
- unless @status
89
- _pid, @status = ::Process.wait(@pid)
90
- end
91
-
92
- @status
93
- end
94
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'group'
4
- require_relative 'thread'
5
- require_relative 'process'
6
-
7
- group = Async::Container::Group.new
8
-
9
- thread_monitor = Fiber.new do
10
- while true
11
- thread = Async::Container::Thread.fork do |instance|
12
- if rand < 0.2
13
- raise "Random Failure!"
14
- end
15
-
16
- instance.send(ready: true, status: "Started Thread")
17
-
18
- sleep(1)
19
- end
20
-
21
- status = group.wait_for(thread) do |message|
22
- puts "Thread message: #{message}"
23
- end
24
-
25
- puts "Thread status: #{status}"
26
- end
27
- end.resume
28
-
29
- process_monitor = Fiber.new do
30
- while true
31
- # process = Async::Container::Process.fork do |instance|
32
- # if rand < 0.2
33
- # raise "Random Failure!"
34
- # end
35
- #
36
- # instance.send(ready: true, status: "Started Process")
37
- #
38
- # sleep(1)
39
- # end
40
-
41
- process = Async::Container::Process.spawn('bash -c "sleep 1; echo foobar; sleep 1; exit -1"')
42
-
43
- status = group.wait_for(process) do |message|
44
- puts "Process message: #{message}"
45
- end
46
-
47
- puts "Process status: #{status}"
48
- end
49
- end.resume
50
-
51
- group.wait
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- puts "Process pid: #{Process.pid}"
5
-
6
- threads = 10.times.collect do
7
- Thread.new do
8
- begin
9
- sleep
10
- rescue Exception
11
- puts "Thread: #{$!}"
12
- end
13
- end
14
- end
15
-
16
- while true
17
- begin
18
- threads.each(&:join)
19
- exit(0)
20
- rescue Exception
21
- puts "Join: #{$!}"
22
- end
23
- end
24
-
25
- puts "Done"