sam-shepherd 0.8.2 → 0.9.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 +4 -4
- data/Gemfile.lock +11 -11
- data/README.md +2 -8
- data/lib/sam/cli.rb +12 -28
- data/lib/sam/commands/monitor.rb +30 -0
- data/lib/sam/commands/reaper.rb +41 -0
- data/lib/sam/commands/reloader.rb +31 -0
- data/lib/sam/commands/runner.rb +31 -0
- data/lib/sam/commands/spawner.rb +30 -0
- data/lib/sam/{cli → commands}/version.rb +0 -0
- data/lib/sam/servers.rb +29 -0
- data/lib/sam/servers/breeder.rb +21 -0
- data/lib/sam/servers/cloner.rb +34 -0
- data/lib/sam/servers/predator.rb +26 -0
- data/lib/sam/{puma → servers/puma}/identifier.rb +0 -2
- data/lib/sam/{puma → servers}/shepherd.rb +14 -18
- data/lib/sam/{unicorn → servers/unicorn}/identifier.rb +0 -2
- data/lib/sam/version.rb +1 -1
- data/sam.gemspec +3 -3
- metadata +15 -24
- data/lib/sam/cli/puma.rb +0 -4
- data/lib/sam/cli/puma/monitor.rb +0 -28
- data/lib/sam/cli/puma/reaper.rb +0 -34
- data/lib/sam/cli/puma/spawner.rb +0 -29
- data/lib/sam/cli/unicorn.rb +0 -10
- data/lib/sam/cli/unicorn/monitor.rb +0 -28
- data/lib/sam/cli/unicorn/reaper.rb +0 -34
- data/lib/sam/cli/unicorn/reloader.rb +0 -25
- data/lib/sam/cli/unicorn/runner.rb +0 -33
- data/lib/sam/cli/unicorn/spawner.rb +0 -29
- data/lib/sam/puma.rb +0 -6
- data/lib/sam/puma/breeder.rb +0 -16
- data/lib/sam/puma/predator.rb +0 -12
- data/lib/sam/unicorn.rb +0 -7
- data/lib/sam/unicorn/breeder.rb +0 -16
- data/lib/sam/unicorn/cloner.rb +0 -22
- data/lib/sam/unicorn/predator.rb +0 -12
- data/lib/sam/unicorn/shepherd.rb +0 -55
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06abe7f1d5b6691e01a1df7433ae4ed8d9f2ec0e153c3fe82dfc558677c33fa7
|
|
4
|
+
data.tar.gz: 204385c6f7c60f1ce2c18b7a44d98af94fc52850f2770725ab0418eeb158fa86
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b2b3ea89e0147e321dbe787e25ab4480dca6144c4de4fb1a5369d9272a950caffb4b36120191134fa2d0cae3b9cc796f4f81e128e3695ed12f5dbc7f665665e
|
|
7
|
+
data.tar.gz: edc6d81e4befc3090877d25157681c888095922aea8cc7dffd39fae8a1407a4cf7459c6fad83412a3fb3e07079ab43ccd03c220c747c10f8cf7a3d005c8fed45
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
sam-shepherd (0.
|
|
4
|
+
sam-shepherd (0.9.0)
|
|
5
5
|
hanami-cli (~> 0.2)
|
|
6
6
|
tty-command (~> 0.7)
|
|
7
7
|
|
|
@@ -22,7 +22,7 @@ GEM
|
|
|
22
22
|
descendants_tracker (~> 0.0.4)
|
|
23
23
|
ice_nine (~> 0.11.0)
|
|
24
24
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
25
|
-
backports (3.11.
|
|
25
|
+
backports (3.11.3)
|
|
26
26
|
builder (3.2.3)
|
|
27
27
|
childprocess (0.9.0)
|
|
28
28
|
ffi (~> 1.0, >= 1.0.11)
|
|
@@ -46,7 +46,7 @@ GEM
|
|
|
46
46
|
backports (>= 3.8.0)
|
|
47
47
|
cucumber-tag_expressions (~> 1.1.0)
|
|
48
48
|
gherkin (>= 5.0.0)
|
|
49
|
-
cucumber-expressions (5.0.
|
|
49
|
+
cucumber-expressions (5.0.17)
|
|
50
50
|
cucumber-tag_expressions (1.1.1)
|
|
51
51
|
cucumber-wire (0.0.1)
|
|
52
52
|
descendants_tracker (0.0.4)
|
|
@@ -57,7 +57,7 @@ GEM
|
|
|
57
57
|
equatable (0.5.0)
|
|
58
58
|
erubis (2.7.0)
|
|
59
59
|
ffi (1.9.23)
|
|
60
|
-
flay (2.
|
|
60
|
+
flay (2.11.0)
|
|
61
61
|
erubis (~> 2.7.0)
|
|
62
62
|
path_expander (~> 1.0)
|
|
63
63
|
ruby_parser (~> 3.0)
|
|
@@ -114,7 +114,7 @@ GEM
|
|
|
114
114
|
nenv (~> 0.1)
|
|
115
115
|
shellany (~> 0.0)
|
|
116
116
|
parallel (1.12.1)
|
|
117
|
-
parser (2.5.0
|
|
117
|
+
parser (2.5.1.0)
|
|
118
118
|
ast (~> 2.4.0)
|
|
119
119
|
pastel (0.7.2)
|
|
120
120
|
equatable (~> 0.5.0)
|
|
@@ -125,7 +125,7 @@ GEM
|
|
|
125
125
|
coderay (~> 1.1.0)
|
|
126
126
|
method_source (~> 0.9.0)
|
|
127
127
|
public_suffix (3.0.2)
|
|
128
|
-
puma (3.11.
|
|
128
|
+
puma (3.11.4)
|
|
129
129
|
rack (2.0.4)
|
|
130
130
|
rack-protection (2.0.1)
|
|
131
131
|
rack
|
|
@@ -135,10 +135,10 @@ GEM
|
|
|
135
135
|
rb-fsevent (0.10.3)
|
|
136
136
|
rb-inotify (0.9.10)
|
|
137
137
|
ffi (>= 0.5.0, < 2)
|
|
138
|
-
reek (4.8.
|
|
138
|
+
reek (4.8.1)
|
|
139
139
|
codeclimate-engine-rb (~> 0.4.0)
|
|
140
140
|
parser (>= 2.5.0.0, < 2.6)
|
|
141
|
-
rainbow (
|
|
141
|
+
rainbow (>= 2.0, < 4.0)
|
|
142
142
|
rspec (3.7.0)
|
|
143
143
|
rspec-core (~> 3.7.0)
|
|
144
144
|
rspec-expectations (~> 3.7.0)
|
|
@@ -152,7 +152,7 @@ GEM
|
|
|
152
152
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
153
153
|
rspec-support (~> 3.7.0)
|
|
154
154
|
rspec-support (3.7.1)
|
|
155
|
-
rubocop (0.
|
|
155
|
+
rubocop (0.55.0)
|
|
156
156
|
parallel (~> 1.10)
|
|
157
157
|
parser (>= 2.5)
|
|
158
158
|
powerpack (~> 0.1)
|
|
@@ -173,7 +173,7 @@ GEM
|
|
|
173
173
|
ruby_parser (~> 3.8)
|
|
174
174
|
tty-which (~> 0.3.0)
|
|
175
175
|
virtus (~> 1.0)
|
|
176
|
-
sexp_processor (4.
|
|
176
|
+
sexp_processor (4.11.0)
|
|
177
177
|
shellany (0.0.1)
|
|
178
178
|
simplecov (0.16.1)
|
|
179
179
|
docile (~> 1.1)
|
|
@@ -190,7 +190,7 @@ GEM
|
|
|
190
190
|
tilt (2.0.8)
|
|
191
191
|
transproc (1.0.2)
|
|
192
192
|
tty-color (0.4.2)
|
|
193
|
-
tty-command (0.
|
|
193
|
+
tty-command (0.8.0)
|
|
194
194
|
pastel (~> 0.7.0)
|
|
195
195
|
tty-which (0.3.0)
|
|
196
196
|
unicode-display_width (1.3.0)
|
data/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Sam
|
|
2
2
|
|
|
3
3
|
[](https://codeclimate.com/github/VAGAScom/sam/maintainability)
|
|
4
|
-
[](https://badge.fury.io/rb/sam)
|
|
5
|
-
[](https://travis-ci.org/VAGAScom/sam)
|
|
4
|
+
[](https://badge.fury.io/rb/sam)
|
|
6
5
|
[](https://beta.gemnasium.com/projects/github.com/VAGAScom/sam)
|
|
7
6
|
|
|
8
7
|
|
|
@@ -29,13 +28,8 @@ Or install it yourself as:
|
|
|
29
28
|
|
|
30
29
|
## Usage
|
|
31
30
|
|
|
32
|
-
**Sam**
|
|
31
|
+
**Sam** is pretty straightforward and you can rely on its internal documentation. By invoking `sam` you can see the list of available commands. For a more in-depth help for each command, you can pass a `-h` flag to it, like this: `sam run -h`
|
|
33
32
|
|
|
34
|
-
1. `unicorn start`: starts an `unicorn` instance
|
|
35
|
-
2. `unicorn stop`: stops an `unicorn` instance
|
|
36
|
-
3. `unicorn monitor`: start a monitoring loop over the running `unicorn` instance. It will forward the signals `HUP, USR2, TERM, QUIT, TTIN, TTOU` to the `unicorn` instance. `HUP` will do an graceful reload of the application
|
|
37
|
-
4. `unicorn reload`: reloads the `unicorn` instance by issuing a `USR2` followed by a `QUIT` signal a few seconds later
|
|
38
|
-
5. `unicorn run`: starts and monitors an `unicorn` instance
|
|
39
33
|
|
|
40
34
|
## Development
|
|
41
35
|
|
data/lib/sam/cli.rb
CHANGED
|
@@ -1,42 +1,26 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'hanami/cli'
|
|
4
|
+
require_relative 'servers'
|
|
4
5
|
|
|
5
6
|
module Sam
|
|
6
7
|
module CLI
|
|
7
8
|
module Commands
|
|
8
9
|
extend Hanami::CLI::Registry
|
|
9
10
|
|
|
10
|
-
require_relative '
|
|
11
|
+
require_relative 'commands/version'
|
|
12
|
+
require_relative 'commands/spawner'
|
|
13
|
+
require_relative 'commands/reaper'
|
|
14
|
+
require_relative 'commands/reloader'
|
|
15
|
+
require_relative 'commands/monitor'
|
|
16
|
+
require_relative 'commands/runner'
|
|
11
17
|
|
|
12
18
|
register 'version', Version
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
cmd.register 'start', Unicorn::Spawner
|
|
19
|
-
cmd.register 'stop', Unicorn::Reaper
|
|
20
|
-
cmd.register 'reload', Unicorn::Reloader
|
|
21
|
-
cmd.register 'monitor', Unicorn::Monitor
|
|
22
|
-
cmd.register 'run', Unicorn::Runner
|
|
23
|
-
end
|
|
24
|
-
rescue Gem::LoadError
|
|
25
|
-
warn 'Unicorn not found. Not loading unicorn commands'
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
begin
|
|
29
|
-
gem 'puma'
|
|
30
|
-
require_relative 'puma'
|
|
31
|
-
require_relative 'cli/puma'
|
|
32
|
-
register 'puma' do |cmd|
|
|
33
|
-
cmd.register 'start', Puma::Spawner
|
|
34
|
-
cmd.register 'stop', Puma::Reaper
|
|
35
|
-
# cmd.register 'stop', Puma::Reaper
|
|
36
|
-
end
|
|
37
|
-
rescue Gem::LoadError
|
|
38
|
-
warn 'Puma not found. Not loading puma commands'
|
|
39
|
-
end
|
|
19
|
+
register 'start', Spawner
|
|
20
|
+
register 'stop', Reaper
|
|
21
|
+
register 'reload', Reloader
|
|
22
|
+
register 'monitor', Monitor
|
|
23
|
+
register 'run', Runner
|
|
40
24
|
end
|
|
41
25
|
end
|
|
42
26
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
class Monitor < Hanami::CLI::Command
|
|
7
|
+
desc 'Monitor an already running server'
|
|
8
|
+
|
|
9
|
+
# rubocop:disable Metrics/LineLength
|
|
10
|
+
argument :server, required: true, values: %w[unicorn puma], desc: 'The application server to be started'
|
|
11
|
+
argument :config, required: true, desc: 'The path to the server configuration file'
|
|
12
|
+
|
|
13
|
+
option :timeout, aliases: ['-t'], default: 10, desc: 'The amount of time waiting for the server process to fork new workers'
|
|
14
|
+
|
|
15
|
+
example [
|
|
16
|
+
'unicorn config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
17
|
+
]
|
|
18
|
+
# rubocop:enable Metrics/LineLength
|
|
19
|
+
|
|
20
|
+
def call(server:, config:, timeout:)
|
|
21
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
22
|
+
Sam::Servers::Shepherd.new.call(server: server, config: path, timeout: timeout)
|
|
23
|
+
rescue Errors::ProcessNotFound
|
|
24
|
+
warn "#{server} exited"
|
|
25
|
+
exit 1
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
class Reaper < Hanami::CLI::Command
|
|
7
|
+
# rubocop:disable Metrics/LineLength
|
|
8
|
+
desc 'Stops the server process'
|
|
9
|
+
argument :server, required: true, values: %w[unicorn puma], desc: 'The application server to be started'
|
|
10
|
+
argument :config, required: true, desc: 'The path to the server configuration file'
|
|
11
|
+
|
|
12
|
+
example [
|
|
13
|
+
'puma config/puma/development.rb # Stops the server in production mode using the config/puma/development.rb config file'
|
|
14
|
+
]
|
|
15
|
+
# rubocop:enable Metrics/LineLength
|
|
16
|
+
|
|
17
|
+
def call(server:, config:)
|
|
18
|
+
exit 1 unless server_found(server)
|
|
19
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
20
|
+
result = Sam::Servers::Predator.new.call(server: server, config: path)
|
|
21
|
+
warn "Hunted one #{server} with pid #{result}"
|
|
22
|
+
rescue Errors::PidfileNotFound
|
|
23
|
+
warn "No running #{server}s found"
|
|
24
|
+
exit 1
|
|
25
|
+
rescue Errors::ConfigfileNotFound => ex
|
|
26
|
+
warn ex.message
|
|
27
|
+
exit 1
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def server_found(server)
|
|
33
|
+
gem server
|
|
34
|
+
rescue Gem::LoadError
|
|
35
|
+
warn "#{server} not found. Make sure it's in your Gemfile"
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
class Reloader < Hanami::CLI::Command
|
|
7
|
+
desc 'Reloads the code on a running server'
|
|
8
|
+
|
|
9
|
+
# rubocop:disable Metrics/LineLength
|
|
10
|
+
argument :server, required: true, values: %w[unicorn puma], desc: 'The application server to be started'
|
|
11
|
+
argument :config, required: true, desc: 'The path to the server configuration file'
|
|
12
|
+
|
|
13
|
+
option :timeout, aliases: ['-t'], default: 10, desc: 'The amount of time waiting for the server process to fork new workers'
|
|
14
|
+
|
|
15
|
+
example [
|
|
16
|
+
'puma config/server_settings.rb # Starts the server in test mode using the config/server_settings.rb config file',
|
|
17
|
+
'unicorn config/server_settings.rb # Starts the server in production mode using the config/server_settings.rb config file'
|
|
18
|
+
]
|
|
19
|
+
# rubocop:enable Metrics/LineLength
|
|
20
|
+
|
|
21
|
+
def call(server:, config:, timeout:)
|
|
22
|
+
path = Pathname.new(Dir.pwd).join(config)
|
|
23
|
+
Sam::Servers::Cloner.new.call(server: server, config: path, timeout: timeout)
|
|
24
|
+
rescue Errors::ProcessNotFound
|
|
25
|
+
warn "No running #{server}s found"
|
|
26
|
+
exit 1
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module CLI
|
|
5
|
+
module Commands
|
|
6
|
+
class Runner < Hanami::CLI::Command
|
|
7
|
+
desc 'Starts and monitor an already running server'
|
|
8
|
+
# rubocop:disable Metrics/LineLength
|
|
9
|
+
argument :server, required: true, values: %w[unicorn puma], desc: 'The application server to be started'
|
|
10
|
+
argument :config, required: true, desc: 'The path to the server configuration file'
|
|
11
|
+
|
|
12
|
+
option :env, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: ['-e']
|
|
13
|
+
option :timeout, aliases: ['-t'], default: 10, desc: 'The amount of time waiting for the server process to fork new workers'
|
|
14
|
+
|
|
15
|
+
example [
|
|
16
|
+
'puma config/server_settings.rb -e test # Starts and monitors the server in test mode using the config/server_settings.rb config file',
|
|
17
|
+
'unicorn config/server_settings.rb #Starts and monitors the server in production mode using the config/server_settings.rb config file'
|
|
18
|
+
]
|
|
19
|
+
# rubocop:enable Metrics/LineLength
|
|
20
|
+
|
|
21
|
+
def call(server:, config:, env:, timeout:)
|
|
22
|
+
Sam::Servers::Breeder.new.call(server: server, config: config, env: env)
|
|
23
|
+
Sam::Servers::Monitor.new.call(server: server, config: config, timeout: timeout)
|
|
24
|
+
rescue Sam::Errors::ProcessNotFound
|
|
25
|
+
warn "#{server} exited"
|
|
26
|
+
exit 1
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'hanami/cli'
|
|
4
|
+
|
|
5
|
+
module Sam
|
|
6
|
+
module CLI
|
|
7
|
+
module Commands
|
|
8
|
+
class Spawner < Hanami::CLI::Command
|
|
9
|
+
desc 'Starts the server'
|
|
10
|
+
|
|
11
|
+
# rubocop:disable Metrics/LineLength
|
|
12
|
+
argument :server, required: true, values: %w[unicorn puma], desc: 'The application server to be started'
|
|
13
|
+
argument :config, required: true, desc: 'The path to the server configuration file'
|
|
14
|
+
|
|
15
|
+
option :env, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: ['-e']
|
|
16
|
+
|
|
17
|
+
example [
|
|
18
|
+
'puma config/server_settings.rb -e test # Starts the server in test mode using the config/server_settings.rb config file',
|
|
19
|
+
'unicorn config/server_settings.rb # Starts the server in production mode using the config/server_settings.rb config file'
|
|
20
|
+
]
|
|
21
|
+
# rubocop:enable Metrics/LineLength
|
|
22
|
+
|
|
23
|
+
def call(server:, config:, env:)
|
|
24
|
+
path_to_config = Pathname.new(Dir.pwd).join(config)
|
|
25
|
+
Sam::Servers::Breeder.new.call(server: server, config: path_to_config, env: env)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
File without changes
|
data/lib/sam/servers.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
gem 'unicorn'
|
|
5
|
+
require 'unicorn'
|
|
6
|
+
require_relative 'servers/unicorn/identifier'
|
|
7
|
+
rescue Gem::LoadError
|
|
8
|
+
warn 'unicorn unavailable'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
begin
|
|
12
|
+
gem 'puma'
|
|
13
|
+
require 'puma/cli'
|
|
14
|
+
require_relative 'servers/puma/identifier'
|
|
15
|
+
rescue Gem::LoadError
|
|
16
|
+
warn 'puma unavailable'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module Sam
|
|
20
|
+
module Servers
|
|
21
|
+
PUMA_PID = ->(config) { Sam::Puma::Identifier.new.call(config) }
|
|
22
|
+
UNICORN_PID = ->(config) { Sam::Unicorn::Identifier.new.call(config) }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require_relative 'servers/breeder'
|
|
27
|
+
require_relative 'servers/cloner'
|
|
28
|
+
require_relative 'servers/predator'
|
|
29
|
+
require_relative 'servers/shepherd'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'tty-command'
|
|
4
|
+
|
|
5
|
+
module Sam
|
|
6
|
+
module Servers
|
|
7
|
+
class Breeder
|
|
8
|
+
UNICORN = 'bundle exec unicorn -D -c ${CONF_PATH} -E ${RACK_ENV}'
|
|
9
|
+
PUMA = 'bundle exec puma -C ${CONF_PATH} -e ${RACK_ENV}'
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@cmd = TTY::Command.new(timeout: 120, printer: :quiet)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def call(server:, config:, env: 'production')
|
|
16
|
+
cmdline = self.class.const_get(server.upcase)
|
|
17
|
+
@cmd.run(cmdline, env: { CONF_PATH: config, RACK_ENV: env })
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module Servers
|
|
5
|
+
class Cloner
|
|
6
|
+
PUMA_PID = ->(config) { Sam::Puma::Identifier.new.call(config) }
|
|
7
|
+
UNICORN_PID = ->(config) { Sam::Unicorn::Identifier.new.call(config) }
|
|
8
|
+
|
|
9
|
+
UNICORN_STRATEGY = lambda do |config, timeout = 10|
|
|
10
|
+
pid = UNICORN_PID.call(config)
|
|
11
|
+
Process.kill('USR2', pid)
|
|
12
|
+
sleep timeout
|
|
13
|
+
newpid = UNICORN_PID.call(config)
|
|
14
|
+
Process.kill('QUIT', pid)
|
|
15
|
+
newpid
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
PUMA_STRATEGY = lambda do |config, _timeout|
|
|
19
|
+
settings = (::Puma::Configuration.new({}) { |conf| conf.load config.to_s }).load
|
|
20
|
+
Process.kill(settings.file_options[:preload_app] ? 'USR1' : 'USR2', PUMA_PID.call(config))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def call(server:, config:, timeout: 10)
|
|
24
|
+
restart_strategy(server, config, timeout)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def restart_strategy(server, config, timeout)
|
|
30
|
+
self.class.const_get("#{server.upcase}_STRATEGY").call(config, timeout)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sam
|
|
4
|
+
module Servers
|
|
5
|
+
class Predator
|
|
6
|
+
PUMA_PID = ->(config) { Sam::Puma::Identifier.new.call(config) }
|
|
7
|
+
UNICORN_PID = ->(config) { Sam::Unicorn::Identifier.new.call(config) }
|
|
8
|
+
|
|
9
|
+
def call(server:, config:)
|
|
10
|
+
@server = server
|
|
11
|
+
@config = config
|
|
12
|
+
Process.kill(signal, pid) && pid
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def signal
|
|
18
|
+
@server == 'unicorn' ? 'QUIT' : 'INT'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def pid
|
|
22
|
+
@pid ||= self.class.const_get("#{@server.upcase}_PID").call(@config)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Sam
|
|
4
|
-
module
|
|
4
|
+
module Servers
|
|
5
5
|
class Shepherd
|
|
6
6
|
def initialize
|
|
7
|
-
|
|
7
|
+
trap_signals
|
|
8
8
|
@restarting = false
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def call(
|
|
11
|
+
def call(server:, config:, timeout: 0.5)
|
|
12
|
+
@config = config
|
|
13
|
+
@server = server
|
|
12
14
|
@timeout = timeout
|
|
13
|
-
@config ||= Pathname.new(Dir.pwd).join(path)
|
|
14
15
|
loop do
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
Process.kill(0, pid)
|
|
17
|
+
rescue Errno::ESRCH
|
|
18
|
+
raise Errors::ProcessNotFound unless @restarting
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
private
|
|
21
23
|
|
|
22
24
|
def pid
|
|
23
|
-
@pid ||=
|
|
25
|
+
@pid ||= self.class.const_get("Sam::Servers::#{@server.upcase}_PID").call(@config)
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
def
|
|
27
|
-
trap('HUP') {
|
|
28
|
+
def trap_signals
|
|
29
|
+
trap('HUP') { reload_server }
|
|
28
30
|
trap('QUIT') { forward_signal('QUIT') }
|
|
29
31
|
trap('USR2') { forward_signal('USR2') }
|
|
30
32
|
trap('TTOU') { forward_signal('TTOU') }
|
|
@@ -33,23 +35,17 @@ module Sam
|
|
|
33
35
|
trap('INT') { forward_signal('INT') }
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
def
|
|
38
|
+
def reload_server
|
|
37
39
|
@restarting = true
|
|
38
|
-
@pid = Cloner.new.call(@config, timeout: @timeout)
|
|
40
|
+
@pid = Cloner.new.call(server: @server, config: @config, timeout: @timeout)
|
|
39
41
|
@restarting = false
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
def forward_signal(signal)
|
|
43
|
-
warn "Sending #{signal} to unicorn #{pid}"
|
|
44
45
|
Process.kill(signal, pid)
|
|
45
46
|
end
|
|
46
47
|
|
|
47
|
-
def
|
|
48
|
-
return if @restarting
|
|
49
|
-
Process.kill(0, pid)
|
|
50
|
-
rescue Errno::ESRCH
|
|
51
|
-
raise Errors::ProcessNotFound
|
|
52
|
-
end
|
|
48
|
+
def heartbeat; end
|
|
53
49
|
end
|
|
54
50
|
end
|
|
55
51
|
end
|
data/lib/sam/version.rb
CHANGED
data/sam.gemspec
CHANGED
|
@@ -18,12 +18,12 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
|
|
19
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
20
20
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
21
|
-
#if spec.respond_to?(:metadata)
|
|
21
|
+
# if spec.respond_to?(:metadata)
|
|
22
22
|
# spec.metadata['allowed_push_host'] = 'https://gemfury.org'
|
|
23
|
-
#else
|
|
23
|
+
# else
|
|
24
24
|
# raise 'RubyGems 2.0 or newer is required to protect against ' \
|
|
25
25
|
# 'public gem pushes.'
|
|
26
|
-
#end
|
|
26
|
+
# end
|
|
27
27
|
|
|
28
28
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
29
29
|
f.match(%r{^(test|spec|features)/})
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sam-shepherd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mereghost
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-04-
|
|
11
|
+
date: 2018-04-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: hanami-cli
|
|
@@ -258,29 +258,20 @@ files:
|
|
|
258
258
|
- exe/sam
|
|
259
259
|
- lib/sam.rb
|
|
260
260
|
- lib/sam/cli.rb
|
|
261
|
-
- lib/sam/
|
|
262
|
-
- lib/sam/
|
|
263
|
-
- lib/sam/
|
|
264
|
-
- lib/sam/
|
|
265
|
-
- lib/sam/
|
|
266
|
-
- lib/sam/
|
|
267
|
-
- lib/sam/cli/unicorn/reaper.rb
|
|
268
|
-
- lib/sam/cli/unicorn/reloader.rb
|
|
269
|
-
- lib/sam/cli/unicorn/runner.rb
|
|
270
|
-
- lib/sam/cli/unicorn/spawner.rb
|
|
271
|
-
- lib/sam/cli/version.rb
|
|
261
|
+
- lib/sam/commands/monitor.rb
|
|
262
|
+
- lib/sam/commands/reaper.rb
|
|
263
|
+
- lib/sam/commands/reloader.rb
|
|
264
|
+
- lib/sam/commands/runner.rb
|
|
265
|
+
- lib/sam/commands/spawner.rb
|
|
266
|
+
- lib/sam/commands/version.rb
|
|
272
267
|
- lib/sam/errors.rb
|
|
273
|
-
- lib/sam/
|
|
274
|
-
- lib/sam/
|
|
275
|
-
- lib/sam/
|
|
276
|
-
- lib/sam/
|
|
277
|
-
- lib/sam/puma/
|
|
278
|
-
- lib/sam/
|
|
279
|
-
- lib/sam/unicorn/
|
|
280
|
-
- lib/sam/unicorn/cloner.rb
|
|
281
|
-
- lib/sam/unicorn/identifier.rb
|
|
282
|
-
- lib/sam/unicorn/predator.rb
|
|
283
|
-
- lib/sam/unicorn/shepherd.rb
|
|
268
|
+
- lib/sam/servers.rb
|
|
269
|
+
- lib/sam/servers/breeder.rb
|
|
270
|
+
- lib/sam/servers/cloner.rb
|
|
271
|
+
- lib/sam/servers/predator.rb
|
|
272
|
+
- lib/sam/servers/puma/identifier.rb
|
|
273
|
+
- lib/sam/servers/shepherd.rb
|
|
274
|
+
- lib/sam/servers/unicorn/identifier.rb
|
|
284
275
|
- lib/sam/version.rb
|
|
285
276
|
- sam.gemspec
|
|
286
277
|
homepage: https://github.com/vagas/sam
|
data/lib/sam/cli/puma.rb
DELETED
data/lib/sam/cli/puma/monitor.rb
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Puma
|
|
7
|
-
class Monitor < Hanami::CLI::Command
|
|
8
|
-
# rubocop:disable Metrics/LineLength
|
|
9
|
-
desc 'Monitor an already running unicorn'
|
|
10
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
-
option :timeout, type: :integer, desc: 'The number of seconds to wait for starting the unicorn server', aliases: ['-t']
|
|
12
|
-
example [
|
|
13
|
-
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
14
|
-
]
|
|
15
|
-
# rubocop:enable Metrics/LineLength
|
|
16
|
-
|
|
17
|
-
def call(config:)
|
|
18
|
-
path = Pathname.new(Dir.pwd).join(config)
|
|
19
|
-
Sam::Puma::Shepherd.new.call(path)
|
|
20
|
-
rescue Errors::ProcessNotFound
|
|
21
|
-
warn 'Puma exited'
|
|
22
|
-
exit 1
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
data/lib/sam/cli/puma/reaper.rb
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Puma
|
|
7
|
-
class Reaper < Hanami::CLI::Command
|
|
8
|
-
NO_MORE_PUMAS = 'Pumas are extinct =('
|
|
9
|
-
|
|
10
|
-
# rubocop:disable Metrics/LineLength
|
|
11
|
-
desc 'Stops the puma process'
|
|
12
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
13
|
-
|
|
14
|
-
example [
|
|
15
|
-
'-config config/server_settings.rb Stops the server in production mode using the config/server_settings.rb config file'
|
|
16
|
-
]
|
|
17
|
-
# rubocop:enable Metrics/LineLength
|
|
18
|
-
|
|
19
|
-
def call(config:)
|
|
20
|
-
path = Pathname.new(Dir.pwd).join(config)
|
|
21
|
-
result = Sam::Puma::Predator.new.call(path)
|
|
22
|
-
warn "Hunted a puma with pid #{result}"
|
|
23
|
-
rescue Errors::PidfileNotFound
|
|
24
|
-
warn NO_MORE_PUMAS
|
|
25
|
-
exit 1
|
|
26
|
-
rescue Errors::ConfigfileNotFound => ex
|
|
27
|
-
warn ex.message
|
|
28
|
-
exit 1
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
data/lib/sam/cli/puma/spawner.rb
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Puma
|
|
7
|
-
class Spawner < Hanami::CLI::Command
|
|
8
|
-
# rubocop:disable Metrics/LineLength
|
|
9
|
-
desc 'Start the puma process'
|
|
10
|
-
|
|
11
|
-
option :environment, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: %w[--env -e]
|
|
12
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/puma/production.rb', aliases: ['-c']
|
|
13
|
-
|
|
14
|
-
example [
|
|
15
|
-
'-e development #Starts the server in development mode',
|
|
16
|
-
'-e production --config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
17
|
-
]
|
|
18
|
-
# rubocop:enable Metrics/LineLength
|
|
19
|
-
|
|
20
|
-
def call(environment:, config:)
|
|
21
|
-
config = Pathname.new(Dir.pwd).join(config)
|
|
22
|
-
Sam::Puma::Breeder.new.call(environment, config)
|
|
23
|
-
warn "We have a newborn puma for environment #{environment} and configuration file: #{config}"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
data/lib/sam/cli/unicorn.rb
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'unicorn/monitor'
|
|
4
|
-
require_relative 'unicorn/reaper'
|
|
5
|
-
require_relative 'unicorn/reloader'
|
|
6
|
-
require_relative 'unicorn/spawner'
|
|
7
|
-
require_relative 'unicorn/runner'
|
|
8
|
-
|
|
9
|
-
# Upstart reload sends SIGHUP to the process
|
|
10
|
-
# Systemd expects an ExecReload= that syncronously reloads the confs.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Unicorn
|
|
7
|
-
class Monitor < Hanami::CLI::Command
|
|
8
|
-
# rubocop:disable Metrics/LineLength
|
|
9
|
-
desc 'Monitor an already running unicorn'
|
|
10
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
-
option :timeout, type: :integer, desc: 'The number of seconds to wait for starting the unicorn server', aliases: ['-t']
|
|
12
|
-
example [
|
|
13
|
-
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
14
|
-
]
|
|
15
|
-
# rubocop:enable Metrics/LineLength
|
|
16
|
-
|
|
17
|
-
def call(config:)
|
|
18
|
-
path = Pathname.new(Dir.pwd).join(config)
|
|
19
|
-
Sam::Unicorn::Shepherd.new.call(path)
|
|
20
|
-
rescue Errors::ProcessNotFound
|
|
21
|
-
warn 'Unicorn exited'
|
|
22
|
-
exit 1
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Unicorn
|
|
7
|
-
class Reaper < Hanami::CLI::Command
|
|
8
|
-
NO_MORE_UNICORNS = 'Unicorns are already extinct'
|
|
9
|
-
|
|
10
|
-
# rubocop:disable Metrics/LineLength
|
|
11
|
-
desc 'Stops the unicorn process'
|
|
12
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
13
|
-
|
|
14
|
-
example [
|
|
15
|
-
'-config config/server_settings.rb Stops the server in production mode using the config/server_settings.rb config file'
|
|
16
|
-
]
|
|
17
|
-
# rubocop:enable Metrics/LineLength
|
|
18
|
-
|
|
19
|
-
def call(config:)
|
|
20
|
-
path = Pathname.new(Dir.pwd).join(config)
|
|
21
|
-
result = Sam::Unicorn::Predator.new.call(path)
|
|
22
|
-
warn "Hunted unicorn with pid #{result}"
|
|
23
|
-
rescue Errors::PidfileNotFound
|
|
24
|
-
warn NO_MORE_UNICORNS
|
|
25
|
-
exit 1
|
|
26
|
-
rescue Errors::ConfigfileNotFound => ex
|
|
27
|
-
warn ex.message
|
|
28
|
-
exit 1
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Unicorn
|
|
7
|
-
class Reloader < Hanami::CLI::Command
|
|
8
|
-
# rubocop:disable Metrics/LineLength
|
|
9
|
-
desc 'Reloads the unicorn configuration'
|
|
10
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
-
|
|
12
|
-
example [
|
|
13
|
-
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
14
|
-
]
|
|
15
|
-
# rubocop:enable Metrics/LineLength
|
|
16
|
-
|
|
17
|
-
def call(config)
|
|
18
|
-
path = Pathname.new(Dir.pwd).join(config)
|
|
19
|
-
Sam::Unicorn::Cloner.new.call(path)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Unicorn
|
|
7
|
-
class Runner < Hanami::CLI::Command
|
|
8
|
-
# rubocop:disable Metrics/LineLength
|
|
9
|
-
desc 'Monitor an already running unicorn'
|
|
10
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
11
|
-
option :environment, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: %w[--env -e]
|
|
12
|
-
option :timeout, type: :integer, desc: 'The number of seconds to wait for starting the unicorn server', default: 5, aliases: ['-t']
|
|
13
|
-
example [
|
|
14
|
-
'--config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file',
|
|
15
|
-
'-t 20 # Waits for 20 seconds for the master process to fork',
|
|
16
|
-
'-e production --config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
17
|
-
|
|
18
|
-
]
|
|
19
|
-
# rubocop:enable Metrics/LineLength
|
|
20
|
-
|
|
21
|
-
def call(config:, environment:, timeout:)
|
|
22
|
-
path = Pathname.new(Dir.pwd).join(config)
|
|
23
|
-
Sam::Unicorn::Breeder.new.call(environment, path)
|
|
24
|
-
Sam::Unicorn::Shepherd.new.call(path, timeout: Integer(timeout))
|
|
25
|
-
rescue Errors::ProcessNotFound
|
|
26
|
-
warn 'Unicorn seems dead.'
|
|
27
|
-
exit 1
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module CLI
|
|
5
|
-
module Commands
|
|
6
|
-
module Unicorn
|
|
7
|
-
class Spawner < Hanami::CLI::Command
|
|
8
|
-
# rubocop:disable Metrics/LineLength
|
|
9
|
-
desc 'Start the unicorn process'
|
|
10
|
-
|
|
11
|
-
option :environment, values: %w[production development test staging], default: 'production', desc: 'RACK_ENV to be used', aliases: %w[--env -e]
|
|
12
|
-
option :config, type: :path, desc: 'The path to the server configuration', default: 'config/unicorn/production.rb', aliases: ['-c']
|
|
13
|
-
|
|
14
|
-
example [
|
|
15
|
-
'-e development #Starts the server in development mode',
|
|
16
|
-
'-e production --config=config/server_settings.rb #Starts the server in production mode using the config/server_settings.rb config file'
|
|
17
|
-
]
|
|
18
|
-
# rubocop:enable Metrics/LineLength
|
|
19
|
-
|
|
20
|
-
def call(environment:, config:)
|
|
21
|
-
config = Pathname.new(Dir.pwd).join(config)
|
|
22
|
-
Sam::Unicorn::Breeder.new.call(environment, config)
|
|
23
|
-
warn "We have a newborn unicorn for environment #{environment} and configuration file: #{config}"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
data/lib/sam/puma.rb
DELETED
data/lib/sam/puma/breeder.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'tty-command'
|
|
4
|
-
|
|
5
|
-
module Sam
|
|
6
|
-
module Puma
|
|
7
|
-
class Breeder
|
|
8
|
-
COMMAND = 'bundle exec puma -C ${CONF_PATH} -e ${RACK_ENV}'
|
|
9
|
-
|
|
10
|
-
def call(env, config)
|
|
11
|
-
cmd = TTY::Command.new(timeout: 120)
|
|
12
|
-
cmd.run(COMMAND, env: { CONF_PATH: config, RACK_ENV: env })
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
data/lib/sam/puma/predator.rb
DELETED
data/lib/sam/unicorn.rb
DELETED
data/lib/sam/unicorn/breeder.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'tty-command'
|
|
4
|
-
|
|
5
|
-
module Sam
|
|
6
|
-
module Unicorn
|
|
7
|
-
class Breeder
|
|
8
|
-
COMMAND = 'bundle exec unicorn -D -c ${CONF_PATH} -E ${RACK_ENV}'
|
|
9
|
-
|
|
10
|
-
def call(env, config)
|
|
11
|
-
cmd = TTY::Command.new(timeout: 120)
|
|
12
|
-
cmd.run(COMMAND, env: { CONF_PATH: config, RACK_ENV: env })
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
data/lib/sam/unicorn/cloner.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module Unicorn
|
|
5
|
-
class Cloner
|
|
6
|
-
def call(config, timeout: 10)
|
|
7
|
-
pid = Identifier.new.call(config)
|
|
8
|
-
# warn "Cloning unicorn tagged #{pid}"
|
|
9
|
-
Process.kill('USR2', pid)
|
|
10
|
-
# warn "Waiting #{timeout} seconds for clone process to conclude..."
|
|
11
|
-
sleep timeout
|
|
12
|
-
newpid = Identifier.new.call(config)
|
|
13
|
-
# warn "New unicorn cloned with tag #{newpid}. Reaping it's predecessor..."
|
|
14
|
-
Process.kill('QUIT', pid)
|
|
15
|
-
newpid
|
|
16
|
-
# warn 'No one suspects a thing.'
|
|
17
|
-
rescue Errno::ESRCH
|
|
18
|
-
raise Errors::ProcessNotFound, "No process with PID #{pid} found"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
data/lib/sam/unicorn/predator.rb
DELETED
data/lib/sam/unicorn/shepherd.rb
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sam
|
|
4
|
-
module Unicorn
|
|
5
|
-
class Shepherd
|
|
6
|
-
def initialize
|
|
7
|
-
setup_signal_handlers
|
|
8
|
-
@restarting = false
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def call(path, timeout: 10)
|
|
12
|
-
@timeout = timeout
|
|
13
|
-
@config ||= Pathname.new(Dir.pwd).join(path)
|
|
14
|
-
loop do
|
|
15
|
-
alive?
|
|
16
|
-
sleep 1
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def pid
|
|
23
|
-
@pid ||= Identifier.new.call(@config)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def setup_signal_handlers
|
|
27
|
-
trap('HUP') { reload_unicorn }
|
|
28
|
-
trap('QUIT') { forward_signal('QUIT') }
|
|
29
|
-
trap('USR2') { forward_signal('USR2') }
|
|
30
|
-
trap('TTOU') { forward_signal('TTOU') }
|
|
31
|
-
trap('TTIN') { forward_signal('TTIN') }
|
|
32
|
-
trap('TERM') { forward_signal('QUIT') }
|
|
33
|
-
trap('INT') { forward_signal('INT') }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def reload_unicorn
|
|
37
|
-
@restarting = true
|
|
38
|
-
@pid = Cloner.new.call(@config, timeout: @timeout)
|
|
39
|
-
@restarting = false
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def forward_signal(signal)
|
|
43
|
-
warn "Sending #{signal} to unicorn #{pid}"
|
|
44
|
-
Process.kill(signal, pid)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def alive?
|
|
48
|
-
return if @restarting
|
|
49
|
-
Process.kill(0, pid)
|
|
50
|
-
rescue Errno::ESRCH
|
|
51
|
-
raise Errors::ProcessNotFound
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|