001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.http.client.retry;
017
018import de.cuioss.http.client.result.HttpResultObject;
019
020import java.util.concurrent.CompletableFuture;
021
022/**
023 * HTTP-specific retry strategy interface using virtual threads and asynchronous execution.
024 *
025 * <h2>Async Design with Virtual Threads</h2>
026 * This interface leverages Java 21's virtual threads to provide efficient, non-blocking retry operations:
027 *
028 * <ul>
029 *   <li><strong>Non-blocking delays</strong> - Uses CompletableFuture.delayedExecutor() instead of Thread.sleep()</li>
030 *   <li><strong>Virtual thread execution</strong> - Operations run on lightweight virtual threads</li>
031 *   <li><strong>Composable operations</strong> - CompletableFuture API enables natural async composition</li>
032 *   <li><strong>Resource efficient</strong> - No blocked threads during retry delays</li>
033 *   <li><strong>Scalable</strong> - Handles thousands of concurrent retry operations</li>
034 * </ul>
035 *
036 * <h2>Result Pattern Approach</h2>
037 * Continues to use the CUI result pattern with enhanced async capabilities:
038 *
039 * <ul>
040 *   <li><strong>No exceptions for flow control</strong> - All error states become result states</li>
041 *   <li><strong>Rich error context</strong> - HttpResultObject contains retry metrics, error codes, and details</li>
042 *   <li><strong>Forced error handling</strong> - Cannot access result without checking state</li>
043 *   <li><strong>Graceful degradation</strong> - Built-in fallback support with default results</li>
044 *   <li><strong>State-based flow</strong> - FRESH, CACHED, STALE, RECOVERED, ERROR states</li>
045 * </ul>
046 *
047 * <h2>Usage Patterns</h2>
048 * <h3>Blocking Usage (Legacy Compatibility)</h3>
049 * <pre>
050 * RetryStrategy strategy = RetryStrategies.exponentialBackoff();
051 * HttpResultObject&lt;String&gt; result = strategy.execute(operation, context).get();
052 *
053 * if (!result.isValid()) {
054 *     // Handle error cases
055 *     useFallbackContent(result.getResult());
056 * } else {
057 *     processResult(result.getResult());
058 * }
059 * </pre>
060 *
061 * <h3>Async Composition (Recommended)</h3>
062 * <pre>
063 * strategy.execute(operation, context)
064 *     .thenCompose(result -> {
065 *         if (result.isValid()) {
066 *             return processResult(result.getResult());
067 *         } else {
068 *             return handleError(result);
069 *         }
070 *     })
071 *     .thenAccept(processed -> updateCache(processed))
072 *     .exceptionally(ex -> handleException(ex));
073 * </pre>
074 */
075@FunctionalInterface
076public interface RetryStrategy {
077
078    /**
079     * Executes the given HTTP operation with retry logic using virtual threads and async execution.
080     *
081     * <p>This method runs operations on virtual threads with non-blocking delays between retry attempts.
082     * The implementation uses {@code CompletableFuture.delayedExecutor()} with virtual thread executors
083     * to provide efficient, scalable retry operations without blocking threads during delays.</p>
084     *
085     * @param <T> the type of result returned by the operation
086     * @param operation the HTTP operation to retry
087     * @param context retry context with operation name and attempt info
088     * @return CompletableFuture containing HttpResultObject with result and comprehensive error/retry information
089     */
090    <T> CompletableFuture<HttpResultObject<T>> execute(HttpOperation<T> operation, RetryContext context);
091
092    /**
093     * Creates a no-op retry strategy (single attempt only).
094     * Useful for disabling retry in specific scenarios or configurations.
095     *
096     * @return a retry strategy that executes the operation exactly once using virtual threads
097     */
098    static RetryStrategy none() {
099        return new RetryStrategy() {
100            @Override
101            public <T> CompletableFuture<HttpResultObject<T>> execute(HttpOperation<T> operation, RetryContext context) {
102                // No retry - just execute once on virtual thread and return completed future
103                return CompletableFuture.completedFuture(operation.execute());
104            }
105        };
106    }
107
108}