expedite 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c3af01b23cd76fd62beb91411f18fd9535c49cca41b530496f2031abc294b67
4
- data.tar.gz: 260e78502a54f80f3c101f0880a79f738d68bf414adc401253d5cfec0a2837b9
3
+ metadata.gz: da93957645e66819877d4c8638d2d42eb4880c631d6b4f8f224a3a9502c45a36
4
+ data.tar.gz: 179e78a453744f0375f6b184ffa1a2cff321b7ab92deafc9be5297fb00c63c4b
5
5
  SHA512:
6
- metadata.gz: 0b0fdaa31cf55dd0fde167748208e5f1f1be5b8cb1b2def68cae75516df458614855e4c1c2bb4affec937dc7d7c43c4d8f04bb830998ff5c9ab7d6c6b65bf9e7
7
- data.tar.gz: d59acca092ec657cadc977c2af264cf811b4cf1b601e5bd8074bd21d91424b3fc07e81930bde3443bdce51e05965541dd132a819a1d5fa4812f6fd32b0809b95
6
+ metadata.gz: 8cf3e2d403eab2d5cb7960a1d5cc43a4f94c3d0495ce36b360d32ec77ad7e5f9887a0e7aca183afa2e441ac3ff23a555ec6254f8441d971783376bdfc84db471
7
+ data.tar.gz: 30f00102d8d8c6cc59f138841caa116421f3002871551dca20718dfc5100aec80f469e8bb31b1d1ee8158020852090b2c053bff5d5fd7c9c728fdc26e4c3c6d0
data/README.md CHANGED
@@ -89,6 +89,13 @@ You can also start the server in the foreground.
89
89
  $ bundle exec expedite server
