process_bot 0.1.0 → 0.1.1
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/.rubocop.yml +180 -4
- data/Gemfile +5 -4
- data/Gemfile.lock +75 -0
- data/lib/process_bot/capistrano/puma/common.rb +86 -0
- data/lib/process_bot/capistrano/puma.rake +9 -6
- data/lib/process_bot/capistrano/puma.rb +4 -6
- data/lib/process_bot/capistrano/sidekiq.rake +6 -9
- data/lib/process_bot/capistrano/sidekiq.rb +5 -3
- data/lib/process_bot/capistrano/sidekiq_helpers.rb +33 -36
- data/lib/process_bot/capistrano.rb +4 -0
- data/lib/process_bot/control_socket.rb +39 -0
- data/lib/process_bot/logger.rb +22 -0
- data/lib/process_bot/options.rb +21 -0
- data/lib/process_bot/process/handlers/sidekiq.rb +55 -0
- data/lib/process_bot/process/handlers.rb +3 -0
- data/lib/process_bot/process/runner.rb +55 -0
- data/lib/process_bot/process.rb +49 -2
- data/lib/process_bot/version.rb +1 -3
- data/lib/process_bot.rb +6 -3
- data/peak_flow.yml +4 -0
- data/process_bot.gemspec +45 -0
- metadata +72 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f81fc2f58388142abc41d1cd0eb5768ea69c1e26b46e2c87ee4f859f19b4d6d4
|
|
4
|
+
data.tar.gz: 754e4510903fb877ccd9cdea055c0b0b4fef87697c0250ebb9a0d9f42cd18fb5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d2bf3cf91868d4c73f31bebe07c9a87d43b6419ed1332410d757f5fb13598a3a6af982311b3c33f654aece52bca325f0ea4d8c9c3fde752c0997b631660b4eb9
|
|
7
|
+
data.tar.gz: 0f6f9fe487f42ce26d709ce88bb01426433f4e985c09e98d88c5f034824c290b0fa974e1e9e9d307c9c339ca888cac06073874661c7a7e6abb36407729430a99
|
data/.rubocop.yml
CHANGED
|
@@ -1,13 +1,189 @@
|
|
|
1
1
|
AllCops:
|
|
2
|
+
DisplayCopNames: true
|
|
3
|
+
DisplayStyleGuide: true
|
|
4
|
+
NewCops: enable
|
|
2
5
|
TargetRubyVersion: 2.6
|
|
3
6
|
|
|
4
|
-
|
|
7
|
+
require:
|
|
8
|
+
- rubocop-performance
|
|
9
|
+
- rubocop-rake
|
|
10
|
+
- rubocop-rspec
|
|
11
|
+
|
|
12
|
+
Layout/AccessModifierIndentation:
|
|
13
|
+
EnforcedStyle: outdent
|
|
14
|
+
|
|
15
|
+
Layout/ArgumentAlignment:
|
|
16
|
+
EnforcedStyle: with_fixed_indentation
|
|
17
|
+
|
|
18
|
+
Layout/CaseIndentation:
|
|
19
|
+
EnforcedStyle: end
|
|
20
|
+
|
|
21
|
+
Layout/EmptyLines:
|
|
22
|
+
Enabled: false
|
|
23
|
+
|
|
24
|
+
Layout/EmptyLinesAroundArguments:
|
|
25
|
+
Enabled: false
|
|
26
|
+
|
|
27
|
+
Layout/EndAlignment:
|
|
28
|
+
EnforcedStyleAlignWith: variable
|
|
29
|
+
|
|
30
|
+
Layout/LineEndStringConcatenationIndentation:
|
|
31
|
+
EnforcedStyle: indented
|
|
32
|
+
|
|
33
|
+
Layout/LineLength:
|
|
34
|
+
Max: 160
|
|
35
|
+
|
|
36
|
+
Layout/MultilineMethodCallIndentation:
|
|
37
|
+
EnforcedStyle: indented
|
|
38
|
+
|
|
39
|
+
Layout/MultilineOperationIndentation:
|
|
40
|
+
EnforcedStyle: indented
|
|
41
|
+
|
|
42
|
+
Layout/ParameterAlignment:
|
|
43
|
+
EnforcedStyle: with_fixed_indentation
|
|
44
|
+
|
|
45
|
+
Layout/RescueEnsureAlignment:
|
|
46
|
+
Enabled: false
|
|
47
|
+
|
|
48
|
+
Layout/SpaceAroundMethodCallOperator:
|
|
49
|
+
Enabled: true
|
|
50
|
+
|
|
51
|
+
Layout/SpaceInsideHashLiteralBraces:
|
|
52
|
+
EnforcedStyle: no_space
|
|
53
|
+
|
|
54
|
+
Lint/MissingSuper:
|
|
55
|
+
Enabled: false
|
|
56
|
+
|
|
57
|
+
Lint/RaiseException:
|
|
58
|
+
Enabled: true
|
|
59
|
+
|
|
60
|
+
Lint/StructNewOverride:
|
|
61
|
+
Enabled: true
|
|
62
|
+
|
|
63
|
+
# Metrics/AbcSize:
|
|
64
|
+
# Max: 25
|
|
65
|
+
|
|
66
|
+
Metrics/BlockLength:
|
|
67
|
+
Enabled: false
|
|
68
|
+
|
|
69
|
+
Metrics/ClassLength:
|
|
70
|
+
Max: 250
|
|
71
|
+
|
|
72
|
+
Metrics/CyclomaticComplexity:
|
|
73
|
+
Max: 12
|
|
74
|
+
|
|
75
|
+
Metrics/MethodLength:
|
|
76
|
+
Max: 50
|
|
77
|
+
|
|
78
|
+
Metrics/ParameterLists:
|
|
79
|
+
CountKeywordArgs: false
|
|
80
|
+
|
|
81
|
+
Metrics/PerceivedComplexity:
|
|
82
|
+
Max: 12
|
|
83
|
+
|
|
84
|
+
RSpec/AnyInstance:
|
|
85
|
+
Enabled: false
|
|
86
|
+
|
|
87
|
+
Style/CaseLikeIf:
|
|
88
|
+
Enabled: false
|
|
89
|
+
|
|
90
|
+
RSpec/ContextWording:
|
|
91
|
+
Enabled: false
|
|
92
|
+
|
|
93
|
+
RSpec/DescribeClass:
|
|
94
|
+
Enabled: false
|
|
95
|
+
|
|
96
|
+
RSpec/DescribedClass:
|
|
97
|
+
Enabled: false
|
|
98
|
+
|
|
99
|
+
RSpec/ExampleLength:
|
|
100
|
+
Enabled: false
|
|
101
|
+
|
|
102
|
+
RSpec/LetSetup:
|
|
103
|
+
Enabled: false
|
|
104
|
+
|
|
105
|
+
RSpec/MessageSpies:
|
|
106
|
+
Enabled: false
|
|
107
|
+
|
|
108
|
+
RSpec/MultipleExpectations:
|
|
109
|
+
Enabled: false
|
|
110
|
+
|
|
111
|
+
RSpec/MultipleMemoizedHelpers:
|
|
112
|
+
Enabled: false
|
|
113
|
+
|
|
114
|
+
RSpec/NamedSubject:
|
|
115
|
+
Enabled: false
|
|
116
|
+
|
|
117
|
+
RSpec/NestedGroups:
|
|
118
|
+
Enabled: false
|
|
119
|
+
|
|
120
|
+
RSpec/StubbedMock:
|
|
121
|
+
Enabled: false
|
|
122
|
+
|
|
123
|
+
Style/ClassAndModuleChildren:
|
|
124
|
+
EnforcedStyle: compact
|
|
125
|
+
|
|
126
|
+
Style/ConditionalAssignment:
|
|
127
|
+
Enabled: false
|
|
128
|
+
|
|
129
|
+
Style/Documentation:
|
|
130
|
+
Enabled: false
|
|
131
|
+
|
|
132
|
+
Style/ExponentialNotation:
|
|
133
|
+
Enabled: true
|
|
134
|
+
|
|
135
|
+
Style/FrozenStringLiteralComment:
|
|
136
|
+
Enabled: false
|
|
137
|
+
|
|
138
|
+
Style/HashAsLastArrayItem:
|
|
139
|
+
Enabled: false
|
|
140
|
+
|
|
141
|
+
Style/HashEachMethods:
|
|
142
|
+
Enabled: true
|
|
143
|
+
|
|
144
|
+
Style/HashTransformKeys:
|
|
145
|
+
Enabled: true
|
|
146
|
+
|
|
147
|
+
Style/HashTransformValues:
|
|
5
148
|
Enabled: true
|
|
149
|
+
|
|
150
|
+
# Will report offences for many places that are much more readable without using a guard clause
|
|
151
|
+
Style/GuardClause:
|
|
152
|
+
Enabled: false
|
|
153
|
+
|
|
154
|
+
Style/KeywordParametersOrder:
|
|
155
|
+
Enabled: false
|
|
156
|
+
|
|
157
|
+
Style/Lambda:
|
|
158
|
+
Enabled: false
|
|
159
|
+
|
|
160
|
+
Style/LambdaCall:
|
|
161
|
+
Enabled: false
|
|
162
|
+
|
|
163
|
+
Style/MultipleComparison:
|
|
164
|
+
Enabled: false
|
|
165
|
+
|
|
166
|
+
Style/RegexpLiteral:
|
|
167
|
+
Enabled: false
|
|
168
|
+
|
|
169
|
+
Style/StringLiterals:
|
|
6
170
|
EnforcedStyle: double_quotes
|
|
7
171
|
|
|
8
172
|
Style/StringLiteralsInInterpolation:
|
|
173
|
+
Enabled: false
|
|
174
|
+
|
|
175
|
+
Style/NilComparison:
|
|
176
|
+
Enabled: false
|
|
177
|
+
|
|
178
|
+
Style/SignalException:
|
|
179
|
+
EnforcedStyle: only_raise
|
|
180
|
+
|
|
181
|
+
Style/SymbolArray:
|
|
182
|
+
Enabled: false
|
|
183
|
+
|
|
184
|
+
Style/TrivialAccessors:
|
|
185
|
+
ExactNameMatch: true
|
|
9
186
|
Enabled: true
|
|
10
|
-
EnforcedStyle: double_quotes
|
|
11
187
|
|
|
12
|
-
|
|
13
|
-
|
|
188
|
+
Style/WordArray:
|
|
189
|
+
Enabled: false
|
data/Gemfile
CHANGED
|
@@ -5,8 +5,9 @@ source "https://rubygems.org"
|
|
|
5
5
|
# Specify your gem's dependencies in process_bot.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem "rake"
|
|
8
|
+
gem "rake"
|
|
9
|
+
gem "rspec"
|
|
10
|
+
gem "rubocop"
|
|
11
|
+
gem "string-cases"
|
|
9
12
|
|
|
10
|
-
gem "
|
|
11
|
-
|
|
12
|
-
gem "rubocop", "~> 1.21"
|
|
13
|
+
gem "pry"
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
process_bot (0.1.1)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
ast (2.4.2)
|
|
10
|
+
coderay (1.1.3)
|
|
11
|
+
diff-lcs (1.5.0)
|
|
12
|
+
json (2.6.2)
|
|
13
|
+
method_source (1.0.0)
|
|
14
|
+
parallel (1.22.1)
|
|
15
|
+
parser (3.1.2.1)
|
|
16
|
+
ast (~> 2.4.1)
|
|
17
|
+
pry (0.14.1)
|
|
18
|
+
coderay (~> 1.1)
|
|
19
|
+
method_source (~> 1.0)
|
|
20
|
+
rainbow (3.1.1)
|
|
21
|
+
rake (13.0.6)
|
|
22
|
+
regexp_parser (2.6.0)
|
|
23
|
+
rexml (3.2.5)
|
|
24
|
+
rspec (3.11.0)
|
|
25
|
+
rspec-core (~> 3.11.0)
|
|
26
|
+
rspec-expectations (~> 3.11.0)
|
|
27
|
+
rspec-mocks (~> 3.11.0)
|
|
28
|
+
rspec-core (3.11.0)
|
|
29
|
+
rspec-support (~> 3.11.0)
|
|
30
|
+
rspec-expectations (3.11.0)
|
|
31
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
32
|
+
rspec-support (~> 3.11.0)
|
|
33
|
+
rspec-mocks (3.11.1)
|
|
34
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
35
|
+
rspec-support (~> 3.11.0)
|
|
36
|
+
rspec-support (3.11.0)
|
|
37
|
+
rubocop (1.36.0)
|
|
38
|
+
json (~> 2.3)
|
|
39
|
+
parallel (~> 1.10)
|
|
40
|
+
parser (>= 3.1.2.1)
|
|
41
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
42
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
43
|
+
rexml (>= 3.2.5, < 4.0)
|
|
44
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
|
45
|
+
ruby-progressbar (~> 1.7)
|
|
46
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
47
|
+
rubocop-ast (1.21.0)
|
|
48
|
+
parser (>= 3.1.1.0)
|
|
49
|
+
rubocop-performance (1.15.0)
|
|
50
|
+
rubocop (>= 1.7.0, < 2.0)
|
|
51
|
+
rubocop-ast (>= 0.4.0)
|
|
52
|
+
rubocop-rake (0.6.0)
|
|
53
|
+
rubocop (~> 1.0)
|
|
54
|
+
rubocop-rspec (2.11.1)
|
|
55
|
+
rubocop (~> 1.19)
|
|
56
|
+
ruby-progressbar (1.11.0)
|
|
57
|
+
string-cases (0.0.4)
|
|
58
|
+
unicode-display_width (2.3.0)
|
|
59
|
+
|
|
60
|
+
PLATFORMS
|
|
61
|
+
x86_64-linux
|
|
62
|
+
|
|
63
|
+
DEPENDENCIES
|
|
64
|
+
process_bot!
|
|
65
|
+
pry
|
|
66
|
+
rake
|
|
67
|
+
rspec
|
|
68
|
+
rubocop
|
|
69
|
+
rubocop-performance
|
|
70
|
+
rubocop-rake
|
|
71
|
+
rubocop-rspec
|
|
72
|
+
string-cases
|
|
73
|
+
|
|
74
|
+
BUNDLED WITH
|
|
75
|
+
2.3.8
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module ProcessBot::Capistrano::Puma::Common
|
|
2
|
+
def puma_switch_user(role)
|
|
3
|
+
user = puma_user(role)
|
|
4
|
+
if user == role.user
|
|
5
|
+
yield
|
|
6
|
+
else
|
|
7
|
+
backend.as user, &block
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def puma_user(role)
|
|
12
|
+
properties = role.properties
|
|
13
|
+
properties.fetch(:puma_user) || # local property for puma only
|
|
14
|
+
fetch(:puma_user) ||
|
|
15
|
+
properties.fetch(:run_as) || # global property across multiple capistrano gems
|
|
16
|
+
role.user
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def puma_bind
|
|
20
|
+
Array(fetch(:puma_bind)).collect do |bind|
|
|
21
|
+
"bind '#{bind}'"
|
|
22
|
+
end.join("\n")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def compiled_template_puma(from, role)
|
|
26
|
+
@role = role
|
|
27
|
+
file = [
|
|
28
|
+
"lib/capistrano/templates/#{from}-#{role.hostname}-#{fetch(:stage)}.rb",
|
|
29
|
+
"lib/capistrano/templates/#{from}-#{role.hostname}.rb",
|
|
30
|
+
"lib/capistrano/templates/#{from}-#{fetch(:stage)}.rb",
|
|
31
|
+
"lib/capistrano/templates/#{from}.rb.erb",
|
|
32
|
+
"lib/capistrano/templates/#{from}.rb",
|
|
33
|
+
"lib/capistrano/templates/#{from}.erb",
|
|
34
|
+
"config/deploy/templates/#{from}.rb.erb",
|
|
35
|
+
"config/deploy/templates/#{from}.rb",
|
|
36
|
+
"config/deploy/templates/#{from}.erb",
|
|
37
|
+
File.expand_path("../templates/#{from}.erb", __FILE__),
|
|
38
|
+
File.expand_path("../templates/#{from}.rb.erb", __FILE__)
|
|
39
|
+
].detect { |path| File.file?(path) }
|
|
40
|
+
erb = File.read(file)
|
|
41
|
+
StringIO.new(ERB.new(erb, trim_mode: "-").result(binding))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def template_puma(from, to, role)
|
|
45
|
+
backend.upload! compiled_template_puma(from, role), to
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
PumaBind = Struct.new(:full_address, :kind, :address) do
|
|
49
|
+
def unix?
|
|
50
|
+
kind == :unix
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def ssl?
|
|
54
|
+
kind == :ssl
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def tcp
|
|
58
|
+
kind == :tcp || ssl?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def local
|
|
62
|
+
if unix?
|
|
63
|
+
self
|
|
64
|
+
else
|
|
65
|
+
PumaBind.new(
|
|
66
|
+
localize_address(full_address),
|
|
67
|
+
kind,
|
|
68
|
+
localize_address(address)
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def localize_address(address)
|
|
76
|
+
address.gsub(/0\.0\.0\.0(.+)/, "127.0.0.1\\1")
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def puma_binds
|
|
81
|
+
Array(fetch(:puma_bind)).map do |m|
|
|
82
|
+
etype, address = /(tcp|unix|ssl):\/{1,2}(.+)/.match(m).captures
|
|
83
|
+
PumaBind.new(m, etype.to_sym, address)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -6,7 +6,7 @@ namespace :process_bot do
|
|
|
6
6
|
task :start do
|
|
7
7
|
on roles(fetch(:puma_role)) do |role|
|
|
8
8
|
git_plugin.puma_switch_user(role) do
|
|
9
|
-
if test
|
|
9
|
+
if test("[ -f #{fetch(:puma_pid)} ]") && test(:kill, "-0 $( cat #{fetch(:puma_pid)} )")
|
|
10
10
|
info "Puma is already running"
|
|
11
11
|
else
|
|
12
12
|
within current_path do
|
|
@@ -24,7 +24,9 @@ namespace :process_bot do
|
|
|
24
24
|
"--control-token foobar"
|
|
25
25
|
]
|
|
26
26
|
|
|
27
|
-
command = "/usr/bin/screen -dmS puma-#{latest_release_version}
|
|
27
|
+
command = "/usr/bin/screen -dmS puma-#{latest_release_version} " \
|
|
28
|
+
"bash -c 'cd #{release_path} && #{SSHKit.config.command_map.prefix[:puma].join(" ")} puma #{puma_args.join(" ")}'"
|
|
29
|
+
|
|
28
30
|
execute command
|
|
29
31
|
end
|
|
30
32
|
end
|
|
@@ -36,7 +38,7 @@ namespace :process_bot do
|
|
|
36
38
|
%w[halt stop status].map do |command|
|
|
37
39
|
desc "#{command} puma"
|
|
38
40
|
task command do
|
|
39
|
-
on roles
|
|
41
|
+
on roles(fetch(:puma_role)) do |role|
|
|
40
42
|
within current_path do
|
|
41
43
|
git_plugin.puma_switch_user(role) do
|
|
42
44
|
with rack_env: fetch(:puma_env) do
|
|
@@ -48,7 +50,7 @@ namespace :process_bot do
|
|
|
48
50
|
execute :rm, fetch(:puma_pid)
|
|
49
51
|
end
|
|
50
52
|
else
|
|
51
|
-
#pid file not found, so puma is probably not running or it using another pidfile
|
|
53
|
+
# pid file not found, so puma is probably not running or it using another pidfile
|
|
52
54
|
warn "Puma not running"
|
|
53
55
|
end
|
|
54
56
|
end
|
|
@@ -61,12 +63,12 @@ namespace :process_bot do
|
|
|
61
63
|
%w[phased-restart restart].map do |command|
|
|
62
64
|
desc "#{command} puma"
|
|
63
65
|
task command do
|
|
64
|
-
on roles
|
|
66
|
+
on roles(fetch(:puma_role)) do |role|
|
|
65
67
|
within current_path do
|
|
66
68
|
git_plugin.puma_switch_user(role) do
|
|
67
69
|
with rack_env: fetch(:puma_env) do
|
|
68
70
|
if git_plugin.puma_running?
|
|
69
|
-
# NOTE pid exist but state file is nonsense, so ignore that case
|
|
71
|
+
# NOTE: pid exist but state file is nonsense, so ignore that case
|
|
70
72
|
git_plugin.run_puma_command(command)
|
|
71
73
|
else
|
|
72
74
|
# Puma is not running or state file is not present : Run it
|
|
@@ -79,6 +81,7 @@ namespace :process_bot do
|
|
|
79
81
|
end
|
|
80
82
|
end
|
|
81
83
|
|
|
84
|
+
desc "Restarts Puma phased if using workers and preload and otherwise a normal restart."
|
|
82
85
|
task :smart_restart do
|
|
83
86
|
if !fetch(:puma_preload_app) && fetch(:puma_workers, 0).to_i > 1
|
|
84
87
|
invoke "process_bot:puma:phased-restart"
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
class ProcessBot::Capistrano::Puma < Capistrano::Plugin
|
|
2
|
+
autoload :Common, "#{__dir__}/puma/common"
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
after 'deploy:finished', 'process_bot:puma:smart_restart'
|
|
6
|
-
end
|
|
4
|
+
include ::ProcessBot::Capistrano::Puma::Common
|
|
7
5
|
|
|
8
6
|
def define_tasks
|
|
9
|
-
eval_rakefile File.expand_path(
|
|
7
|
+
eval_rakefile File.expand_path("./puma.rake", __dir__)
|
|
10
8
|
end
|
|
11
9
|
|
|
12
10
|
def puma_running?
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
git_plugin = self
|
|
2
2
|
|
|
3
3
|
namespace :load do
|
|
4
|
+
desc "Default variables for Sidekiq"
|
|
4
5
|
task :defaults do
|
|
5
6
|
set :sidekiq_default_hooks, true
|
|
6
7
|
|
|
@@ -18,17 +19,12 @@ namespace :load do
|
|
|
18
19
|
set :chruby_map_bins, fetch(:chruby_map_bins).to_a.concat(%w[sidekiq sidekiqctl])
|
|
19
20
|
# Bundler integration
|
|
20
21
|
set :bundle_bins, fetch(:bundle_bins).to_a.concat(%w[sidekiq sidekiqctl])
|
|
21
|
-
# Init system integration
|
|
22
|
-
set :init_system, -> { nil }
|
|
23
|
-
# systemd integration
|
|
24
|
-
set :service_unit_name, "sidekiq-#{fetch(:stage)}.service"
|
|
25
|
-
set :upstart_service_name, "sidekiq"
|
|
26
22
|
end
|
|
27
23
|
end
|
|
28
24
|
|
|
29
25
|
namespace :process_bot do
|
|
30
26
|
namespace :sidekiq do
|
|
31
|
-
desc
|
|
27
|
+
desc "Quiet sidekiq (stop fetching new tasks from Redis)"
|
|
32
28
|
task :quiet do
|
|
33
29
|
on roles fetch(:sidekiq_roles) do |role|
|
|
34
30
|
git_plugin.switch_user(role) do
|
|
@@ -39,7 +35,7 @@ namespace :process_bot do
|
|
|
39
35
|
end
|
|
40
36
|
end
|
|
41
37
|
|
|
42
|
-
desc
|
|
38
|
+
desc "Stop Sidekiq (graceful shutdown within timeout, put unfinished tasks back to Redis)"
|
|
43
39
|
task :stop do
|
|
44
40
|
on roles fetch(:sidekiq_roles) do |role|
|
|
45
41
|
git_plugin.switch_user(role) do
|
|
@@ -50,6 +46,7 @@ namespace :process_bot do
|
|
|
50
46
|
end
|
|
51
47
|
end
|
|
52
48
|
|
|
49
|
+
desc "Stops Sidekiq after a set amount of time"
|
|
53
50
|
task :stop_after_time do
|
|
54
51
|
on roles fetch(:sidekiq_roles) do |role|
|
|
55
52
|
git_plugin.switch_user(role) do
|
|
@@ -60,7 +57,7 @@ namespace :process_bot do
|
|
|
60
57
|
end
|
|
61
58
|
end
|
|
62
59
|
|
|
63
|
-
desc
|
|
60
|
+
desc "Start sidekiq"
|
|
64
61
|
task :start do
|
|
65
62
|
on roles fetch(:sidekiq_roles) do |role|
|
|
66
63
|
git_plugin.switch_user(role) do
|
|
@@ -72,7 +69,7 @@ namespace :process_bot do
|
|
|
72
69
|
end
|
|
73
70
|
end
|
|
74
71
|
|
|
75
|
-
desc
|
|
72
|
+
desc "Restart sidekiq"
|
|
76
73
|
task :restart do
|
|
77
74
|
invoke! "process_bot:sidekiq:stop"
|
|
78
75
|
invoke! "process_bot:sidekiq:start"
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require_relative "sidekiq_helpers"
|
|
2
|
+
|
|
3
|
+
class ProcessBot::Capistrano::Sidekiq < Capistrano::Plugin
|
|
4
|
+
include ProcessBot::Capistrano::SidekiqHelpers
|
|
3
5
|
|
|
4
6
|
def define_tasks
|
|
5
|
-
eval_rakefile File.expand_path("./sidekiq.rake",
|
|
7
|
+
eval_rakefile File.expand_path("./sidekiq.rake", __dir__)
|
|
6
8
|
end
|
|
7
9
|
end
|
|
@@ -1,44 +1,36 @@
|
|
|
1
|
-
module ProcessBot::
|
|
1
|
+
module ProcessBot::Capistrano::SidekiqHelpers
|
|
2
2
|
def sidekiq_require
|
|
3
|
-
if fetch(:sidekiq_require)
|
|
4
|
-
"--require #{fetch(:sidekiq_require)}"
|
|
5
|
-
end
|
|
3
|
+
"--require #{fetch(:sidekiq_require)}" if fetch(:sidekiq_require)
|
|
6
4
|
end
|
|
7
5
|
|
|
8
6
|
def sidekiq_config
|
|
9
|
-
if fetch(:sidekiq_config)
|
|
10
|
-
"--config #{fetch(:sidekiq_config)}"
|
|
11
|
-
end
|
|
7
|
+
"--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
|
12
8
|
end
|
|
13
9
|
|
|
14
10
|
def sidekiq_concurrency
|
|
15
|
-
if fetch(:sidekiq_concurrency)
|
|
16
|
-
"--concurrency #{fetch(:sidekiq_concurrency)}"
|
|
17
|
-
end
|
|
11
|
+
"--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
|
|
18
12
|
end
|
|
19
13
|
|
|
20
14
|
def sidekiq_queues
|
|
21
15
|
Array(fetch(:sidekiq_queue)).map do |queue|
|
|
22
16
|
"--queue #{queue}"
|
|
23
|
-
end.join(
|
|
17
|
+
end.join(" ")
|
|
24
18
|
end
|
|
25
19
|
|
|
26
20
|
def sidekiq_logfile
|
|
27
21
|
fetch(:sidekiq_log)
|
|
28
22
|
end
|
|
29
23
|
|
|
30
|
-
def switch_user(role)
|
|
24
|
+
def switch_user(role, &block)
|
|
31
25
|
su_user = sidekiq_user(role)
|
|
32
26
|
if su_user == role.user
|
|
33
27
|
yield
|
|
34
28
|
else
|
|
35
|
-
as su_user
|
|
36
|
-
yield
|
|
37
|
-
end
|
|
29
|
+
as su_user, &block
|
|
38
30
|
end
|
|
39
31
|
end
|
|
40
32
|
|
|
41
|
-
VALID_SIGNALS = ["TERM", "TSTP"]
|
|
33
|
+
VALID_SIGNALS = ["TERM", "TSTP"].freeze
|
|
42
34
|
def stop_sidekiq(pid:, signal:)
|
|
43
35
|
raise "Invalid PID: #{pid}" unless pid.to_s.match?(/\A\d+\Z/)
|
|
44
36
|
raise "Invalid signal: #{signal}" unless VALID_SIGNALS.include?(signal)
|
|
@@ -53,7 +45,7 @@ module ProcessBot::Sidekiq::Helpers
|
|
|
53
45
|
time = ENV["STOP_AFTER_TIME"] || fetch(:sidekiq_stop_after_time)
|
|
54
46
|
raise "Invalid time: #{time}" unless time.to_s.match?(/\A\d+\Z/)
|
|
55
47
|
|
|
56
|
-
backend.execute "screen -dmS stopsidekiq#{pid} sleep #{time}
|
|
48
|
+
backend.execute "screen -dmS stopsidekiq#{pid} bash -c \"sleep #{time} && kill -#{signal} #{pid}\""
|
|
57
49
|
end
|
|
58
50
|
|
|
59
51
|
def running_sidekiq_processes
|
|
@@ -94,23 +86,7 @@ module ProcessBot::Sidekiq::Helpers
|
|
|
94
86
|
backend.capture(:echo, SSHKit.config.command_map[:bundle]).strip
|
|
95
87
|
end
|
|
96
88
|
|
|
97
|
-
def start_sidekiq(idx = 0)
|
|
98
|
-
args = []
|
|
99
|
-
args.push "--environment #{fetch(:sidekiq_env)}"
|
|
100
|
-
#args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
|
101
|
-
args.push "--require #{fetch(:sidekiq_require)}" if fetch(:sidekiq_require)
|
|
102
|
-
args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag)
|
|
103
|
-
Array(fetch(:sidekiq_queue)).each do |queue|
|
|
104
|
-
args.push "--queue #{queue}"
|
|
105
|
-
end
|
|
106
|
-
args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config)
|
|
107
|
-
args.push "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency)
|
|
108
|
-
if (process_options = fetch(:sidekiq_options_per_process))
|
|
109
|
-
args.push process_options[idx]
|
|
110
|
-
end
|
|
111
|
-
# use sidekiq_options for special options
|
|
112
|
-
args.push fetch(:sidekiq_options) if fetch(:sidekiq_options)
|
|
113
|
-
|
|
89
|
+
def start_sidekiq(idx = 0) # rubocop:disable Metrics/AbcSize
|
|
114
90
|
releases = backend.capture(:ls, "-x", releases_path).split
|
|
115
91
|
releases << release_timestamp.to_s if release_timestamp
|
|
116
92
|
releases.uniq
|
|
@@ -118,13 +94,34 @@ module ProcessBot::Sidekiq::Helpers
|
|
|
118
94
|
latest_release_version = releases.last
|
|
119
95
|
raise "Invalid release timestamp: #{release_timestamp}" unless latest_release_version
|
|
120
96
|
|
|
97
|
+
args = [
|
|
98
|
+
"--id", "sidekiq-#{latest_release_version}-#{idx}",
|
|
99
|
+
"--handler", "sidekiq",
|
|
100
|
+
"--bundle-prefix", SSHKit.config.command_map.prefix[:bundle].join(" "),
|
|
101
|
+
"--sidekiq-environment", fetch(:sidekiq_env),
|
|
102
|
+
"--port", 7050 + idx
|
|
103
|
+
]
|
|
104
|
+
args += ["--log-file-path", fetch(:sidekiq_log)] if fetch(:sidekiq_log)
|
|
105
|
+
args += ["--sidekiq-require", fetch(:sidekiq_require)] if fetch(:sidekiq_require)
|
|
106
|
+
args += ["--sidekiq-tag", fetch(:sidekiq_tag)] if fetch(:sidekiq_tag)
|
|
107
|
+
args += ["--sidekiq-queues", Array(fetch(:sidekiq_queue)).join(",")] if fetch(:sidekiq_queue)
|
|
108
|
+
args += ["--sidekiq-config", fetch(:sidekiq_config)] if fetch(:sidekiq_config)
|
|
109
|
+
args += ["--sidekiq-concurrency", fetch(:sidekiq_concurrency)] if fetch(:sidekiq_concurrency)
|
|
110
|
+
if (process_options = fetch(:sidekiq_options_per_process))
|
|
111
|
+
args += process_options[idx]
|
|
112
|
+
end
|
|
113
|
+
args += fetch(:sidekiq_options) if fetch(:sidekiq_options)
|
|
114
|
+
|
|
121
115
|
screen_args = ["-dmS sidekiq-#{idx}-#{latest_release_version}"]
|
|
122
116
|
screen_args << "-L -Logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log)
|
|
123
117
|
|
|
124
|
-
|
|
125
|
-
|
|
118
|
+
process_bot_args = args.compact.map { |arg| "\"#{arg}\"" }
|
|
119
|
+
|
|
120
|
+
command = "/usr/bin/screen #{screen_args.join(" ")} " \
|
|
121
|
+
"bash -c 'cd #{release_path} && #{SSHKit.config.command_map.prefix[:bundle].join(" ")} bundle exec process_bot #{process_bot_args.join(" ")}'"
|
|
126
122
|
|
|
127
123
|
puts "WARNING: A known bug prevents Sidekiq from starting when pty is set (which it is)" if fetch(:pty)
|
|
124
|
+
puts "ProcessBot Sidekiq command: #{command}"
|
|
128
125
|
|
|
129
126
|
backend.execute command
|
|
130
127
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class ProcessBot::ControlSocket
|
|
2
|
+
attr_reader :options, :process, :server
|
|
3
|
+
|
|
4
|
+
def initialize(options:, process:)
|
|
5
|
+
@options = options
|
|
6
|
+
@process = process
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def port
|
|
10
|
+
options.fetch(:port).to_i
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def start
|
|
14
|
+
require "socket"
|
|
15
|
+
|
|
16
|
+
@server = TCPServer.new(port)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run_client_loop
|
|
20
|
+
Thread.new do
|
|
21
|
+
client = server.accept
|
|
22
|
+
|
|
23
|
+
Thread.new do
|
|
24
|
+
handle_client(client)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def handle_client(client)
|
|
30
|
+
command = JSON.parse(client.gets)
|
|
31
|
+
type = command.fetch("type")
|
|
32
|
+
|
|
33
|
+
if type == "stop"
|
|
34
|
+
process.stop
|
|
35
|
+
else
|
|
36
|
+
client.puts(JSON.generate(type: "error", message: "Unknown type: #{type}"))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class ProcessBot::Logger
|
|
2
|
+
attr_reader :fp_log, :options
|
|
3
|
+
|
|
4
|
+
def initialize(options:)
|
|
5
|
+
@options = options
|
|
6
|
+
|
|
7
|
+
open_file
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def log(output)
|
|
11
|
+
fp_log&.write(output)
|
|
12
|
+
fp_log&.flush
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def log_file_path
|
|
16
|
+
options.fetch(:log_file_path)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def open_file
|
|
20
|
+
@fp_log = File.open(log_file_path, "a")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class ProcessBot::Options
|
|
2
|
+
attr_reader :options
|
|
3
|
+
|
|
4
|
+
def initialize(options = {})
|
|
5
|
+
@options = options
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def fetch(*args, **opts, &blk)
|
|
9
|
+
options.fetch(*args, **opts, &blk)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def present?(key)
|
|
13
|
+
return true if options.key?(key) && options[key]
|
|
14
|
+
|
|
15
|
+
false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def set(key, value)
|
|
19
|
+
options[key] = value
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
class ProcessBot::Process::Handlers::Sidekiq
|
|
2
|
+
attr_reader :options
|
|
3
|
+
|
|
4
|
+
def initialize(options)
|
|
5
|
+
@options = options
|
|
6
|
+
|
|
7
|
+
set_defaults
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def fetch(*args, **opts)
|
|
11
|
+
options.fetch(*args, **opts)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def set_option(key, value)
|
|
15
|
+
raise "Unknown option for Sidekiq handler: #{key}" unless options.key?(key)
|
|
16
|
+
|
|
17
|
+
set(key, value)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def set(*args, **opts)
|
|
21
|
+
options.set(*args, **opts)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def set_defaults
|
|
25
|
+
set :sidekiq_default_hooks, true
|
|
26
|
+
set :sidekiq_pid, -> { File.join(shared_path, "tmp", "pids", "sidekiq.pid") }
|
|
27
|
+
set :sidekiq_timeout, 10
|
|
28
|
+
set :sidekiq_roles, fetch(:sidekiq_role, :app)
|
|
29
|
+
set :sidekiq_processes, 1
|
|
30
|
+
set :sidekiq_options_per_process, nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def command # rubocop:disable Metrics/AbcSize
|
|
34
|
+
args = []
|
|
35
|
+
|
|
36
|
+
options.options.each do |key, value|
|
|
37
|
+
if (match = key.to_s.match(/\Asidekiq-(.+)\Z/))
|
|
38
|
+
sidekiq_key = match[1]
|
|
39
|
+
|
|
40
|
+
if sidekiq_key == "queue"
|
|
41
|
+
value.split(",").each do |queue|
|
|
42
|
+
args.push "--queue #{value}"
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
args.push "--#{sidekiq_key} #{value}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
command = ""
|
|
51
|
+
command << "#{options.fetch(:bundle_prefix)} " if options.present?(:bundle_prefix)
|
|
52
|
+
command << "bundle exec sidekiq #{args.compact.join(' ')}"
|
|
53
|
+
command
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
class ProcessBot::Process::Runner
|
|
2
|
+
attr_reader :command, :exit_status, :logger, :monitor, :options, :stop_time
|
|
3
|
+
|
|
4
|
+
def initialize(command:, logger:, options:)
|
|
5
|
+
@command = command
|
|
6
|
+
@logger = logger
|
|
7
|
+
@monitor = Monitor.new
|
|
8
|
+
@options = options
|
|
9
|
+
@output = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def output(output:, type:) # rubocop:disable Lint/UnusedMethodArgument
|
|
13
|
+
logger.log(output)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def run # rubocop:disable Metrics/AbcSize
|
|
17
|
+
@start_time = Time.new
|
|
18
|
+
stderr_reader, stderr_writer = IO.pipe
|
|
19
|
+
|
|
20
|
+
require "pty"
|
|
21
|
+
|
|
22
|
+
PTY.spawn(command, err: stderr_writer.fileno) do |stdout, _stdin, pid|
|
|
23
|
+
@pid = pid
|
|
24
|
+
logger.log "Command running with PID #{pid}: #{command}"
|
|
25
|
+
|
|
26
|
+
stdout_reader_thread = Thread.new do
|
|
27
|
+
stdout.each_char do |chunk|
|
|
28
|
+
monitor.synchronize do
|
|
29
|
+
output(type: :stdout, output: chunk)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
rescue Errno::EIO
|
|
33
|
+
# Process done
|
|
34
|
+
ensure
|
|
35
|
+
status = Process::Status.wait(@pid, 0)
|
|
36
|
+
|
|
37
|
+
@exit_status = status.exitstatus
|
|
38
|
+
stderr_writer.close
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
stderr_reader_thread = Thread.new do
|
|
42
|
+
stderr_reader.each_char do |chunk|
|
|
43
|
+
monitor.synchronize do
|
|
44
|
+
output(type: :stderr, output: chunk)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
stdout_reader_thread.join
|
|
50
|
+
stderr_reader_thread.join
|
|
51
|
+
|
|
52
|
+
@stop_time = Time.new
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/process_bot/process.rb
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
class ProcessBot::Process
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
autoload :Handlers, "#{__dir__}/process/handlers"
|
|
3
|
+
autoload :Runner, "#{__dir__}/process/runner"
|
|
4
|
+
|
|
5
|
+
attr_reader :options, :stopped
|
|
6
|
+
|
|
7
|
+
def initialize(options)
|
|
8
|
+
@options = options
|
|
9
|
+
@stopped = false
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def logger
|
|
13
|
+
@logger ||= ProcessBot::Logger.new(options: options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def start_control_socket
|
|
17
|
+
@control_socket = ProcessBot::ControlSocket.new(options: options, process: self)
|
|
18
|
+
@control_socket.start
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def stop
|
|
22
|
+
@stopped = true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def handler_class
|
|
26
|
+
@handler_class ||= begin
|
|
27
|
+
require_relative "process/handlers/#{options.fetch(:handler)}"
|
|
28
|
+
ProcessBot::Process::Handlers.const_get(StringCases.snake_to_camel(options.fetch(:handler)))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def execute!
|
|
33
|
+
start_control_socket
|
|
34
|
+
|
|
35
|
+
loop do
|
|
36
|
+
run
|
|
37
|
+
|
|
38
|
+
if stopped
|
|
39
|
+
break
|
|
40
|
+
else
|
|
41
|
+
puts "Process stopped - starting again after 1 sec"
|
|
42
|
+
sleep 1
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def run
|
|
48
|
+
handler_instance = handler_class.new(options)
|
|
49
|
+
runner = ProcessBot::Process::Runner.new(command: handler_instance.command, logger: logger, options: options)
|
|
50
|
+
runner.run
|
|
4
51
|
end
|
|
5
52
|
end
|
data/lib/process_bot/version.rb
CHANGED
data/lib/process_bot.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
require_relative "process_bot/version"
|
|
4
2
|
|
|
5
3
|
module ProcessBot
|
|
6
4
|
class Error < StandardError; end
|
|
7
|
-
|
|
5
|
+
|
|
6
|
+
autoload :Capistrano, "#{__dir__}/process_bot/capistrano"
|
|
7
|
+
autoload :ControlSocket, "#{__dir__}/process_bot/control_socket"
|
|
8
|
+
autoload :Logger, "#{__dir__}/process_bot/logger"
|
|
9
|
+
autoload :Options, "#{__dir__}/process_bot/options"
|
|
10
|
+
autoload :Process, "#{__dir__}/process_bot/process"
|
|
8
11
|
end
|
data/peak_flow.yml
ADDED
data/process_bot.gemspec
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/process_bot/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "process_bot"
|
|
7
|
+
spec.version = ProcessBot::VERSION
|
|
8
|
+
spec.authors = ["kaspernj"]
|
|
9
|
+
spec.email = ["k@spernj.org"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Run and control processes."
|
|
12
|
+
spec.description = "Run and control processes."
|
|
13
|
+
spec.homepage = "https://github.com/kaspernj/process_bot"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = ">= 2.6.0"
|
|
16
|
+
|
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
18
|
+
|
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/kaspernj/process_bot"
|
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/kaspernj/process_bot/blob/master/CHANGELOG.md"
|
|
22
|
+
|
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
26
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
27
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|exe|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
spec.bindir = "exe"
|
|
31
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
32
|
+
spec.require_paths = ["lib"]
|
|
33
|
+
|
|
34
|
+
# Uncomment to register a new dependency of your gem
|
|
35
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
|
36
|
+
|
|
37
|
+
spec.add_development_dependency "rubocop"
|
|
38
|
+
spec.add_development_dependency "rubocop-performance"
|
|
39
|
+
spec.add_development_dependency "rubocop-rake"
|
|
40
|
+
spec.add_development_dependency "rubocop-rspec"
|
|
41
|
+
|
|
42
|
+
# For more information and examples about making a new gem, check out our
|
|
43
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
|
44
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
45
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,71 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: process_bot
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kaspernj
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
12
|
-
dependencies:
|
|
11
|
+
date: 2022-10-18 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rubocop
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rubocop-performance
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rubocop-rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rubocop-rspec
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
13
69
|
description: Run and control processes.
|
|
14
70
|
email:
|
|
15
71
|
- k@spernj.org
|
|
@@ -21,17 +77,28 @@ files:
|
|
|
21
77
|
- ".rubocop.yml"
|
|
22
78
|
- CHANGELOG.md
|
|
23
79
|
- Gemfile
|
|
80
|
+
- Gemfile.lock
|
|
24
81
|
- LICENSE.txt
|
|
25
82
|
- README.md
|
|
26
83
|
- Rakefile
|
|
27
84
|
- lib/process_bot.rb
|
|
85
|
+
- lib/process_bot/capistrano.rb
|
|
28
86
|
- lib/process_bot/capistrano/puma.rake
|
|
29
87
|
- lib/process_bot/capistrano/puma.rb
|
|
88
|
+
- lib/process_bot/capistrano/puma/common.rb
|
|
30
89
|
- lib/process_bot/capistrano/sidekiq.rake
|
|
31
90
|
- lib/process_bot/capistrano/sidekiq.rb
|
|
32
91
|
- lib/process_bot/capistrano/sidekiq_helpers.rb
|
|
92
|
+
- lib/process_bot/control_socket.rb
|
|
93
|
+
- lib/process_bot/logger.rb
|
|
94
|
+
- lib/process_bot/options.rb
|
|
33
95
|
- lib/process_bot/process.rb
|
|
96
|
+
- lib/process_bot/process/handlers.rb
|
|
97
|
+
- lib/process_bot/process/handlers/sidekiq.rb
|
|
98
|
+
- lib/process_bot/process/runner.rb
|
|
34
99
|
- lib/process_bot/version.rb
|
|
100
|
+
- peak_flow.yml
|
|
101
|
+
- process_bot.gemspec
|
|
35
102
|
- sig/process_bot.rbs
|
|
36
103
|
homepage: https://github.com/kaspernj/process_bot
|
|
37
104
|
licenses:
|
|
@@ -41,6 +108,7 @@ metadata:
|
|
|
41
108
|
homepage_uri: https://github.com/kaspernj/process_bot
|
|
42
109
|
source_code_uri: https://github.com/kaspernj/process_bot
|
|
43
110
|
changelog_uri: https://github.com/kaspernj/process_bot/blob/master/CHANGELOG.md
|
|
111
|
+
rubygems_mfa_required: 'true'
|
|
44
112
|
post_install_message:
|
|
45
113
|
rdoc_options: []
|
|
46
114
|
require_paths:
|
|
@@ -56,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
56
124
|
- !ruby/object:Gem::Version
|
|
57
125
|
version: '0'
|
|
58
126
|
requirements: []
|
|
59
|
-
rubygems_version: 3.
|
|
127
|
+
rubygems_version: 3.3.7
|
|
60
128
|
signing_key:
|
|
61
129
|
specification_version: 4
|
|
62
130
|
summary: Run and control processes.
|