@@ -14,6 +14,14 @@ def initialize(operation, cluster)
14
14
@cluster = cluster
15
15
end
16
16
17
+ def max_read_retries
18
+ cluster . max_read_retries
19
+ end
20
+
21
+ def read_retry_interval
22
+ cluster . read_retry_interval
23
+ end
24
+
17
25
def read
18
26
read_with_retry do
19
27
operation . execute
@@ -81,14 +89,80 @@ def write
81
89
82
90
context 'when an operation failure occurs' do
83
91
84
- before do
85
- expect ( operation ) . to receive ( :execute ) . and_raise ( Mongo ::Error ::OperationFailure ) . ordered
92
+ context 'when the cluster is not a mongos' do
93
+
94
+ before do
95
+ expect ( operation ) . to receive ( :execute ) . and_raise ( Mongo ::Error ::OperationFailure ) . ordered
96
+ expect ( cluster ) . to receive ( :sharded? ) . and_return ( false )
97
+ end
98
+
99
+ it 'raises an exception' do
100
+ expect {
101
+ retryable . read
102
+ } . to raise_error ( Mongo ::Error ::OperationFailure )
103
+ end
86
104
end
87
105
88
- it 'raises an exception' do
89
- expect {
90
- retryable . read
91
- } . to raise_error ( Mongo ::Error ::OperationFailure )
106
+ context 'when the cluster is a mongos' do
107
+
108
+ context 'when the operation failure is not retryable' do
109
+
110
+ let ( :error ) do
111
+ Mongo ::Error ::OperationFailure . new ( 'not authorized' )
112
+ end
113
+
114
+ before do
115
+ expect ( operation ) . to receive ( :execute ) . and_raise ( error ) . ordered
116
+ expect ( cluster ) . to receive ( :sharded? ) . and_return ( true )
117
+ end
118
+
119
+ it 'raises the exception' do
120
+ expect {
121
+ retryable . read
122
+ } . to raise_error ( Mongo ::Error ::OperationFailure )
123
+ end
124
+ end
125
+
126
+ context 'when the operation failure is retryable' do
127
+
128
+ let ( :error ) do
129
+ Mongo ::Error ::OperationFailure . new ( 'no master' )
130
+ end
131
+
132
+ context 'when the retry succeeds' do
133
+
134
+ before do
135
+ expect ( operation ) . to receive ( :execute ) . and_raise ( error ) . ordered
136
+ expect ( cluster ) . to receive ( :sharded? ) . and_return ( true )
137
+ expect ( cluster ) . to receive ( :max_read_retries ) . and_return ( 1 ) . ordered
138
+ expect ( cluster ) . to receive ( :read_retry_interval ) . and_return ( 0.1 ) . ordered
139
+ expect ( operation ) . to receive ( :execute ) . and_return ( true ) . ordered
140
+ end
141
+
142
+ it 'returns the result' do
143
+ expect ( retryable . read ) . to be true
144
+ end
145
+ end
146
+
147
+ context 'when the retry fails once and then succeeds' do
148
+
149
+ before do
150
+ expect ( operation ) . to receive ( :execute ) . and_raise ( error ) . ordered
151
+ expect ( cluster ) . to receive ( :sharded? ) . and_return ( true )
152
+ expect ( cluster ) . to receive ( :max_read_retries ) . and_return ( 1 ) . ordered
153
+ expect ( cluster ) . to receive ( :read_retry_interval ) . and_return ( 0.1 ) . ordered
154
+ expect ( operation ) . to receive ( :execute ) . and_raise ( error ) . ordered
155
+ expect ( cluster ) . to receive ( :sharded? ) . and_return ( true )
156
+ expect ( cluster ) . to receive ( :max_read_retries ) . and_return ( 1 ) . ordered
157
+ expect ( cluster ) . to receive ( :read_retry_interval ) . and_return ( 0.1 ) . ordered
158
+ expect ( operation ) . to receive ( :execute ) . and_return ( true ) . ordered
159
+ end
160
+
161
+ it 'returns the result' do
162
+ expect ( retryable . read ) . to be true
163
+ end
164
+ end
165
+ end
92
166
end
93
167
end
94
168
end
0 commit comments