einhorn 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/CONTRIBUTORS ADDED
@@ -0,0 +1,6 @@
1
+ Greg Brockman <gdb@stripe.com>
2
+ Evan Broder <evan@stripe.com>
3
+ Nelson Elhage <nelhage@stripe.com>
4
+ Paul Hammond <paul@paulhammond.org>
5
+ Conrad Irwin <conrad.irwin@gmail.com>
6
+ Max Wang <max@stripe.com>
data/Gemfile CHANGED
@@ -1,4 +1,8 @@
1
- source 'https://rubygems.org'
1
+ # Execute bundler hook if present
2
+ ['~/.', '/etc/'].any? do |file|
3
+ File.lstat(path = File.expand_path(file + 'bundle-gemfile-hook')) rescue next
4
+ eval(File.read(path), binding, path); break true
5
+ end || source('https://rubygems.org/')
2
6
 
3
7
  # Specify your gem's dependencies in einhorn.gemspec
4
8
  gemspec
data/Rakefile CHANGED
@@ -20,3 +20,15 @@ end
20
20
 
21
21
  task :default => :test do
22
22
  end
23
+ require 'bundler/setup'
24
+ require 'chalk-rake/gem_tasks'
25
+ require 'rake/testtask'
26
+
27
+ Rake::TestTask.new do |t|
28
+ t.libs = ['lib']
29
+ # t.warning = true
30
+ t.verbose = true
31
+ t.test_files = FileList['test/**/*.rb'].reject do |file|
32
+ file.end_with?('_lib.rb') || file.include?('/_lib/')
33
+ end
34
+ end
data/bin/einhornsh CHANGED
@@ -11,6 +11,9 @@ require 'einhorn'
11
11
  module Einhorn
12
12
  class EinhornSH
13
13
 
14
+ class EinhornSHExit < StandardError
15
+ end
16
+
14
17
  def initialize(path_to_socket)
15
18
  @path_to_socket = path_to_socket
16
19
  @request_id = 0
@@ -42,15 +45,28 @@ module Einhorn
42
45
  emit
43
46
  emit('Type "quit" or "exit" to quit at any time')
44
47
 
45
- while line = Readline.readline('> ', true)
46
- command, args = parse_command(line)
47
- if ['quit', 'exit'].include?(command)
48
- emit("Goodbye!")
49
- return
50
- end
51
- send_command({'id' => request_id, 'command' => command, 'args' => args}) do |message|
52
- puts message
53
- end
48
+ while command_line_sequence = Readline.readline('> ', true)
49
+ run_command_line_sequence(command_line_sequence)
50
+ end
51
+ end
52
+
53
+ def run_command_line_sequence(command_line_sequence)
54
+ command_lines = command_line_sequence.split(";")
55
+ command_lines.each do |command_line|
56
+ run_command_line(command_line)
57
+ end
58
+ end
59
+
60
+ def run_command_line(command_line)
61
+ command, args = parse_command_line(command_line)
62
+ if command.nil?
63
+ return
64
+ elsif ['quit', 'exit'].include?(command)
65
+ emit("Goodbye!")
66
+ raise EinhornSHExit
67
+ end
68
+ send_command({'id' => request_id, 'command' => command, 'args' => args}) do |message|
69
+ puts message
54
70
  end
55
71
  end
56
72
 
@@ -58,8 +74,8 @@ module Einhorn
58
74
  @request_id += 1
59
75
  end
60
76
 
61
- def parse_command(line)
62
- command, *args = Shellwords.shellsplit(line)
77
+ def parse_command_line(command_line)
78
+ command, *args = Shellwords.shellsplit(command_line)
63
79
  [command, args]
64
80
  end
65
81
 
@@ -128,6 +144,11 @@ with a `-d`, provide the same argument here."
128
144
  opts.on('-d PATH', '--socket-path PATH', 'Path to the Einhorn command socket') do |path|
129
145
  options[:socket_path] = path
130
146
  end
147
+
148
+ opts.on('-e CMD_LINE_SEQ', '--execute CMD_LINE_SEQ', 'Execute this command outside of interactive mode') do |cmd_line_seq|
149
+ options[:cmd_line_seq] = cmd_line_seq
150
+ end
151
+
131
152
  end
132
153
  optparse.parse!
133
154
 
@@ -148,8 +169,16 @@ with a `-d`, provide the same argument here."
148
169
  path_to_socket = Einhorn::Command::Interface.default_socket_path(cmd_name)
149
170
  end
150
171
 
151
- sh = Einhorn::EinhornSH.new(path_to_socket)
152
- sh.run
172
+ sh = Einhorn::EinhornSH.new(path_to_socket)
173
+
174
+ cmd_line_seq = options[:cmd_line_seq]
175
+
176
+ begin
177
+ cmd_line_seq ? sh.run_command_line_sequence(cmd_line_seq) : sh.run
178
+ rescue Einhorn::EinhornSH::EinhornSHExit => e
179
+ return 0
180
+ end
181
+
153
182
  return 0
154
183
  end
155
184
 