90
90
  ```
91
91
 
92
+ If `rails` is in the `Gemfile`, then you can also start the rails commands through expedite.
93
+
94
+ ```
95
+ $ bundle exec expedite rails console
96
+ $ echo "puts ActiveRecord::Base.connection" | bundle exec expedite rails runner -
97
+ ```
98
+
92
99
  ## Acknowledgements
93
100
 
94
101
  Expedite's server core is modified from [Spring](https://github.com/rails/spring)
@@ -35,9 +35,9 @@ module Expedite
35
35
  end
36
36
 
37
37
  def lookup(name)
38
- ret = @registrations[name]
39
- raise NotImplementedError, "Action #{name.inspect} not found" if ret.nil?
40
- ret
38
+ ret = @registrations[name.to_s]
39
+ raise NotImplementedError, "Action #{name.inspect} not found" if ret.nil?
40
+ ret
41
41
  end
42
42
 
43
43
  def register(name, klass_or_nil = nil, **named_options, &block)
@@ -47,7 +47,7 @@ module Expedite
47
47
  klass_or_nil.new(**named_options)
48
48
  end
49
49
 
50
- @registrations[name] = cmd
50
+ @registrations[name.to_s] = cmd
51
51
  end
52
52
 
53
53
  def reset
@@ -82,7 +82,7 @@ module Expedite
82
82
  ret = @registrations.find do |r|
83
83
  r.match?(agent)
84
84
  end
85
- raise NotImplementedError, "Agent #{agent.inspect} not found" if ret.nil?
85
+ raise AgentNotFoundError, "Agent #{agent.inspect} not found" if ret.nil?
86
86
  ret.agent
87
87
  end
88
88
 
@@ -0,0 +1,13 @@
1
+ module Expedite
2
+ module Cli
3
+ class Rails
4
+ def run(args)
5
+ Expedite.agent(:rails_environment).exec(:rails_commands, args)
6
+ end
7
+
8
+ def summary
9
+ 'Starts the expedite server'
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/expedite/cli.rb CHANGED
@@ -1,16 +1,20 @@
1
+ require 'expedite/cli/rails'
1
2
  require 'expedite/cli/server'
2
3
  require 'expedite/cli/status'
3
4
  require 'expedite/cli/stop'
4
5
 
5
6
  module Expedite
6
7
  module Cli
8
+ class UnknownCommandError < StandardError
9
+ end
10
+
7
11
  class Help
8
12
  def run(args)
9
13
  puts "Expected: <command>"
10
14
  puts
11
15
  puts "Commands:"
12
16
 
13
- cmds = Expedite::Cli::COMMANDS
17
+ cmds = Expedite::Cli.commands
14
18
  cmds.keys.sort!.each do |cmd|
15
19
  c = cmds[cmd].new
16
20
  puts " #{cmd}: #{c.summary}"
@@ -24,22 +28,29 @@ module Expedite
24
28
 
25
29
  module_function
26
30
 
27
- COMMANDS = {
28
- 'help' => Cli::Help,
29
- 'server' => Cli::Server,
30
- 'status' => Cli::Status,
31
- 'stop' => Cli::Stop,
32
- }
31
+ def commands
32
+ return @commands unless @commands.nil?
33
+
34
+ cmds = {
35
+ 'help' => Cli::Help,
36
+ 'server' => Cli::Server,
37
+ 'status' => Cli::Status,
38
+ 'stop' => Cli::Stop,
39
+ }
40
+ cmds['rails'] = Cli::Rails if Gem.loaded_specs["rails"]
41
+ @commands = cmds
42
+ end
33
43
 
34
44
  def run(args)
35
45
  command(args.first).run(args[1..])
36
- rescue NotImplementedError
46
+ rescue UnknownCommandError => e
47
+ STDERR.puts e
37
48
  Cli::Help.new.run([])
38
49
  end
39
50
 
40
51
  def command(cmd)
41
- klass = COMMANDS[cmd]
42
- raise NotImplementedError, "Unknown command '#{cmd}'" if klass.nil?
52
+ klass = commands[cmd]
53
+ raise UnknownCommandError, "Unknown command '#{cmd}'" if klass.nil?
43
54
  klass.new
44
55
  end
45
56
  end
@@ -58,7 +58,16 @@ module Expedite
58
58
  def run
59
59
  status = perform(*@args)
60
60
 
61
- exit status.to_i
61
+ code = if status.respond_to?(:to_i)
62
+ status.to_i
63
+ elsif status == true
64
+ 0
65
+ elsif status == false
66
+ 1
67
+ else
68
+ 126
69
+ end
70
+ exit code
62
71
  rescue Errno::ECONNRESET
63
72
  exit 1
64
73
  end
@@ -49,7 +49,7 @@ module Expedite
49
49
  def connect_to_agent(client, args)
50
50
  server.send_io client
51
51
 
52
- server.send_object("args" => args, "agent" => agent)
52
+ server.send_object({"args" => args, "agent" => agent}, env)
53
53
 
54
54
  if IO.select([server], [], [], CONNECT_TIMEOUT)
55
55
  server.gets or raise CommandNotFound
@@ -65,7 +65,11 @@ module Expedite
65
65
  agent.send_io STDERR
66
66
  agent.send_io STDIN
67
67
 
68
- agent.send_object("args" => args, "env" => ENV.to_hash)
68
+ agent.send_object({
69
+ "args" => args,
70
+ "env" => ENV.to_hash,
71
+ "method" => "invoke"
72
+ }, env)
69
73
 
70
74
  pid = server.gets
71
75
  pid = pid.chomp if pid
data/lib/expedite/env.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'digest'
2
2
  require 'pathname'
3
3
  require 'expedite/version'
4
- require 'expedite/server/agent_manager'
4
+ require 'expedite/server/application_manager'
5
5
 
6
6
  module Expedite
7
7
  class Env
@@ -18,9 +18,7 @@ module Expedite
18
18
  @application_id = Digest::SHA1.hexdigest(@root)
19
19
 
20
20
  env = self
21
- @applications = Hash.new do |h, k|
22
- h[k] = Server::AgentManager.new(k, env)
23
- end
21
+ @applications = Server::ApplicationManager.new(env)
24
22
  end
25
23
 
26
24
  def version
@@ -8,4 +8,7 @@ module Expedite
8
8
 
9
9
  class UnknownError < Error
10
10
  end
11
+
12
+ class AgentNotFoundError < Error
13
+ end
11
14
  end
@@ -0,0 +1,14 @@
1
+ Expedite.define do
2
+ # Agent that rails environment loaded
3
+ agent :rails_environment do
4
+ app_root = Dir.pwd
5
+ require "#{app_root}/config/environment.rb"
6
+ end
7
+
8
+ # Actions that runs rails commands
9
+ action :rails_commands do |args|
10
+ ARGV.replace(args)
11
+ require "rails/commands"
12
+ true
13
+ end
14
+ end
@@ -2,17 +2,20 @@ require 'socket'
2
2
 
3
3
  module Expedite
4
4
  module Protocol
5
- def send_object(object)
5
+ def send_object(object, env)
6
+ env.log "send_object #{object.inspect}"
6
7
  data = Marshal.dump(object)
7
8
 
8
- self.puts data.bytesize
9
+ self.puts data.bytesize.to_i
9
10
  self.write data
10
11
  end
11
12
 
12
13
  def recv_object
13
- Marshal.load(self.read(self.gets.to_i))
14
+ len = self.gets.to_i
15
+ data = self.read(len)
16
+ Marshal.load(data)
14
17
  end
15
18
  end
16
19
  end
17
20
 
18
- UNIXSocket.include ::Expedite::Protocol
21
+ IO.include ::Expedite::Protocol
@@ -23,6 +23,13 @@ module Expedite
23
23
  end
24
24
 
25
25
  module Server
26
+ # This code runs in the process that has the actual code pre-loaded, and is
27
+ # used to serve requests.
28
+ # * An "invoke" request is handled in the agent itself.
29
+ # * A "fork" request causes the agent to fork, and the forked process handles
30
+ # the request.
31
+ # Each agent processes a single request at a time, unless it is an
32
+ # Expedite::Action::Boot request which is used to make derived agents.
26
33
  class Agent
27
34
  include Signals
28
35
 
@@ -125,7 +132,7 @@ module Expedite
125
132
  end
126
133
 
127
134
  def serve(client)
128
- log "got client"
135
+ puts "got client"
129
136
  manager.puts
130
137
 
131
138
  _stdout, stderr, _stdin = streams = 3.times.map { client.recv_io }
@@ -133,48 +140,23 @@ module Expedite
133
140
 
134
141
  preload unless preloaded?
135
142
 
136
- args, env = client.recv_object.values_at("args", "env")
143
+ args, env, method = client.recv_object.values_at("args", "env", "method")
137
144
 
138
145
  exec_name = args.shift
139
146
  action = Expedite::Actions.lookup(exec_name)
140
147
  action.setup(client)
141
148
 
142
- connect_database
143
-
144
- pid = fork do
145
- Process.setsid
146
- IGNORE_SIGNALS.each { |sig| trap(sig, "DEFAULT") }
147
- trap("TERM", "DEFAULT")
148
-
149
- # Load in the current env vars, except those which *were* changed when Spring started
150
- env.each { |k, v| ENV[k] = v }
151
-
152
- # requiring is faster, so if config.cache_classes was true in
153
- # the environment's config file, then we can respect that from
154
- # here on as we no longer need constant reloading.
155
- if @original_cache_classes
156
- ActiveSupport::Dependencies.mechanism = :require
157
- Rails.application.config.cache_classes = true
158
- end
159
-
160
- connect_database
161
- srand
162
-
163
- invoke_after_fork_callbacks
164
- shush_backtraces
165
-
166
- begin
167
- ret = action.call(*args)
168
- rescue => e
169
- client.send_object("exception" => e)
170
- else
171
- client.send_object("return" => ret )
172
- end
149
+ connect_database # why are we connecting prior? is this for invoke?
150
+ pid = case method
151
+ when "invoke"
152
+ serve_invoke(client, action, args, env)
153
+ else
154
+ serve_fork(client, action, args, env)
173
155
  end
174
156
 
175
157
  disconnect_database
176
158
 
177
- log "forked #{pid}"
159
+ log "forked #{pid}" # pid is current process
178
160
  manager.puts pid
179
161
 
180
162
  # Boot makes a new application, so we don't wait for it
@@ -201,6 +183,51 @@ module Expedite
201
183
  reset_streams
202
184
  end
203
185
 
186
+ # Returns pid of the current process
187
+ def serve_invoke(client, action, args, env)
188
+ begin
189
+ ret = action.call(*args)
190
+ rescue Exception => e
191
+ client.send_object({"exception" => e}, self.env)
192
+ else
193
+ client.send_object({"return" => ret}, self.env)
194
+ end
195
+ Process.pid
196
+ end
197
+
198
+ def serve_fork(client, action, args, env)
199
+ fork do
200
+ Process.setsid
201
+ IGNORE_SIGNALS.each { |sig| trap(sig, "DEFAULT") }
202
+ trap("TERM", "DEFAULT")
203
+
204
+ # Load in the current env vars, except those which *were* changed when Spring started
205
+ env.each { |k, v| ENV[k] = v }
206
+
207
+ # requiring is faster, so if config.cache_classes was true in
208
+ # the environment's config file, then we can respect that from
209
+ # here on as we no longer need constant reloading.
210
+ if @original_cache_classes
211
+ ActiveSupport::Dependencies.mechanism = :require
212
+ Rails.application.config.cache_classes = true
213
+ end
214
+
215
+ connect_database
216
+ srand
217
+
218
+ invoke_after_fork_callbacks
219
+ shush_backtraces
220
+
221
+ begin
222
+ ret = action.call(*args)
223
+ rescue => e
224
+ client.send_object({"exception" => e}, self.env)
225
+ else
226
+ client.send_object({"return" => ret}, self.env)
227
+ end
228
+ end
229
+ end
230
+
204
231
  def terminate
205
232
  if exiting?
206
233
  # Ensure that we do not ignore subsequent termination attempts
@@ -283,19 +310,28 @@ module Expedite
283
310
  end
284
311
 
285
312
  def wait(pid, streams, client)
286
- @mutex.synchronize { @waiting << pid }
313
+ if pid != Process.pid
314
+ @mutex.synchronize { @waiting << pid }
315
+ end
287
316
 
288
317
  # Wait in a separate thread so we can run multiple actions at once
289
318
  Expedite.failsafe_thread {
290
319
  begin
291
- _, status = Process.wait2 pid
292
- log "#{pid} exited with #{status.exitstatus}"
320
+ exitstatue = if pid == Process.pid
321
+ log "#{pid} is current process"
322
+ 0
323
+ else
324
+ _, status = Process.wait2 pid
325
+ log "#{pid} exited with #{status.exitstatus}"
326
+ end
293
327
 
294
328
  streams.each(&:close)
295
- client.puts(status.exitstatus)
329
+ client.puts(exitstatus)
296
330
  client.close
297
331
  ensure
298
- @mutex.synchronize { @waiting.delete pid }
332
+ if pid != Process.pid
333
+ @mutex.synchronize { @waiting.delete pid }
334
+ end
299
335
  exit_if_finished
300
336
  end
301
337
  }
@@ -7,6 +7,7 @@ require 'expedite/agents'
7
7
 
8
8
  module Expedite
9
9
  module Server
10
+ # Locates agent processes and spawns them if necessary
10
11
  class AgentManager
11
12
  attr_reader :pid, :child, :name, :env, :status, :agent
12
13
 
@@ -79,6 +80,10 @@ module Expedite
79
80
  log "got worker pid #{pid}"
80
81
  pid
81
82
  end
83
+ rescue Exception => e
84
+ # NotImplementedError is an Exception, not StandardError
85
+ client.send_object({"exception" => e}, env)
86
+ return Process.pid
82
87
  rescue Errno::ECONNRESET, Errno::EPIPE => e
83
88
  log "#{e} while reading from child; returning no pid"
84
89
  nil
@@ -116,6 +121,7 @@ module Expedite
116
121
  end
117
122
  end
118
123
 
124
+ # Creates a child that is forked from a parent
119
125
  def fork_child(preload = false)
120
126
  @child, child_socket = UNIXSocket.pair
121
127
 
@@ -125,42 +131,43 @@ module Expedite
125
131
  wr.send_io STDERR
126
132
  wr.send_io STDIN
127
133
 
128
- wr.send_object(
134
+ wr.send_object({
129
135
  'args' => ['expedite/boot', name],
130
- 'env' => {}
131
- )
136
+ 'env' => {},
137
+ 'method' => "fork",
138
+ }, env)
132
139
 
133
140
  wr.send_io child_socket
134
141
  wr.send_io env.log_file
135
142
  wr.close
136
143
 
137
- @pid = env.applications[parent].run(rd)
144
+ @pid = env.applications.with(parent) do |target|
145
+ target.run(rd)
146
+ end
138
147
 
139
148
  start_wait_thread(pid, child) if child.gets
140
149
  child_socket.close
141
150
  end
142
151
 
152
+ # Creates a child that is started from scratch
143
153
  def spawn_child(preload = false)
144
154
  @child, child_socket = UNIXSocket.pair
145
155
 
146
- Bundler.with_original_env do
147
- puts File.expand_path("..", __FILE__)
148
- bundler_dir = File.expand_path("../..", $LOADED_FEATURES.grep(/bundler\/setup\.rb$/).first)
149
- @pid = Process.spawn(
150
- {
151
- "EXPEDITE_VARIANT" => name,
152
- "EXPEDITE_ROOT" => env.root,
153
- },
154
- "ruby",
155
- *(bundler_dir != RbConfig::CONFIG["rubylibdir"] ? ["-I", bundler_dir] : []),
156
- "-I", File.expand_path("../../..", __FILE__),
157
- "-e", "require 'expedite/server/agent_boot'",
158
- 3 => child_socket,
159
- 4 => env.log_file,
160
- )
161
- end
156
+ bundler_dir = File.expand_path("../..", $LOADED_FEATURES.grep(/bundler\/setup\.rb$/).first)
157
+ @pid = Process.spawn(
158
+ {
159
+ "EXPEDITE_VARIANT" => name,
160
+ "EXPEDITE_ROOT" => env.root,
161
+ },
162
+ "ruby",
163
+ *(bundler_dir != RbConfig::CONFIG["rubylibdir"] ? ["-I", bundler_dir] : []),
164
+ "-I", File.expand_path("../../..", __FILE__),
165
+ "-e", "require 'expedite/server/agent_boot'",
166
+ 3 => child_socket,
167
+ 4 => env.log_file,
168
+ )
162
169
 
163
- start_wait_thread(pid, child) if child.gets
170
+ start_wait_thread(@pid, child) if child.gets
164
171
  child_socket.close
165
172
  end
166
173
 
@@ -0,0 +1,39 @@
1
+ require 'set'
2
+ require 'expedite/server/agent_manager'
3
+
4
+ module Expedite
5
+ module Server
6
+ class AgentPool
7
+ def initialize(name, env)
8
+ @name = name
9
+ @env = env
10
+ @checked_in = []
11
+ @checked_out = Set.new
12
+ end
13
+
14
+ # Get a free agent from the pool
15
+ def checkout
16
+ agent = @checked_in.pop
17
+
18
+ agent = build_agent if agent.nil?
19
+ @checked_out.add(agent)
20
+
21
+ agent
22
+ end
23
+
24
+ def checkin(agent)
25
+ @checked_out.delete(agent)
26
+ @checked_in.push(agent)
27
+ end
28
+
29
+ def build_agent
30
+ Server::AgentManager.new(@name, @env)
31
+ end
32
+
33
+ # Returns all agents, both checked in and checked out
34
+ def all
35
+ @checked_in + @checked_out.to_a
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ require 'expedite/server/agent_pool'
2
+
3
+ module Expedite
4
+ module Server
5
+ class ApplicationManager
6
+ attr_reader :pools
7
+
8
+ def initialize(env)
9
+ @env = env
10
+ @pools = Hash.new do |h, k|
11
+ h[k] = AgentPool.new(k, @env)
12
+ end
13
+ end
14
+
15
+ def with(name)
16
+ pool = @pools[name]
17
+ target = pool.checkout
18
+ begin
19
+ ret = yield target
20
+ ensure
21
+ pool.checkin(target)
22
+ end
23
+ ret
24
+ end
25
+ end
26
+ end
27
+ end
@@ -97,42 +97,69 @@ module Expedite
97
97
  log "accepted client"
98
98
  client.puts env.version
99
99
 
100
+ # Corresponds to Client::Invoke#connect_to_agent
100
101
  app_client = client.recv_io
101
102
  command = client.recv_object
102
103
 
103
- args, agent = command.values_at('args', 'agent')
104
+ args, agent = command.values_at("args", "agent")
104
105
  cmd = args.first
105
106
 
106
- if agent == '__server__'
107
+ if agent == "__server__"
107
108
  case cmd
108
- when 'application_pids'
109
+ when "application_pids"
110
+ # Corresponds to Client::Invoke#run_command
109
111
  client.puts
112
+
110
113
  unix_socket = UNIXSocket.for_fd(app_client.fileno)
111
- _stdout, _stderr, _stdin = streams = 3.times.map do
112
- unix_socket.recv_io
113
- end
114
+ _stdout = unix_socket.recv_io
115
+ _stderr = unix_socket.recv_io
116
+ _stdin = unix_socket.recv_io
117
+
114
118
  client.puts Process.pid
115
119
 
116
120
  application_pids = []
117
- env.applications.each do |k, v|
118
- application_pids << v.pid if v.pid
121
+ env.applications.pools.each do |k, pool|
122
+ application_pids.concat(pool.all.map(&:pid))
119
123
  end
120
- unix_socket.send_object("return" => application_pids)
124
+ unix_socket.send_object({"return" => application_pids}, env)
121
125
 
122
126
  unix_socket.close
123
127
  client.close
124
128
  else
125
129
  end
126
130
  elsif Expedite::Actions.lookup(cmd)
131
+ # Corresponds to Client::Invoke#run_command
127
132
  log "running command #{cmd}: #{args}"
133
+
128
134
  client.puts
129
135
 
130
- target = env.applications[agent]
131
- client.puts target.run(app_client)
136
+ begin
137
+ env.applications.with(agent) do |target|
138
+ client.puts target.run(app_client)
139
+ end
140
+ rescue AgentNotFoundError => e
141
+ unix_socket = UNIXSocket.for_fd(app_client.fileno)
142
+ _stdout = unix_socket.recv_io
143
+ _stderr = unix_socket.recv_io
144
+ _stdin = unix_socket.recv_io
145
+
146
+ args, env = unix_socket.recv_object.values_at("args", "env")
147
+
148
+ client.puts Process.pid
149
+
150
+ # boot only
151
+ #@child_socket = client.recv_io
152
+ #@log_file = client.recv_io
153
+ unix_socket.send_object({"exception" => e}, env)
154
+
155
+ unix_socket.close
156
+ client.close
157
+ end
132
158
  else
133
159
  log "command not found #{cmd}"
134
160
  client.close
135
161
  end
162
+ rescue AgentNotFoundError => e
136
163
  rescue SocketError => e
137
164
  raise e unless client.eof?
138
165
  ensure
@@ -168,7 +195,13 @@ module Expedite
168
195
  end
169
196
  end
170
197
 
171
- env.applications.values.map { |a| Expedite.failsafe_thread { a.stop } }.map(&:join)
198
+ thrs = []
199
+ env.applications.pools.each do |k, pool|
200
+ pool.all.each do |a|
201
+ thrs << Expedite.failsafe_thread { a.stop }
202
+ end
203
+ end
204
+ thrs.map(&:join)
172
205
  end
173
206
 
174
207
  def write_pidfile
@@ -201,11 +234,20 @@ module Expedite
201
234
 
202
235
  def default_log_file
203
236
  if foreground? && !ENV["SPRING_LOG"]
204
- $stdout
237
+ $stderr
205
238
  else
206
239
  nil
207
240
  end
208
241
  end
242
+
243
+ # Server command
244
+ def application_pids
245
+ pids = []
246
+ env.applications.each do |k, v|
247
+ pids << v.pid if v.pid
248
+ end
249
+ return pids
250
+ end
209
251
  end
210
252
  end
211
253
  end
@@ -1,3 +1,3 @@
1
1
  module Expedite
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/expedite.rb CHANGED
@@ -31,5 +31,3 @@ module Expedite
31
31
  @clients[agent]
32
32
  end
33
33
  end
34
-
35
-
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.1.0
4
+ version: 0.2.0
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: 2022-12-08 00:00:00.000000000 Z
11
+ date: 2022-12-16 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
@@ -25,6 +25,7 @@ files:
25
25
  - lib/expedite/actions.rb
26
26
  - lib/expedite/agents.rb
27
27
  - lib/expedite/cli.rb
28
+ - lib/expedite/cli/rails.rb
28
29
  - lib/expedite/cli/server.rb
29
30
  - lib/expedite/cli/status.rb
30
31
  - lib/expedite/cli/stop.rb
@@ -33,10 +34,13 @@ files:
33
34
  - lib/expedite/env.rb
34
35
  - lib/expedite/errors.rb
35
36
  - lib/expedite/failsafe_thread.rb
37
+ - lib/expedite/helper/rails.rb
36
38
  - lib/expedite/protocol.rb
37
39
  - lib/expedite/server/agent.rb
38
40
  - lib/expedite/server/agent_boot.rb
39
41
  - lib/expedite/server/agent_manager.rb
42
+ - lib/expedite/server/agent_pool.rb
43
+ - lib/expedite/server/application_manager.rb
40
44
  - lib/expedite/server/controller.rb
41
45
  - lib/expedite/signals.rb
42
46
  - lib/expedite/syntax.rb