einhorn 0.5.6 → 0.5.7
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.
- data/Gemfile +3 -0
- data/README.md +2 -5
- data/example/thin_example +5 -5
- data/lib/einhorn/command.rb +34 -5
- data/lib/einhorn/command/interface.rb +15 -0
- data/lib/einhorn/version.rb +1 -1
- data/lib/einhorn/worker.rb +17 -0
- metadata +4 -9
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -238,11 +238,8 @@ servers) to a wider array of applications.
|
|
238
238
|
See https://stripe.com/blog/meet-einhorn for more background.
|
239
239
|
|
240
240
|
Stripe currently uses Einhorn in production for a number of
|
241
|
-
services.
|
242
|
-
|
243
|
-
can obtain these patches from our public forks of the
|
244
|
-
[respective](https://github.com/stripe/thin)
|
245
|
-
[projects](https://github.com/stripe/eventmachine). Check out
|
241
|
+
services. You can use Conrad Irwin's thin-attach_socket gem along with
|
242
|
+
EventMachine-LE to support file-descriptor passing. Check out
|
246
243
|
`example/thin_example` for an example of running Thin under Einhorn.
|
247
244
|
|
248
245
|
## Compatibility
|
data/example/thin_example
CHANGED
@@ -9,11 +9,9 @@
|
|
9
9
|
require 'rubygems'
|
10
10
|
require 'einhorn'
|
11
11
|
|
12
|
-
|
13
|
-
gem 'thin', '1.3.2.stripe.0'
|
14
|
-
gem 'eventmachine', '1.0.0.beta.4.stripe.0'
|
15
|
-
|
12
|
+
require 'eventmachine-le'
|
16
13
|
require 'thin'
|
14
|
+
require 'thin/attach_socket'
|
17
15
|
|
18
16
|
class App
|
19
17
|
def initialize(id)
|
@@ -42,7 +40,9 @@ def einhorn_main
|
|
42
40
|
EventMachine.run do
|
43
41
|
(0...fd_count).each do |i|
|
44
42
|
sock = Einhorn::Worker.socket!(i)
|
45
|
-
srv = Thin::Server.new(
|
43
|
+
srv = Thin::Server.new(App.new(i),
|
44
|
+
:backend => Thin::Backends::AttachSocket,
|
45
|
+
:socket => IO.for_fd(sock))
|
46
46
|
srv.start
|
47
47
|
end
|
48
48
|
end
|
data/lib/einhorn/command.rb
CHANGED
@@ -152,6 +152,24 @@ module Einhorn
|
|
152
152
|
output
|
153
153
|
end
|
154
154
|
|
155
|
+
def self.set_workers(new)
|
156
|
+
if new == Einhorn::State.config[:number]
|
157
|
+
return ""
|
158
|
+
end
|
159
|
+
|
160
|
+
Einhorn::Event.break_loop
|
161
|
+
old = Einhorn::State.config[:number]
|
162
|
+
Einhorn::State.config[:number] = new
|
163
|
+
output = "Altering worker count, #{old} -> #{new}. Will "
|
164
|
+
if old < new
|
165
|
+
output << "spin up additional workers."
|
166
|
+
else
|
167
|
+
output << "gracefully terminate workers."
|
168
|
+
end
|
169
|
+
$stderr.puts(output)
|
170
|
+
output
|
171
|
+
end
|
172
|
+
|
155
173
|
def self.dumpable_state
|
156
174
|
global_state = Einhorn::State.state
|
157
175
|
descriptor_state = Einhorn::Event.persistent_descriptors.map do |descriptor|
|
@@ -220,8 +238,16 @@ module Einhorn
|
|
220
238
|
end
|
221
239
|
end
|
222
240
|
|
241
|
+
def self.next_index
|
242
|
+
all_indexes = Set.new(Einhorn::State.children.map { |k, st| st[:index] })
|
243
|
+
0.upto(all_indexes.length) do |i|
|
244
|
+
return i unless all_indexes.include?(i)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
223
248
|
def self.spinup(cmd=nil)
|
224
249
|
cmd ||= Einhorn::State.cmd
|
250
|
+
index = next_index
|
225
251
|
if Einhorn::TransientState.preloaded
|
226
252
|
pid = fork do
|
227
253
|
Einhorn::TransientState.whatami = :worker
|
@@ -234,7 +260,7 @@ module Einhorn
|
|
234
260
|
|
235
261
|
reseed_random
|
236
262
|
|
237
|
-
prepare_child_environment
|
263
|
+
prepare_child_environment(index)
|
238
264
|
einhorn_main
|
239
265
|
end
|
240
266
|
else
|
@@ -251,17 +277,18 @@ module Einhorn
|
|
251
277
|
# Note that Ruby 1.9's close_others option is useful here.
|
252
278
|
Einhorn::Event.close_all_for_worker
|
253
279
|
|
254
|
-
prepare_child_environment
|
280
|
+
prepare_child_environment(index)
|
255
281
|
Einhorn::Compat.exec(cmd[0], cmd[1..-1], :close_others => false)
|
256
282
|
end
|
257
283
|
end
|
258
284
|
|
259
|
-
Einhorn.log_info("===> Launched #{pid}", :upgrade)
|
285
|
+
Einhorn.log_info("===> Launched #{pid} (index: #{index})", :upgrade)
|
260
286
|
Einhorn::State.children[pid] = {
|
261
287
|
:type => :worker,
|
262
288
|
:version => Einhorn::State.version,
|
263
289
|
:acked => false,
|
264
|
-
:signaled => Set.new
|
290
|
+
:signaled => Set.new,
|
291
|
+
:index => index
|
265
292
|
}
|
266
293
|
Einhorn::State.last_spinup = Time.now
|
267
294
|
|
@@ -276,7 +303,7 @@ module Einhorn
|
|
276
303
|
end
|
277
304
|
end
|
278
305
|
|
279
|
-
def self.prepare_child_environment
|
306
|
+
def self.prepare_child_environment(index)
|
280
307
|
# This is run from the child
|
281
308
|
ENV['EINHORN_MASTER_PID'] = Process.ppid.to_s
|
282
309
|
ENV['EINHORN_SOCK_PATH'] = Einhorn::Command::Interface.socket_path
|
@@ -289,6 +316,8 @@ module Einhorn
|
|
289
316
|
ENV['EINHORN_FD_COUNT'] = Einhorn::State.bind_fds.length.to_s
|
290
317
|
Einhorn::State.bind_fds.each_with_index {|fd, i| ENV["EINHORN_FD_#{i}"] = fd.to_s}
|
291
318
|
|
319
|
+
ENV['EINHORN_CHILD_INDEX'] = index.to_s
|
320
|
+
|
292
321
|
# EINHORN_FDS is deprecated. It was originally an attempt to
|
293
322
|
# match Upstart's nominal internal support for space-separated
|
294
323
|
# FD lists, but nobody uses that in practice, and it makes
|
@@ -328,6 +328,21 @@ EOF
|
|
328
328
|
Einhorn::Command.decrement
|
329
329
|
end
|
330
330
|
|
331
|
+
command 'set_workers', 'Set the number of Einhorn child processes' do |conn, request|
|
332
|
+
args = request['args']
|
333
|
+
if message = validate_args(args)
|
334
|
+
next message
|
335
|
+
end
|
336
|
+
|
337
|
+
count = args[0].to_i
|
338
|
+
if count < 1 || count > 100
|
339
|
+
# sancheck. 100 is kinda arbitrary.
|
340
|
+
next "Invalid count: '#{args[0]}'. Must be an integer in [1,100)."
|
341
|
+
end
|
342
|
+
|
343
|
+
Einhorn::Command.set_workers(count)
|
344
|
+
end
|
345
|
+
|
331
346
|
command 'quieter', 'Decrease verbosity' do
|
332
347
|
Einhorn::Command.quieter
|
333
348
|
end
|
data/lib/einhorn/version.rb
CHANGED
data/lib/einhorn/worker.rb
CHANGED
@@ -33,6 +33,23 @@ module Einhorn
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
# Returns the index of this Einhorn child process.
|
37
|
+
#
|
38
|
+
# If an Einhorn master has N children, this will be an integer in
|
39
|
+
# the range [0,N), and no two workers running concurrently will
|
40
|
+
# ever have the same index.
|
41
|
+
#
|
42
|
+
# Returns nil if not running in Einhorn, or running on a version
|
43
|
+
# of Einhorn that does not support indexing children.
|
44
|
+
def self.einhorn_child_index
|
45
|
+
index = ENV['EINHORN_CHILD_INDEX']
|
46
|
+
if index.nil? || index !~ /\A \d+ \z/x
|
47
|
+
index
|
48
|
+
else
|
49
|
+
index.to_i
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
36
53
|
# Call this once your app is up and running in a good state.
|
37
54
|
# Arguments:
|
38
55
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: einhorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-04-
|
12
|
+
date: 2014-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -164,21 +164,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
164
|
- - ! '>='
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
-
segments:
|
168
|
-
- 0
|
169
|
-
hash: -2873954184645788574
|
170
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
168
|
none: false
|
172
169
|
requirements:
|
173
170
|
- - ! '>='
|
174
171
|
- !ruby/object:Gem::Version
|
175
172
|
version: '0'
|
176
|
-
segments:
|
177
|
-
- 0
|
178
|
-
hash: -2873954184645788574
|
179
173
|
requirements: []
|
180
174
|
rubyforge_project:
|
181
|
-
rubygems_version: 1.8.23
|
175
|
+
rubygems_version: 1.8.23.2
|
182
176
|
signing_key:
|
183
177
|
specification_version: 3
|
184
178
|
summary: ! 'Einhorn: the language-independent shared socket manager'
|
@@ -190,3 +184,4 @@ test_files:
|
|
190
184
|
- test/unit/einhorn/command/interface.rb
|
191
185
|
- test/unit/einhorn/event.rb
|
192
186
|
- test/unit/einhorn/worker_pool.rb
|
187
|
+
has_rdoc:
|