@@ -258,30 +258,36 @@ class AutoClusterFailoverImpl : public std::enable_shared_from_this<AutoClusterF
258258 onServiceInfoUpdate_ (current ());
259259 }
260260
261- void probeSecondaryFrom (size_t index, CompletionCallback done ) {
261+ void probeSecondaryFrom (size_t index, const ServiceInfo* excludedServiceInfo, ProbeCallback callback ) {
262262 if (index >= config_.secondary .size ()) {
263- done ();
263+ callback (false );
264+ return ;
265+ }
266+
267+ if (&config_.secondary [index] == excludedServiceInfo) {
268+ probeSecondaryFrom (index + 1 , excludedServiceInfo, std::move (callback));
264269 return ;
265270 }
266271
267272 auto weakSelf = weak_from_this ();
268- probeAvailableAsync (config_.secondary [index],
269- [weakSelf, index, done = std::move (done)](bool available) mutable {
270- auto self = weakSelf.lock ();
271- if (!self) {
272- return ;
273- }
274-
275- LOG_DEBUG (" Detected secondary " << self->config_ .secondary [index].serviceUrl ()
276- << " availability: " << available);
277- if (available) {
278- self->switchTo (&self->config_ .secondary [index]);
279- done ();
280- return ;
281- }
282-
283- self->probeSecondaryFrom (index + 1 , std::move (done));
284- });
273+ probeAvailableAsync (
274+ config_.secondary [index],
275+ [weakSelf, index, excludedServiceInfo, callback = std::move (callback)](bool available) mutable {
276+ auto self = weakSelf.lock ();
277+ if (!self) {
278+ return ;
279+ }
280+
281+ LOG_DEBUG (" Detected secondary " << self->config_ .secondary [index].serviceUrl ()
282+ << " availability: " << available);
283+ if (available) {
284+ self->switchTo (&self->config_ .secondary [index]);
285+ callback (true );
286+ return ;
287+ }
288+
289+ self->probeSecondaryFrom (index + 1 , excludedServiceInfo, std::move (callback));
290+ });
285291 }
286292
287293 void checkAndFailoverToSecondaryAsync (CompletionCallback done) {
@@ -305,10 +311,45 @@ class AutoClusterFailoverImpl : public std::enable_shared_from_this<AutoClusterF
305311 return ;
306312 }
307313
308- self->probeSecondaryFrom (0 , std::move (done));
314+ self->probeSecondaryFrom (0 , nullptr , [done = std::move (done)]( bool ) mutable { done (); } );
309315 });
310316 }
311317
318+ void failoverFromUnavailableSecondaryAsync (CompletionCallback done) {
319+ auto weakSelf = weak_from_this ();
320+ probeAvailableAsync (
321+ config_.primary , [weakSelf, done = std::move (done)](bool primaryAvailable) mutable {
322+ auto self = weakSelf.lock ();
323+ if (!self) {
324+ return ;
325+ }
326+
327+ LOG_DEBUG (" Detected primary while secondary is unavailable "
328+ << self->config_ .primary .serviceUrl () << " availability: " << primaryAvailable);
329+ if (primaryAvailable) {
330+ self->switchTo (&self->config_ .primary );
331+ done ();
332+ return ;
333+ }
334+
335+ self->probeSecondaryFrom (
336+ 0 , self->currentServiceInfo_ ,
337+ [weakSelf, done = std::move (done)](bool switchedToAnotherSecondary) mutable {
338+ auto self = weakSelf.lock ();
339+ if (!self) {
340+ return ;
341+ }
342+
343+ if (switchedToAnotherSecondary) {
344+ done ();
345+ return ;
346+ }
347+
348+ self->checkSwitchBackToPrimaryAsync (std::move (done), false );
349+ });
350+ });
351+ }
352+
312353 void checkSwitchBackToPrimaryAsync (CompletionCallback done, std::optional<bool > primaryAvailableHint) {
313354 auto handlePrimaryAvailable = [weakSelf = weak_from_this (),
314355 done = std::move (done)](bool primaryAvailable) mutable {
@@ -358,23 +399,7 @@ class AutoClusterFailoverImpl : public std::enable_shared_from_this<AutoClusterF
358399 return ;
359400 }
360401
361- self->probeAvailableAsync (
362- self->config_ .primary , [weakSelf, done = std::move (done)](bool primaryAvailable) mutable {
363- auto self = weakSelf.lock ();
364- if (!self) {
365- return ;
366- }
367-
368- LOG_DEBUG (" Detected primary while secondary is unavailable "
369- << self->config_ .primary .serviceUrl () << " availability: " << primaryAvailable);
370- if (primaryAvailable) {
371- self->switchTo (&self->config_ .primary );
372- done ();
373- return ;
374- }
375-
376- self->checkSwitchBackToPrimaryAsync (std::move (done), false );
377- });
402+ self->failoverFromUnavailableSecondaryAsync (std::move (done));
378403 });
379404 }
380405};
0 commit comments