|
74 | 74 | client.subscribe(Mongo::Monitoring::CONNECTION_POOL, subscriber) |
75 | 75 | end |
76 | 76 |
|
77 | | - it "retries on PoolClearedError" do |
78 | | - # After the first find fails, the pool is paused and retry is triggered. |
79 | | - # Now, a race is started between the second find acquiring a connection, |
80 | | - # and the first retrying the read. Now, retry reads cause the cluster to |
81 | | - # be rescanned and the pool to be unpaused, allowing the second checkout |
82 | | - # to succeed (when it should fail). Therefore we want the second find's |
83 | | - # check out to win the race. This gives the check out a little head start. |
84 | | - allow_any_instance_of(Mongo::Server::ConnectionPool).to receive(:ready).and_wrap_original do |m, *args, &block| |
85 | | - ::Utils.wait_for_condition(5) do |
86 | | - # check_out_results should contain: |
87 | | - # - find1 connection check out successful |
88 | | - # - pool cleared |
89 | | - # - find2 connection check out failed |
90 | | - # We wait here for the third event to happen before we ready the pool. |
91 | | - cmap_events.select do |e| |
92 | | - event_types.include?(e.class) |
93 | | - end.length >= 3 |
| 77 | + shared_examples_for 'retries on PoolClearedError' do |
| 78 | + it "retries on PoolClearedError" do |
| 79 | + # After the first find fails, the pool is paused and retry is triggered. |
| 80 | + # Now, a race is started between the second find acquiring a connection, |
| 81 | + # and the first retrying the read. Now, retry reads cause the cluster to |
| 82 | + # be rescanned and the pool to be unpaused, allowing the second checkout |
| 83 | + # to succeed (when it should fail). Therefore we want the second find's |
| 84 | + # check out to win the race. This gives the check out a little head start. |
| 85 | + allow_any_instance_of(Mongo::Server::ConnectionPool).to receive(:ready).and_wrap_original do |m, *args, &block| |
| 86 | + ::Utils.wait_for_condition(5) do |
| 87 | + # check_out_results should contain: |
| 88 | + # - find1 connection check out successful |
| 89 | + # - pool cleared |
| 90 | + # - find2 connection check out failed |
| 91 | + # We wait here for the third event to happen before we ready the pool. |
| 92 | + cmap_events.select do |e| |
| 93 | + event_types.include?(e.class) |
| 94 | + end.length >= 3 |
| 95 | + end |
| 96 | + m.call(*args, &block) |
94 | 97 | end |
95 | | - m.call(*args, &block) |
| 98 | + threads.map(&:join) |
| 99 | + expect(check_out_results[0]).to be_a(Mongo::Monitoring::Event::Cmap::ConnectionCheckedOut) |
| 100 | + expect(check_out_results[1]).to be_a(Mongo::Monitoring::Event::Cmap::PoolCleared) |
| 101 | + expect(check_out_results[2]).to be_a(Mongo::Monitoring::Event::Cmap::ConnectionCheckOutFailed) |
| 102 | + expect(find_events.length).to eq(3) |
96 | 103 | end |
97 | | - threads.map(&:join) |
98 | | - expect(check_out_results[0]).to be_a(Mongo::Monitoring::Event::Cmap::ConnectionCheckedOut) |
99 | | - expect(check_out_results[1]).to be_a(Mongo::Monitoring::Event::Cmap::PoolCleared) |
100 | | - expect(check_out_results[2]).to be_a(Mongo::Monitoring::Event::Cmap::ConnectionCheckOutFailed) |
101 | | - expect(find_events.length).to eq(3) |
| 104 | + end |
| 105 | + |
| 106 | + it_behaves_like 'retries on PoolClearedError' |
| 107 | + |
| 108 | + context 'legacy read retries' do |
| 109 | + |
| 110 | + let(:client) { authorized_client.with(options.merge(retry_reads: false, max_read_retries: 1)) } |
| 111 | + |
| 112 | + it_behaves_like 'retries on PoolClearedError' |
102 | 113 | end |
103 | 114 |
|
104 | 115 | after do |
|
0 commit comments