genghis 1.2 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +12 -8
- data/lib/genghis.rb +22 -21
- metadata +3 -2
data/README.rdoc
CHANGED
@@ -44,9 +44,13 @@ If you are using replica sets, the configuration varies somewhat.
|
|
44
44
|
password: secretpassword
|
45
45
|
...
|
46
46
|
connection_options:
|
47
|
-
max_retries: 7
|
48
47
|
pool_size: 5
|
48
|
+
slave_ok: true
|
49
49
|
...
|
50
|
+
resilience_options:
|
51
|
+
max_retries: 7
|
52
|
+
sleep_between_retries: 0.5
|
53
|
+
|
50
54
|
|
51
55
|
The servers are specified in an array, and most importantly for resilience the max_retries
|
52
56
|
entry is specified in connection options. This specifies how many times Genghis will try to establish
|
@@ -81,7 +85,7 @@ Similarly you can retrieve the actual mongo database
|
|
81
85
|
== Resilience
|
82
86
|
|
83
87
|
|
84
|
-
While MongoDB provides impressive levels of stability and failover, its driver design leaves failover
|
88
|
+
While MongoDB provides impressive levels of stability and failover, its driver design leaves handling failover
|
85
89
|
up to the implementer. This leaves your application subject to connection exceptions that can happen
|
86
90
|
at any time, possibly littering your code with ugly and difficult to maintain reconnect logic.
|
87
91
|
Genghis's resilience framework solves this for you.
|
@@ -129,10 +133,10 @@ watching over its shoulder, protecting you from any connection related problems.
|
|
129
133
|
|
130
134
|
|
131
135
|
Let's say that while you are executing an update and a connection error occurs. Genghis's guardian
|
132
|
-
realizes something has gone wrong and invalidates the current connection. It then
|
133
|
-
new connection to the other server in the replica set. If that succeeds,
|
134
|
-
that was executing when the failure occurs. It then keeps using this connection.
|
136
|
+
realizes something has gone wrong and invalidates the current connection. It then waits sleep_between_retries
|
137
|
+
seconds and then tries to make a new connection to the other server in the replica set. If that succeeds,
|
138
|
+
it then re-tries the code that was executing when the failure occurs. It then keeps using this connection.
|
135
139
|
|
136
|
-
If the second connection fails, it then
|
137
|
-
|
138
|
-
it will raise
|
140
|
+
If the second connection fails, it then continues to the next server in the list. Genghis will cycle
|
141
|
+
between the servers until it reaches the max_retries threshold, at which point
|
142
|
+
it will raise a Mongo::ConnectionFailure exception (the same type that was originally thrown).
|
data/lib/genghis.rb
CHANGED
@@ -26,6 +26,10 @@ class Genghis
|
|
26
26
|
self.hosts = parse_mongo_urls([v])
|
27
27
|
elsif k == 'replica_set'
|
28
28
|
self.hosts = parse_mongo_urls(v)
|
29
|
+
elsif k == 'resilience_options'
|
30
|
+
v.each_pair do |opt, setting|
|
31
|
+
self.send("#{opt}=".to_sym, setting)
|
32
|
+
end
|
29
33
|
else
|
30
34
|
self.class.instance_eval do
|
31
35
|
v = HashWithConsistentAccess.new(v) if v.is_a?(::Hash)
|
@@ -57,12 +61,26 @@ class Genghis
|
|
57
61
|
@connection = safe_create_connection
|
58
62
|
end
|
59
63
|
|
64
|
+
def self.max_retries=(num)
|
65
|
+
@@retries = num
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.max_retries
|
69
|
+
@@retries ||= 5
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.sleep_between_retries=(num)
|
73
|
+
@@sleep_time = num
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.sleep_between_retries
|
77
|
+
@@sleep_time || 1
|
78
|
+
end
|
79
|
+
|
60
80
|
private
|
61
81
|
|
62
82
|
def self.parse_connection_options
|
63
83
|
@@connection_options ||= symbolize_keys(default_connection_options.merge(@@config['connection_options']))
|
64
|
-
@@retries ||= @@connection_options.delete(:max_retries)
|
65
|
-
@@connection_options
|
66
84
|
end
|
67
85
|
|
68
86
|
def self.parse_mongo_urls(urls)
|
@@ -85,30 +103,13 @@ class Genghis
|
|
85
103
|
end
|
86
104
|
end
|
87
105
|
|
88
|
-
def self.max_retries=(num)
|
89
|
-
@@retries = num
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.max_retries
|
93
|
-
connection_options
|
94
|
-
@@retries ||= 5
|
95
|
-
end
|
96
|
-
|
97
|
-
def self.sleep_time=(num)
|
98
|
-
@@sleep_time = num
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.sleep_time
|
102
|
-
@@sleep_time || 1
|
103
|
-
end
|
104
106
|
|
105
107
|
def self.connection_options
|
106
108
|
@@connection_options ||= parse_connection_options
|
107
109
|
end
|
108
110
|
|
109
111
|
def self.default_connection_options
|
110
|
-
{:
|
111
|
-
:pool_size => 5,
|
112
|
+
{ :pool_size => 5,
|
112
113
|
:timeout => 5,
|
113
114
|
:slave_ok => false
|
114
115
|
}
|
@@ -208,7 +209,7 @@ class Genghis
|
|
208
209
|
retries += 1
|
209
210
|
raise ex if retries > max_retries
|
210
211
|
fix_broken_connection
|
211
|
-
sleep(Genghis.
|
212
|
+
sleep(Genghis.sleep_between_retries)
|
212
213
|
end
|
213
214
|
end
|
214
215
|
rv
|
metadata
CHANGED