genghis 1.0 → 1.0.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.
- data/README.rdoc +125 -0
- metadata +4 -3
- data/README +0 -0
data/README.rdoc
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
= Genghis - a MongoDB configuration and resilience
|
2
|
+
|
3
|
+
== What is Genghis?
|
4
|
+
* A configuration framework for mongoDB
|
5
|
+
* A resilience framework when using MongoDB in replica pairs
|
6
|
+
|
7
|
+
== Getting started
|
8
|
+
|
9
|
+
=== Configuration
|
10
|
+
|
11
|
+
|
12
|
+
When invoked from rails, Genghis looks for a file called mongodb.yml in the RAILS_ROOT/config directory.
|
13
|
+
the format of this file closely mimics that of the database.yml file you know well.
|
14
|
+
|
15
|
+
development:
|
16
|
+
servers: localhost:27017
|
17
|
+
databases:
|
18
|
+
paperclip : 'paperclip_files'
|
19
|
+
mongo_mapper : 'mongo_mapper'
|
20
|
+
connection_options:
|
21
|
+
pool_size: 7
|
22
|
+
timeout: 2
|
23
|
+
|
24
|
+
In this case, we have a single mongodb server at localhost:2701. The database defines an alias for each
|
25
|
+
actual mongo database in your mongodb server. You can then look up the databases by the alias later.
|
26
|
+
The connection_options hash is passed directly to the mongo connection constructor.
|
27
|
+
|
28
|
+
=== Paired configuration
|
29
|
+
|
30
|
+
|
31
|
+
If you are using replica pairs, the configuration varies somewhat.
|
32
|
+
|
33
|
+
development:
|
34
|
+
servers:
|
35
|
+
left: left_host:27017
|
36
|
+
right: right_host:27017
|
37
|
+
databases:
|
38
|
+
paperclip : 'paperclip_files'
|
39
|
+
...
|
40
|
+
connection_options:
|
41
|
+
max_retries: 7
|
42
|
+
pool_size: 5
|
43
|
+
...
|
44
|
+
|
45
|
+
The left and right servers are specified in a hash, and most importantly for resilience the max_retries
|
46
|
+
entry is specified in connection options. This specifies how many times Genghis will try to establish
|
47
|
+
a connection to one of the servers if it detects a connection error.
|
48
|
+
|
49
|
+
=== Initialization
|
50
|
+
|
51
|
+
|
52
|
+
In rails, it's extremely simple to set up Genghis, simply include the gem and then require it.
|
53
|
+
Then set it up in environmnet.rb
|
54
|
+
|
55
|
+
Genghis.environment = RAILS_ENV
|
56
|
+
|
57
|
+
Genghis manages connections so you don't have to. They are available through Genghis, so you can do
|
58
|
+
the following:
|
59
|
+
|
60
|
+
MongoMapper.connection = Genghis.connection
|
61
|
+
|
62
|
+
|
63
|
+
Database names can then be used to configure mongo mapper or any other frameworks you have
|
64
|
+
|
65
|
+
MongoMapper.database = Genghis.databases['mongo_mapper']
|
66
|
+
|
67
|
+
|
68
|
+
== Resilience
|
69
|
+
|
70
|
+
|
71
|
+
While MongoDB provides impressive levels of stability and failover, its driver design leaves failover
|
72
|
+
up to the implementor. This leaves your application subject to connection exceptions that can happen
|
73
|
+
at any time, possibly littering your code with ugly and difficult to maintain reconnect logic.
|
74
|
+
Genghis's resilience framework solves this for you.
|
75
|
+
|
76
|
+
=== Setup
|
77
|
+
|
78
|
+
|
79
|
+
To make an object resilient, you must first have a replica pair of MongoDB servers. After you have
|
80
|
+
that set up, you're ready to make your objects robust.
|
81
|
+
|
82
|
+
The following examples will assume you have a mongo_mapper object with the following definition:
|
83
|
+
|
84
|
+
class Foo < MongoMapper::Document
|
85
|
+
key :bar, String
|
86
|
+
key :baz, Integer
|
87
|
+
end
|
88
|
+
|
89
|
+
First you must re-define your old object so that the application can't see it under the original name.
|
90
|
+
I find the namespace Unsafe communicates my intention pretty well:
|
91
|
+
|
92
|
+
module Unsafe
|
93
|
+
class Foo < MongoMapper::Document
|
94
|
+
key :bar, String
|
95
|
+
key :baz, Integer
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
Then you need to need to enlist Genghis's guardian class, which is a protective object proxy.
|
100
|
+
module Unsafe
|
101
|
+
class Foo < MongoMapper::Document
|
102
|
+
key :bar, String
|
103
|
+
key :baz, Integer
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Foo < Genghis::Guardian
|
108
|
+
protects Unsafe::Foo
|
109
|
+
end
|
110
|
+
|
111
|
+
That's it. You are now free to use the Foo class as you did before but now it has Genghis's guardian
|
112
|
+
watching over its shoulder, protecting you from any connection related problems.
|
113
|
+
|
114
|
+
|
115
|
+
=== What happens on error
|
116
|
+
|
117
|
+
|
118
|
+
Let's say that while you are executing an update and a connection error occurs. Genghis's guardian
|
119
|
+
realizes something has gone wrong and invalidates the current connection. It then tries to make a
|
120
|
+
new connection to the other server in the replica pair. If that succeeds, it then re-tries the code
|
121
|
+
that was executing when the failure occurs. It then keeps using this connection.
|
122
|
+
|
123
|
+
If the second connection fails, it then reverts to the first server in the list. Genghis will flit
|
124
|
+
back and forth between the two servers until it reaches the max_retries threshold, at which point
|
125
|
+
it will raise an application level exception (the same type that was originally thrown).
|
metadata
CHANGED
@@ -5,7 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
9
10
|
platform: ruby
|
10
11
|
authors:
|
11
12
|
- Steve Cohen
|
@@ -36,10 +37,10 @@ executables: []
|
|
36
37
|
extensions: []
|
37
38
|
|
38
39
|
extra_rdoc_files:
|
39
|
-
- README
|
40
|
+
- README.rdoc
|
40
41
|
files:
|
41
42
|
- lib/genghis.rb
|
42
|
-
- README
|
43
|
+
- README.rdoc
|
43
44
|
has_rdoc: true
|
44
45
|
homepage: http://github.com/scohen/genghis
|
45
46
|
licenses: []
|
data/README
DELETED
File without changes
|