74 Stimmen

Entwurfsmuster für die Wiederholung einer fehlgeschlagenen Logik?

Ich schreibe einige Reconnect-Logik, um regelmäßig zu versuchen, eine Verbindung zu einem entfernten Endpunkt herzustellen, der ausgefallen ist. Im Wesentlichen sieht der Code wie folgt aus:

public void establishConnection() {
    try {
        this.connection = newConnection();
    } catch (IOException e) {
        // connection failed, try again.
        try { Thread.sleep(1000); } catch (InterruptedException e) {};

        establishConnection();
    }
}

Ich habe dieses allgemeine Problem schon oft mit ähnlichem Code gelöst, aber ich bin mit dem Ergebnis weitgehend unzufrieden. Gibt es ein Entwurfsmuster für die Lösung dieses Problems?

0voto

Andrey Borisov Punkte 3150

Es gibt nichts Besonderes bei der Wiederholung von Versuchen - nehmen Sie diese Klasse als Beispiel http://www.docjar.com/html/api/org/springframework/jms/listener/DefaultMessageListenerContainer.java.html Wie Sie sehen können, schreiben selbst Spring-Entwickler immer noch Code für Wiederholungen - Zeile 791... es gibt kein solches spezielles Muster AFAIK..

Was ich raten kann, um mit Ressourcen umzugehen ist Apache Commons Pool-Bibliothek zu nehmen - überprüfen Sie diese http://commons.apache.org/pool/apidocs/org/apache/commons/pool/impl/GenericObjectPool.html und besuchen Sie http://commons.apache.org/pool

0voto

Mehmet Pekdemir Punkte 145

Ich habe meine eigene Anmerkung geschrieben. Vielleicht können Sie diese Anmerkung verwenden.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RetryOperation {

    int retryCount();

    int waitSeconds();
}

@Slf4j
@Aspect
@Component
public class RetryOperationAspect {

    @Around(value = "@annotation(com.demo.infra.annotation.RetryOperation)")
    public Object retryOperation(ProceedingJoinPoint joinPoint) throws Throwable {
        Object response = null;
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        RetryOperation annotation = method.getAnnotation(RetryOperation.class);
        int retryCount = annotation.retryCount();
        int waitSeconds = annotation.waitSeconds();
        boolean successful = false;

        do {
            try {
                response = joinPoint.proceed();
                successful = true;
            } catch (Exception e) {
                log.error("Operation failed, retries remaining: {}", retryCount);
                retryCount--;
                if (retryCount < 0) {
                    throw e;
                }
                if (waitSeconds > 0) {
                    log.warn("Waiting for {} second(s) before next retry", waitSeconds);
                    Thread.sleep(waitSeconds * 1000L);
                }
            }
        } while (!successful);

        return response;
    }
}

@RetryOperation(retryCount = 5, waitSeconds = 1)
public void method() {

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X