data/einhorn.gemspec CHANGED
@@ -2,18 +2,22 @@
2
2
  require File.expand_path('../lib/einhorn/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["Greg Brockman"]
6
- gem.email = ["gdb@stripe.com"]
7
- gem.summary = "Einhorn: the language-independent shared socket manager"
8
- gem.description = "Einhorn makes it easy to run multiple instances of an application server, all listening on the same port. You can also seamlessly restart your workers without dropping any requests. Einhorn requires minimal application-level support, making it easy to use with an existing project."
9
- gem.homepage = "https://github.com/stripe/einhorn"
10
- gem.license = "MIT"
5
+ gem.authors = ['Greg Brockman']
6
+ gem.email = ['gdb@stripe.com']
7
+ gem.summary = 'Einhorn: the language-independent shared socket manager'
8
+ gem.description = 'Einhorn makes it easy to run multiple instances of an application server, all listening on the same port. You can also seamlessly restart your workers without dropping any requests. Einhorn requires minimal application-level support, making it easy to use with an existing project.'
9
+ gem.homepage = 'https://github.com/stripe/einhorn'
10
+ gem.license = 'MIT'
11
11
 
12
12
  gem.files = `git ls-files`.split($\)
13
13
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
14
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
- gem.name = "einhorn"
16
- gem.require_paths = ["lib"]
15
+ gem.name = 'einhorn'
16
+ gem.require_paths = ['lib']
17
+ gem.add_development_dependency 'rake'
18
+ gem.add_development_dependency 'minitest'
19
+ gem.add_development_dependency 'mocha'
20
+ gem.add_development_dependency 'chalk-rake'
17
21
 
18
22
  gem.add_development_dependency('rake')
19
23
  gem.add_development_dependency('minitest', '< 5.0')
@@ -319,6 +319,7 @@ module Einhorn
319
319
 
320
320
  def self.cull
321
321
  acked = Einhorn::WorkerPool.ack_count
322
+ unsignaled = Einhorn::WorkerPool.unsignaled_count
322
323
  target = Einhorn::WorkerPool.ack_target
323
324
 
324
325
  if Einhorn::State.upgrading && acked >= target
@@ -333,8 +334,8 @@ module Einhorn
333
334
  signal_all("USR2", old_workers)
334
335
  end
335
336
 
336
- if acked > target
337
- excess = Einhorn::WorkerPool.acked_unsignaled_modern_workers[0...(acked-target)]
337
+ if unsignaled > target
338
+ excess = Einhorn::WorkerPool.unsignaled_modern_workers_with_priority[0...(unsignaled-target)]
338
339
  Einhorn.log_info("Have too many workers at the current version, so killing off #{excess.length} of them.")
339
340
  signal_all("USR2", excess)
340
341
  end
@@ -1,3 +1,3 @@
1
1
  module Einhorn
2
- VERSION = '0.5.0'
2
+ VERSION = '0.5.1'
3
3
  end
@@ -34,12 +34,24 @@ module Einhorn
34
34
  acked_modern_workers_with_state.map {|pid, _| pid}
35
35
  end
36
36
 
37
+ def self.unsignaled_modern_workers_with_state
38
+ modern_workers_with_state.select do |_, spec|
39
+ spec[:signaled].length == 0
40
+ end
41
+ end
42
+
37
43
  def self.acked_unsignaled_modern_workers
38
44
  acked_modern_workers_with_state.select do |_, spec|
39
45
  spec[:signaled].length == 0
40
46
  end.map {|pid, _| pid}
41
47
  end
42
48
 
49
+ def self.unsignaled_modern_workers_with_priority
50
+ unsignaled_modern_workers_with_state.sort_by do |pid, spec|
51
+ spec[:acked] ? 1 : 0
52
+ end.map {|pid, _| pid}
53
+ end
54
+
43
55
  # Use the number of modern workers, rather than unsignaled modern
44
56
  # workers. This means if e.g. we do bunch of decs and then incs,
45
57
  # any workers which haven't died yet will count towards our number
@@ -59,6 +71,10 @@ module Einhorn
59
71
  Einhorn::State.config[:number]
60
72
  end
61
73
 
74
+ def self.unsignaled_count
75
+ unsignaled_modern_workers_with_state.length
76
+ end
77
+
62
78
  def self.old_workers
63
79
  unsignaled_workers - modern_workers
64
80
  end
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.0
4
+ version: 0.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,72 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-26 00:00:00.000000000 Z
12
+ date: 2013-10-16 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: minitest
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: mocha
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: chalk-rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
14
78
  - !ruby/object:Gem::Dependency
15
79
  name: rake
16
80
  requirement: !ruby/object:Gem::Requirement
@@ -73,6 +137,7 @@ extra_rdoc_files: []
73
137
  files:
74
138
  - .gitignore
75
139
  - .travis.yml
140
+ - CONTRIBUTORS
76
141
  - Gemfile
77
142
  - History.txt
78
143
  - LICENSE
@@ -132,7 +197,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
197
  version: '0'
133
198
  segments:
134
199
  - 0
135
- hash: 3689317997291483105
200
+ hash: -4058700174817085581
136
201
  required_rubygems_version: !ruby/object:Gem::Requirement
137
202
  none: false
138
203
  requirements:
@@ -141,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
206
  version: '0'
142
207
  segments:
143
208
  - 0
144
- hash: 3689317997291483105
209
+ hash: -4058700174817085581
145
210
  requirements: []
146
211
  rubyforge_project:
147
212
  rubygems_version: 1.8.23