// Path: src/main/java/com/optimaize/command4j/lang/Duration.java
// @Immutable
// public final class Duration {
// 
//     private final long time;
//     @NotNull
//     private final TimeUnit timeUnit;
// 
//     @NotNull
//     public static Duration of(long time, @NotNull TimeUnit unit) {
//         return new Duration(time, unit);
//     }
// 
//     @NotNull
//     public static Duration millis(long time) {
//         return of(time, TimeUnit.MILLISECONDS);
//     }
// 
//     @NotNull
//     public static Duration seconds(long time) {
//         return of(time, TimeUnit.SECONDS);
//     }
// 
//     private Duration(long time, @NotNull TimeUnit timeUnit) {
//         this.time = time;
//         this.timeUnit = timeUnit;
//     }
// 
// 
//     public long getTime() {
//         return time;
//     }
// 
//     @NotNull
//     public TimeUnit getTimeUnit() {
//         return timeUnit;
//     }
// 
//     public long toMillis() {
//         return timeUnit.toMillis(time);
//     }
// 
//     public boolean isZero() {
//         return time==0;
//     }
// 
//     @Override
//     public String toString() {
//         return "Duration[" + time + toString(timeUnit) + ']';
//     }
// 
//     @NotNull
//     private String toString(@NotNull TimeUnit timeUnit) {
//         switch (timeUnit) {
//             case MILLISECONDS:
//                 return "ms";
//             case SECONDS:
//                 return "s";
//             case MINUTES:
//                 return "m";
//             case HOURS:
//                 return "h";
//             case DAYS:
//                 return "d";
//             default:
//                 return timeUnit.name();
//         }
//     }
// }


import com.optimaize.command4j.lang.Duration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
package com.optimaize.command4j.ext.extensions.failover.autoretry;


/**
 * @author Fabian Kessler
 */
public interface AutoRetryStrategy {

    /**
     * Decides if auto-retry should take place.
     * @param executionCounter When this method is called for the first time the number is 1 (one
     *                         execution failed already). The second time it's 2, and so on.
     *                         You need to return <code>null</code> when this number gets too high to
     *                         prevent endless retrying and waiting.
     *                         Also, you may increase the duration as the counter increases.
     * @param exception The exception that occurred. The method is encouraged to respond based on this.
     * @return <code>null</code> to not retry, otherwise a Duration for how long to wait until the retry
     *         should take place.
     */
    @Nullable
// Path: src/main/java/com/optimaize/command4j/lang/Duration.java
// @Immutable
// public final class Duration {
// 
//     private final long time;
//     @NotNull
//     private final TimeUnit timeUnit;
// 
//     @NotNull
//     public static Duration of(long time, @NotNull TimeUnit unit) {
//         return new Duration(time, unit);
//     }
// 
//     @NotNull
//     public static Duration millis(long time) {
//         return of(time, TimeUnit.MILLISECONDS);
//     }
// 
//     @NotNull
//     public static Duration seconds(long time) {
//         return of(time, TimeUnit.SECONDS);
//     }
// 
//     private Duration(long time, @NotNull TimeUnit timeUnit) {
//         this.time = time;
//         this.timeUnit = timeUnit;
//     }
// 
// 
//     public long getTime() {
//         return time;
//     }
// 
//     @NotNull
//     public TimeUnit getTimeUnit() {
//         return timeUnit;
//     }
// 
//     public long toMillis() {
//         return timeUnit.toMillis(time);
//     }
// 
//     public boolean isZero() {
//         return time==0;
//     }
// 
//     @Override
//     public String toString() {
//         return "Duration[" + time + toString(timeUnit) + ']';
//     }
// 
//     @NotNull
//     private String toString(@NotNull TimeUnit timeUnit) {
//         switch (timeUnit) {
//             case MILLISECONDS:
//                 return "ms";
//             case SECONDS:
//                 return "s";
//             case MINUTES:
//                 return "m";
//             case HOURS:
//                 return "h";
//             case DAYS:
//                 return "d";
//             default:
//                 return timeUnit.name();
//         }
//     }
// }


// Path: src/main/java/com/optimaize/command4j/ext/extensions/failover/autoretry/AutoRetryStrategy.java
import com.optimaize.command4j.lang.Duration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

package com.optimaize.command4j.ext.extensions.failover.autoretry;


/**
 * @author Fabian Kessler
 */
public interface AutoRetryStrategy {

    /**
     * Decides if auto-retry should take place.
     * @param executionCounter When this method is called for the first time the number is 1 (one
     *                         execution failed already). The second time it's 2, and so on.
     *                         You need to return <code>null</code> when this number gets too high to
     *                         prevent endless retrying and waiting.
     *                         Also, you may increase the duration as the counter increases.
     * @param exception The exception that occurred. The method is encouraged to respond based on this.
     * @return <code>null</code> to not retry, otherwise a Duration for how long to wait until the retry
     *         should take place.
     */
    @Nullable
    Duration doRetry(int executionCounter, @NotNull Exception exception);