haproxy-cluster 0.0.6 → 0.0.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/lib/haproxy_cluster.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'haproxy_cluster/member'
|
2
2
|
require 'timeout'
|
3
|
+
require 'logger'
|
3
4
|
require 'thread'
|
4
5
|
|
5
6
|
class HAProxyCluster
|
@@ -7,18 +8,25 @@ class HAProxyCluster
|
|
7
8
|
Inf = +1.0/0.0
|
8
9
|
NegInf = -1.0/0.0
|
9
10
|
|
10
|
-
def initialize(members = [])
|
11
|
+
def initialize(members = [], log_level = Logger::INFO)
|
11
12
|
@members = []
|
13
|
+
@log = Logger.new(STDOUT)
|
14
|
+
pp log_level
|
15
|
+
log.level = log_level
|
16
|
+
original_formatter = Logger::Formatter.new
|
17
|
+
@log.formatter = proc { |severity,datetime,progname,msg|
|
18
|
+
original_formatter.call(severity,datetime,self.class.to_s,msg)
|
19
|
+
}
|
12
20
|
threads = []
|
13
21
|
members.each do |url|
|
14
22
|
threads << Thread.new do
|
15
|
-
@members << HAProxyCluster::Member.new(url)
|
23
|
+
@members << HAProxyCluster::Member.new(url,@log)
|
16
24
|
end
|
17
25
|
end
|
18
26
|
threads.each{|t|t.join}
|
19
27
|
end
|
20
28
|
|
21
|
-
attr_accessor :members
|
29
|
+
attr_accessor :members, :log
|
22
30
|
|
23
31
|
# Poll the cluster, executing the given block with fresh data at the
|
24
32
|
# prescribed interval.
|
@@ -57,7 +65,7 @@ class HAProxyCluster
|
|
57
65
|
# * :condition, anything accepted by `check_condition`
|
58
66
|
# * :interval, check interval (default 2 seconds, same as HA Proxy)
|
59
67
|
# * :timeout, give up after this number of seconds
|
60
|
-
# * :min_checks, require :condition
|
68
|
+
# * :min_checks, require :condition consecutive positive results
|
61
69
|
#
|
62
70
|
def wait_until (options = {}, &code)
|
63
71
|
opts = {
|
@@ -73,7 +81,10 @@ class HAProxyCluster
|
|
73
81
|
|
74
82
|
# Break out as soon as we reach :min_checks in a row
|
75
83
|
history << check_condition(opts[:condition], results.values.flatten)
|
76
|
-
|
84
|
+
if history.last(opts[:min_checks]) == [true] * opts[:min_checks]
|
85
|
+
log.info { "Ok, we've seen #{opts[:min_checks]} consecutive successful results." }
|
86
|
+
return true
|
87
|
+
end
|
77
88
|
|
78
89
|
sleep opts[:interval]
|
79
90
|
each_member { poll! }
|
@@ -19,12 +19,12 @@ class HAProxyCluster
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def rolling_restartable? (enough = 80)
|
22
|
-
up_servers = @servers.map{ |name,server|
|
22
|
+
up_servers = @servers.map{ |name,server| server.ok? }.count
|
23
23
|
if up_servers == 0
|
24
24
|
@member.log.warn { "All servers are down; can't hurt!" }
|
25
25
|
return true
|
26
26
|
elsif Rational(up_servers,@servers.count) >= Rational(enough,100)
|
27
|
-
@member.log.
|
27
|
+
@member.log.debug { "#{up_servers}/#{@servers.count} is at least #{enough}%!" }
|
28
28
|
return true
|
29
29
|
else
|
30
30
|
@member.log.warn { "Insufficient capacity to handle a rolling restart at this time." }
|
data/lib/haproxy_cluster/cli.rb
CHANGED
@@ -10,14 +10,18 @@ require 'haproxy_cluster'
|
|
10
10
|
Signal.trap("INT"){exit 1}
|
11
11
|
|
12
12
|
options = OpenStruct.new
|
13
|
+
options.log_level = Logger::INFO
|
13
14
|
OptionParser.new do |opts|
|
14
15
|
opts.banner = "Usage: #{File.basename $0} ARGS URL [URL] [...]"
|
15
16
|
opts.on("-e", "--eval=CODE", "Ruby code block to be evaluated") do |o|
|
16
17
|
options.code_string = o
|
17
18
|
end
|
18
19
|
opts.on("-v", "--verbose", "Verbose logging") do
|
19
|
-
# TODO Need better coverage here
|
20
20
|
RestClient.log = STDERR
|
21
|
+
options.log_level = Logger::DEBUG
|
22
|
+
end
|
23
|
+
opts.on("-q", "--quiet", "Only report problems") do
|
24
|
+
options.log_level = Logger::WARN
|
21
25
|
end
|
22
26
|
opts.on("--csv", "Assume result will be an Array of Arrays and emit as CSV") do
|
23
27
|
options.csv = true
|
@@ -37,10 +41,10 @@ if options.code_string
|
|
37
41
|
|
38
42
|
if options.timeout
|
39
43
|
result = Timeout::timeout(options.timeout) do
|
40
|
-
Kernel.eval( options.code_string, HAProxyCluster.new(options.urls).instance_eval("binding") )
|
44
|
+
Kernel.eval( options.code_string, HAProxyCluster.new(options.urls, options.log_level).instance_eval("binding") )
|
41
45
|
end
|
42
46
|
else
|
43
|
-
result = Kernel.eval( options.code_string, HAProxyCluster.new(options.urls).instance_eval("binding") )
|
47
|
+
result = Kernel.eval( options.code_string, HAProxyCluster.new(options.urls, options.log_level).instance_eval("binding") )
|
44
48
|
end
|
45
49
|
|
46
50
|
case result.class.to_s
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'csv'
|
2
|
-
require 'logger'
|
3
2
|
require 'rest-client'
|
4
3
|
require 'haproxy_cluster/backend'
|
5
4
|
require 'haproxy_cluster/server'
|
@@ -7,13 +6,9 @@ require 'haproxy_cluster/server'
|
|
7
6
|
class HAProxyCluster
|
8
7
|
class Member
|
9
8
|
|
10
|
-
def initialize(source)
|
9
|
+
def initialize(source,log)
|
11
10
|
@source = source
|
12
|
-
@log =
|
13
|
-
original_formatter = Logger::Formatter.new
|
14
|
-
@log.formatter = proc { |severity,datetime,progname,msg|
|
15
|
-
original_formatter.call(severity,datetime,"HAProxyCluster",msg)
|
16
|
-
}
|
11
|
+
@log = log
|
17
12
|
@backends = Hash.new { |h,k| h[k] = Backend.new({},self) }
|
18
13
|
if source =~ /https?:/
|
19
14
|
@type = :url
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haproxy-cluster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-08-15 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
16
|
-
requirement: &
|
16
|
+
requirement: &70281269238780 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70281269238780
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: test-unit
|
27
|
-
requirement: &
|
27
|
+
requirement: &70281269236340 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70281269236340
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: webmock
|
38
|
-
requirement: &
|
38
|
+
requirement: &70281269233120 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70281269233120
|
47
47
|
description: ! " Gem and command line tool for quickly answering questions like,
|
48
48
|
\"Can we\n survive a rolling restart?\", \"How many transactions per second am
|
49
49
|
I seeing?\",\n \"What's my session backlog?\". Intended for use within continuous
|