expedite 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -8
- data/lib/expedite/action/block.rb +2 -1
- data/lib/expedite/action/boot.rb +7 -6
- data/lib/expedite/agents.rb +18 -16
- data/lib/expedite/client/agent_proxy.rb +6 -6
- data/lib/expedite/client/base.rb +4 -4
- data/lib/expedite/hooks.rb +46 -0
- data/lib/expedite/protocol.rb +29 -1
- data/lib/expedite/server/agent.rb +34 -28
- data/lib/expedite/server/agent_boot.rb +1 -1
- data/lib/expedite/server/agent_manager.rb +25 -23
- data/lib/expedite/server/controller.rb +5 -9
- data/lib/expedite/syntax.rb +4 -2
- data/lib/expedite/version.rb +1 -1
- data/lib/expedite.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ece07855912fe5042042713eb78fecedc03cd06f5b495c0f17a1e7dab14ee99e
|
|
4
|
+
data.tar.gz: c94ea277e1a83968b187648d5917ed2e42181c81f3a3a04c4c6acafc1c52fbf5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb9688825664432ab5e7f5ef60ee855715eabcf6e25ee9242c6eca816c99bb7431eb36ad12b1124e11401dd961b4d68868077c41c9dd8f6b5bb20ffc854a1e09
|
|
7
|
+
data.tar.gz: baf6f7c68c3f98eccf8651947b72dd7e3150580d886015038e7ccd68e0c63798db82e8b6977c1f974a1c027112a233dc0fc227b002cb763151c3916fbda58a5f
|
data/README.md
CHANGED
|
@@ -16,7 +16,9 @@ This is the "parent" agent:
|
|
|
16
16
|
```
|
|
17
17
|
Expedite.define do
|
|
18
18
|
agent :parent do
|
|
19
|
-
|
|
19
|
+
before(:serve) do |name|
|
|
20
|
+
$parent_var = name
|
|
21
|
+
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
```
|
|
@@ -26,8 +28,12 @@ matchers.
|
|
|
26
28
|
|
|
27
29
|
```
|
|
28
30
|
Expedite.define do
|
|
29
|
-
agent "development/*"
|
|
30
|
-
|
|
31
|
+
agent "development/*" do
|
|
32
|
+
self.parent = :parent
|
|
33
|
+
|
|
34
|
+
before(:serve) do |name|
|
|
35
|
+
$child_var = name
|
|
36
|
+
end
|
|
31
37
|
end
|
|
32
38
|
end
|
|
33
39
|
```
|
|
@@ -37,10 +43,12 @@ The following defines an `info` action.
|
|
|
37
43
|
```
|
|
38
44
|
Expedite.define do
|
|
39
45
|
action :info do
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
{
|
|
47
|
+
"Process.pid" => Process.pid,
|
|
48
|
+
"Process.ppid" => Process.ppid,
|
|
49
|
+
"$parent_var" => $parent_var,
|
|
50
|
+
"$child_var" => $child_var,
|
|
51
|
+
}
|
|
44
52
|
end
|
|
45
53
|
end
|
|
46
54
|
```
|
|
@@ -55,7 +63,7 @@ the action; in that case, the return result is the exit code.
|
|
|
55
63
|
```
|
|
56
64
|
require 'expedite'
|
|
57
65
|
|
|
58
|
-
Expedite.agent("development/abc").invoke("info")
|
|
66
|
+
puts Expedite.agent("development/abc").invoke("info")
|
|
59
67
|
```
|
|
60
68
|
|
|
61
69
|
When you run `main.rb`, the following output is produced. Note that `$sleep_parent`
|
|
@@ -3,7 +3,7 @@ module Expedite
|
|
|
3
3
|
module Action
|
|
4
4
|
class Block
|
|
5
5
|
attr_reader :runs_in
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
def initialize(runs_in: :application, &block)
|
|
8
8
|
@runs_in = runs_in
|
|
9
9
|
@block = block
|
|
@@ -13,6 +13,7 @@ module Expedite
|
|
|
13
13
|
@block.call(*args)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
# Ignoring all streams
|
|
16
17
|
def setup(_)
|
|
17
18
|
end
|
|
18
19
|
end
|
data/lib/expedite/action/boot.rb
CHANGED
|
@@ -2,12 +2,12 @@ module Expedite
|
|
|
2
2
|
module Action
|
|
3
3
|
class Boot
|
|
4
4
|
def call(*args)
|
|
5
|
-
|
|
5
|
+
name = args[0]
|
|
6
6
|
|
|
7
7
|
require "expedite/server/agent"
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
Expedite::Server::Agent.new(
|
|
10
|
-
|
|
10
|
+
name: name,
|
|
11
11
|
manager: UNIXSocket.for_fd(@child_socket.fileno),
|
|
12
12
|
env: Expedite::Env.new(
|
|
13
13
|
root: ENV['EXPEDITE_ROOT'],
|
|
@@ -16,9 +16,10 @@ module Expedite
|
|
|
16
16
|
).boot
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@log_file =
|
|
19
|
+
# STDOUT, STDERR, STDIN, log, child_socket
|
|
20
|
+
def setup(streams)
|
|
21
|
+
@log_file = streams[3]
|
|
22
|
+
@child_socket = streams[4]
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def runs_in
|
data/lib/expedite/agents.rb
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
require 'expedite/hooks'
|
|
1
2
|
|
|
2
3
|
module Expedite
|
|
3
4
|
# Definition of a Agent
|
|
4
5
|
class Agent
|
|
6
|
+
include Hooks
|
|
7
|
+
|
|
5
8
|
##
|
|
6
9
|
# Name of the parent agent. This allows you to create agents from
|
|
7
10
|
# an existing agent.
|
|
@@ -16,18 +19,20 @@ module Expedite
|
|
|
16
19
|
##
|
|
17
20
|
# [parent] Name of parent agent.
|
|
18
21
|
# [keep_alive] Specifies if the agent should be automatically restarted if it is terminated. Defaults to false.
|
|
19
|
-
|
|
20
|
-
def initialize(parent: nil, keep_alive: false, &after_fork)
|
|
22
|
+
def initialize(parent: nil, keep_alive: false)
|
|
21
23
|
@parent = parent
|
|
22
24
|
@keep_alive = keep_alive
|
|
23
|
-
@after_fork_proc = after_fork
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
##
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
def
|
|
30
|
-
|
|
28
|
+
# Register a before event
|
|
29
|
+
# @params event [String] Allowed values: :run
|
|
30
|
+
def before(event, &block)
|
|
31
|
+
register_hook(:"before_#{event}", block)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def after(event, &block)
|
|
35
|
+
register_hook(:"after_#{event}", block)
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
|
|
@@ -54,8 +59,6 @@ module Expedite
|
|
|
54
59
|
#
|
|
55
60
|
# [matcher] Wildcard to match a name against.
|
|
56
61
|
# [named_options] Agent options.
|
|
57
|
-
# [after_fork] Optional block that is called when
|
|
58
|
-
# agent is preloaded.
|
|
59
62
|
#
|
|
60
63
|
# = Example
|
|
61
64
|
# Expedite::Agents.register('base' do |name|
|
|
@@ -64,8 +67,8 @@ module Expedite
|
|
|
64
67
|
# Expedite::Agents.register('development/abc', parent: 'base') do |name|
|
|
65
68
|
# puts "Agent #{name} started"
|
|
66
69
|
# end
|
|
67
|
-
def self.register(matcher, **named_options
|
|
68
|
-
self.current.register(matcher.to_s, **named_options
|
|
70
|
+
def self.register(matcher, **named_options)
|
|
71
|
+
self.current.register(matcher.to_s, **named_options)
|
|
69
72
|
end
|
|
70
73
|
|
|
71
74
|
##
|
|
@@ -86,11 +89,10 @@ module Expedite
|
|
|
86
89
|
ret.agent
|
|
87
90
|
end
|
|
88
91
|
|
|
89
|
-
def register(matcher, **named_options
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)
|
|
92
|
+
def register(matcher, **named_options)
|
|
93
|
+
agent = Agent.new(**named_options)
|
|
94
|
+
@registrations << Registration.new(matcher, agent)
|
|
95
|
+
agent
|
|
94
96
|
end
|
|
95
97
|
|
|
96
98
|
def reset
|
|
@@ -4,23 +4,23 @@ require 'expedite/client/invoke'
|
|
|
4
4
|
module Expedite
|
|
5
5
|
module Client
|
|
6
6
|
class AgentProxy
|
|
7
|
-
attr_accessor :
|
|
7
|
+
attr_accessor :name, :env
|
|
8
8
|
|
|
9
9
|
##
|
|
10
10
|
#
|
|
11
|
+
# @param name [String] Name of the agent
|
|
11
12
|
# @param env [Expedite::Env] Environment
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
def initialize(name, env:)
|
|
14
|
+
self.name = name
|
|
14
15
|
self.env = env
|
|
15
|
-
self.agent = agent
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def exec(*args)
|
|
19
|
-
Client::Exec.new(env: env, agent:
|
|
19
|
+
Client::Exec.new(env: env, agent: name).call(*args)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def invoke(*args)
|
|
23
|
-
Client::Invoke.new(env: env, agent:
|
|
23
|
+
Client::Invoke.new(env: env, agent: name).call(*args)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
data/lib/expedite/client/base.rb
CHANGED
|
@@ -59,11 +59,11 @@ module Expedite
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def run_command(client, agent, args)
|
|
62
|
+
@null_socket ||= File.open(File::NULL, "a")
|
|
62
63
|
log "sending command"
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
agent.
|
|
66
|
-
agent.send_io STDIN
|
|
65
|
+
# No child socket
|
|
66
|
+
agent.send_setup(@null_socket, env)
|
|
67
67
|
|
|
68
68
|
agent.send_object({
|
|
69
69
|
"args" => args,
|
|
@@ -85,7 +85,7 @@ module Expedite
|
|
|
85
85
|
## suspend_resume_on_tstp_cont(pid)
|
|
86
86
|
|
|
87
87
|
## forward_signals(application)
|
|
88
|
-
result = agent.recv_object
|
|
88
|
+
result = agent.recv_object(env)
|
|
89
89
|
if result.key?("exception")
|
|
90
90
|
e = result["exception"]
|
|
91
91
|
log "got exception #{e}"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Expedite
|
|
2
|
+
module Hooks
|
|
3
|
+
##
|
|
4
|
+
# Register a new hook with the given block to name
|
|
5
|
+
# @param name [String] Name of the hook
|
|
6
|
+
def register_hook(name, block)
|
|
7
|
+
return clear_hooks(name) if block.nil?
|
|
8
|
+
|
|
9
|
+
block = Array(block)
|
|
10
|
+
all_hooks[name].concat(block)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Clears all hooks for the specified name
|
|
15
|
+
# @param name [String] Name of the hook
|
|
16
|
+
def clear_hooks(name)
|
|
17
|
+
all_hooks[name] = []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Returns all hooks for the specified name
|
|
22
|
+
# @param name [String] Name of the hook
|
|
23
|
+
def hooks(name)
|
|
24
|
+
all_hooks[name]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Returne all hooks as a hash
|
|
29
|
+
def all_hooks
|
|
30
|
+
@all_hooks ||= Hash.new { |h, k| h[k] = [] }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Runs all Procs registered for the specified name
|
|
35
|
+
# @param name [String] Name of the hook
|
|
36
|
+
# @param @args Arguments passed to the Procs
|
|
37
|
+
def run_hook(name, *args)
|
|
38
|
+
hks = hooks(name)
|
|
39
|
+
return if hks.empty?
|
|
40
|
+
|
|
41
|
+
hks.each do |hook|
|
|
42
|
+
args.any? ? hook.call(*args) : hook.call
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/expedite/protocol.rb
CHANGED
|
@@ -8,6 +8,7 @@ module Expedite
|
|
|
8
8
|
|
|
9
9
|
self.puts data.bytesize.to_i
|
|
10
10
|
self.write data
|
|
11
|
+
self.write "$"
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
##
|
|
@@ -29,11 +30,38 @@ module Expedite
|
|
|
29
30
|
self.send_object({"return" => obj}, env)
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
def recv_object
|
|
33
|
+
def recv_object(env)
|
|
33
34
|
len = self.gets.to_i
|
|
34
35
|
data = self.read(len)
|
|
36
|
+
e = self.read(1)
|
|
37
|
+
env.log "recv_object len=#{len} data=... e=#{e}"
|
|
38
|
+
raise "Unexpected end #{e}" if e != "$"
|
|
35
39
|
Marshal.load(data)
|
|
36
40
|
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# Send sockets for setup.
|
|
45
|
+
# Linux seems to require all fds to be sent first
|
|
46
|
+
#
|
|
47
|
+
def send_setup(child_socket, env)
|
|
48
|
+
self.send_io STDOUT
|
|
49
|
+
self.send_io STDERR
|
|
50
|
+
self.send_io STDIN
|
|
51
|
+
self.send_io env.log_file
|
|
52
|
+
self.send_io child_socket
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Receive setup sockets.
|
|
57
|
+
# Returns the child_socket
|
|
58
|
+
#
|
|
59
|
+
def recv_setup(env)
|
|
60
|
+
streams = 5.times.map { self.recv_io }
|
|
61
|
+
[STDOUT, STDERR, STDIN].zip(streams[0..2]).each { |a, b| a.reopen(b) }
|
|
62
|
+
env.log_file = streams[3]
|
|
63
|
+
return streams
|
|
64
|
+
end
|
|
37
65
|
end
|
|
38
66
|
end
|
|
39
67
|
|
|
@@ -4,11 +4,11 @@ require 'pty'
|
|
|
4
4
|
require 'set'
|
|
5
5
|
require 'socket'
|
|
6
6
|
require 'expedite/actions'
|
|
7
|
+
require 'expedite/agents'
|
|
7
8
|
require 'expedite/env'
|
|
8
9
|
require 'expedite/failsafe_thread'
|
|
9
10
|
require 'expedite/protocol'
|
|
10
11
|
require 'expedite/signals'
|
|
11
|
-
require 'expedite/agents'
|
|
12
12
|
|
|
13
13
|
module Expedite
|
|
14
14
|
def self.agent
|
|
@@ -33,11 +33,12 @@ module Expedite
|
|
|
33
33
|
class Agent
|
|
34
34
|
include Signals
|
|
35
35
|
|
|
36
|
-
attr_reader :
|
|
36
|
+
attr_reader :name
|
|
37
37
|
attr_reader :manager, :env
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
# @params name [String] Name of agent
|
|
40
|
+
def initialize(name:, manager:, env:)
|
|
41
|
+
@name = name
|
|
41
42
|
@manager = manager
|
|
42
43
|
@env = env
|
|
43
44
|
@mutex = Mutex.new
|
|
@@ -56,8 +57,8 @@ module Expedite
|
|
|
56
57
|
Signal.trap("TERM") { terminate }
|
|
57
58
|
|
|
58
59
|
env.load_helper
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
|
|
61
|
+
serve
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
def state(val)
|
|
@@ -75,8 +76,12 @@ module Expedite
|
|
|
75
76
|
env.app_name
|
|
76
77
|
end
|
|
77
78
|
|
|
79
|
+
def agent
|
|
80
|
+
@agent ||= Expedite::Agents.lookup(name)
|
|
81
|
+
end
|
|
82
|
+
|
|
78
83
|
def log(message)
|
|
79
|
-
env.log "[application:#{
|
|
84
|
+
env.log "[application:#{name}] #{message}"
|
|
80
85
|
end
|
|
81
86
|
|
|
82
87
|
def preloaded?
|
|
@@ -112,10 +117,10 @@ module Expedite
|
|
|
112
117
|
with_pty { preload }
|
|
113
118
|
end
|
|
114
119
|
|
|
115
|
-
def
|
|
116
|
-
$0 = "expedite agent | #{app_name} | #{
|
|
120
|
+
def serve
|
|
121
|
+
$0 = "expedite agent | #{app_name} | #{name}"
|
|
117
122
|
|
|
118
|
-
|
|
123
|
+
agent.run_hook(:before_serve, name)
|
|
119
124
|
|
|
120
125
|
state :running
|
|
121
126
|
manager.puts
|
|
@@ -124,36 +129,37 @@ module Expedite
|
|
|
124
129
|
IO.select [manager, @interrupt.first]
|
|
125
130
|
|
|
126
131
|
if terminating? || preload_failed?
|
|
132
|
+
agent.run_hook(:after_serve, name)
|
|
127
133
|
exit
|
|
128
134
|
else
|
|
129
|
-
|
|
135
|
+
serve_request(manager.recv_io(UNIXSocket))
|
|
130
136
|
end
|
|
131
137
|
end
|
|
132
138
|
end
|
|
133
139
|
|
|
134
|
-
def
|
|
140
|
+
def serve_request(client)
|
|
135
141
|
puts "got client"
|
|
136
142
|
manager.puts
|
|
137
143
|
|
|
138
|
-
|
|
139
|
-
[STDOUT, STDERR, STDIN].zip(streams).each { |a, b| a.reopen(b) }
|
|
144
|
+
streams = client.recv_setup(env)
|
|
140
145
|
|
|
141
146
|
preload unless preloaded?
|
|
142
147
|
|
|
143
|
-
|
|
144
|
-
log "serve #{
|
|
148
|
+
cargs, cenv, cmethod = client.recv_object(env).values_at("args", "env", "method")
|
|
149
|
+
log "serve #{cargs} using #{cmethod}"
|
|
145
150
|
|
|
146
|
-
exec_name =
|
|
151
|
+
exec_name = cargs.shift
|
|
147
152
|
action = Expedite::Actions.lookup(exec_name)
|
|
148
|
-
action.setup(
|
|
153
|
+
action.setup(streams)
|
|
154
|
+
# TODO: before(:request)
|
|
149
155
|
|
|
150
156
|
connect_database # why are we connecting prior? is this for invoke?
|
|
151
|
-
pid = case
|
|
157
|
+
pid = case cmethod
|
|
152
158
|
when "invoke"
|
|
153
159
|
# TODO: Invoke in a worker process instead of the preloader
|
|
154
|
-
serve_invoke(client, action,
|
|
160
|
+
serve_invoke(client, action, cargs, cenv)
|
|
155
161
|
else
|
|
156
|
-
serve_fork(client, action,
|
|
162
|
+
serve_fork(client, action, cargs, cenv)
|
|
157
163
|
end
|
|
158
164
|
|
|
159
165
|
disconnect_database
|
|
@@ -186,25 +192,25 @@ module Expedite
|
|
|
186
192
|
end
|
|
187
193
|
|
|
188
194
|
# Returns pid of the current process
|
|
189
|
-
def serve_invoke(client, action,
|
|
195
|
+
def serve_invoke(client, action, cargs, cenv)
|
|
190
196
|
begin
|
|
191
|
-
ret = action.call(*
|
|
197
|
+
ret = action.call(*cargs)
|
|
192
198
|
rescue Exception => e
|
|
193
|
-
client.
|
|
199
|
+
client.send_exception(e, self.env)
|
|
194
200
|
else
|
|
195
|
-
client.
|
|
201
|
+
client.send_return(ret, self.env)
|
|
196
202
|
end
|
|
197
203
|
Process.pid
|
|
198
204
|
end
|
|
199
205
|
|
|
200
|
-
def serve_fork(client, action,
|
|
206
|
+
def serve_fork(client, action, cargs, cenv)
|
|
201
207
|
fork do
|
|
202
208
|
Process.setsid
|
|
203
209
|
IGNORE_SIGNALS.each { |sig| trap(sig, "DEFAULT") }
|
|
204
210
|
trap("TERM", "DEFAULT")
|
|
205
211
|
|
|
206
212
|
# Load in the current env vars, except those which *were* changed when Spring started
|
|
207
|
-
|
|
213
|
+
cenv.each { |k, v| ENV[k] = v }
|
|
208
214
|
|
|
209
215
|
# requiring is faster, so if config.cache_classes was true in
|
|
210
216
|
# the environment's config file, then we can respect that from
|
|
@@ -221,7 +227,7 @@ module Expedite
|
|
|
221
227
|
shush_backtraces
|
|
222
228
|
|
|
223
229
|
begin
|
|
224
|
-
ret = action.call(*
|
|
230
|
+
ret = action.call(*cargs)
|
|
225
231
|
rescue => e
|
|
226
232
|
client.send_exception(e, self.env)
|
|
227
233
|
else
|
|
@@ -82,7 +82,7 @@ module Expedite
|
|
|
82
82
|
end
|
|
83
83
|
rescue Exception => e
|
|
84
84
|
# NotImplementedError is an Exception, not StandardError
|
|
85
|
-
client.
|
|
85
|
+
client.send_exception(e, env)
|
|
86
86
|
return Process.pid
|
|
87
87
|
rescue Errno::ECONNRESET, Errno::EPIPE => e
|
|
88
88
|
log "#{e} while reading from child; returning no pid"
|
|
@@ -95,9 +95,10 @@ module Expedite
|
|
|
95
95
|
log "stopping"
|
|
96
96
|
@state = :stopping
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
Process.
|
|
98
|
+
_pid = self.pid
|
|
99
|
+
if _pid
|
|
100
|
+
Process.kill('TERM', _pid)
|
|
101
|
+
Process.wait(_pid)
|
|
101
102
|
end
|
|
102
103
|
rescue Errno::ESRCH, Errno::ECHILD
|
|
103
104
|
# Don't care
|
|
@@ -123,30 +124,31 @@ module Expedite
|
|
|
123
124
|
|
|
124
125
|
# Creates a child that is forked from a parent
|
|
125
126
|
def fork_child(preload = false)
|
|
126
|
-
|
|
127
|
+
child_socket = nil
|
|
128
|
+
wr = nil
|
|
129
|
+
begin
|
|
130
|
+
@child, child_socket = UNIXSocket.pair(:STREAM)
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
wr.send_io STDOUT
|
|
131
|
-
wr.send_io STDERR
|
|
132
|
-
wr.send_io STDIN
|
|
132
|
+
# Compose command
|
|
133
|
+
wr, rd = UNIXSocket.pair(:STREAM)
|
|
133
134
|
|
|
134
|
-
|
|
135
|
-
'args' => ['expedite/boot', name],
|
|
136
|
-
'env' => {},
|
|
137
|
-
'method' => "fork",
|
|
138
|
-
}, env)
|
|
135
|
+
wr.send_setup(child_socket, env)
|
|
139
136
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
wr.send_object({
|
|
138
|
+
'args' => ['expedite/boot', name],
|
|
139
|
+
'env' => {},
|
|
140
|
+
'method' => "fork",
|
|
141
|
+
}, env)
|
|
143
142
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
@pid = env.applications.with(parent) do |target|
|
|
144
|
+
target.run(rd)
|
|
145
|
+
end
|
|
147
146
|
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
start_wait_thread(pid, child) if child.gets
|
|
148
|
+
ensure
|
|
149
|
+
wr&.close
|
|
150
|
+
child_socket&.close
|
|
151
|
+
end
|
|
150
152
|
end
|
|
151
153
|
|
|
152
154
|
# Creates a child that is started from scratch
|
|
@@ -102,7 +102,7 @@ module Expedite
|
|
|
102
102
|
|
|
103
103
|
# Corresponds to Client::Invoke#connect_to_agent
|
|
104
104
|
app_client = client.recv_io
|
|
105
|
-
command = client.recv_object
|
|
105
|
+
command = client.recv_object(env)
|
|
106
106
|
|
|
107
107
|
args, agent = command.values_at("args", "agent")
|
|
108
108
|
cmd = args.first
|
|
@@ -114,9 +114,7 @@ module Expedite
|
|
|
114
114
|
client.puts
|
|
115
115
|
|
|
116
116
|
unix_socket = UNIXSocket.for_fd(app_client.fileno)
|
|
117
|
-
|
|
118
|
-
_stderr = unix_socket.recv_io
|
|
119
|
-
_stdin = unix_socket.recv_io
|
|
117
|
+
_ = unix_socket.recv_setup(env)
|
|
120
118
|
|
|
121
119
|
client.puts Process.pid
|
|
122
120
|
|
|
@@ -124,7 +122,7 @@ module Expedite
|
|
|
124
122
|
env.applications.pools.each do |k, pool|
|
|
125
123
|
application_pids.concat(pool.all.map(&:pid))
|
|
126
124
|
end
|
|
127
|
-
unix_socket.
|
|
125
|
+
unix_socket.send_return(application_pids, env)
|
|
128
126
|
|
|
129
127
|
unix_socket.close
|
|
130
128
|
client.close
|
|
@@ -142,11 +140,9 @@ module Expedite
|
|
|
142
140
|
end
|
|
143
141
|
rescue AgentNotFoundError => e
|
|
144
142
|
unix_socket = UNIXSocket.for_fd(app_client.fileno)
|
|
145
|
-
|
|
146
|
-
_stderr = unix_socket.recv_io
|
|
147
|
-
_stdin = unix_socket.recv_io
|
|
143
|
+
_ = unix_socket.recv_setup(env)
|
|
148
144
|
|
|
149
|
-
args, env = unix_socket.recv_object.values_at("args", "env")
|
|
145
|
+
args, env = unix_socket.recv_object(env).values_at("args", "env")
|
|
150
146
|
|
|
151
147
|
client.puts Process.pid
|
|
152
148
|
|
data/lib/expedite/syntax.rb
CHANGED
|
@@ -13,7 +13,9 @@ module Expedite
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def agent(name, parent:nil, &block)
|
|
16
|
-
Expedite::Agents.register(name, parent: parent
|
|
16
|
+
agent = Expedite::Agents.register(name, parent: parent)
|
|
17
|
+
agent.instance_eval(&block) if !block.nil?
|
|
18
|
+
agent
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def self.run(&block)
|
|
@@ -23,4 +25,4 @@ module Expedite
|
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
extend Syntax
|
|
26
|
-
end
|
|
28
|
+
end
|
data/lib/expedite/version.rb
CHANGED
data/lib/expedite.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: expedite
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bing-Chang Lai
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-02-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Manages Ruby processes that can be used to spawn child processes faster.
|
|
14
14
|
email: johnny.lai@me.com
|
|
@@ -37,6 +37,7 @@ files:
|
|
|
37
37
|
- lib/expedite/errors.rb
|
|
38
38
|
- lib/expedite/failsafe_thread.rb
|
|
39
39
|
- lib/expedite/helper/rails.rb
|
|
40
|
+
- lib/expedite/hooks.rb
|
|
40
41
|
- lib/expedite/protocol.rb
|
|
41
42
|
- lib/expedite/server/agent.rb
|
|
42
43
|
- lib/expedite/server/agent_boot.rb
|