diff --git a/src/main/java/kz/konturai/parser/service/OpenAIAnalyticsService.java b/src/main/java/kz/konturai/parser/service/OpenAIAnalyticsService.java index 81ccc9f..c1000ba 100644 --- a/src/main/java/kz/konturai/parser/service/OpenAIAnalyticsService.java +++ b/src/main/java/kz/konturai/parser/service/OpenAIAnalyticsService.java @@ -235,7 +235,7 @@ public class OpenAIAnalyticsService { } try { - Map response = this.webClient.post() + Mono> responseMono = this.webClient.post() .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .bodyValue(requestBody) @@ -261,8 +261,12 @@ public class OpenAIAnalyticsService { logger.error("OpenAI API request timed out after {}ms", timeoutMs); } return Mono.empty(); - }) - .block(Duration.ofMillis(timeoutMs + 10000)); // Add buffer for block timeout + }); + // Calculate block timeout: request timeout + (max retries * max delay) + buffer + long blockTimeoutMs = timeoutMs + + (maxRetryAttempts * maxRetryDelayMs) + + 30000; // 30 second buffer + Map response = responseMono.block(Duration.ofMillis(blockTimeoutMs)); if (response == null) { return null; @@ -364,7 +368,7 @@ public class OpenAIAnalyticsService { try { logger.debug("Calling OpenAI API with model: {} (timeout: {}ms)", modelName, timeoutMsInstruction); // Use timeout operator in the reactive chain so timeouts can be retried - Map response = this.webClient.post() + Mono> responseMono = this.webClient.post() .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .bodyValue(requestBody) @@ -390,8 +394,15 @@ public class OpenAIAnalyticsService { logger.error("OpenAI API request timed out after {}ms", timeoutMsInstruction); } return Mono.empty(); - }) - .block(Duration.ofMillis(timeoutMsInstruction + 10000)); // Add buffer for block timeout + }); + // Calculate block timeout: request timeout + (max retries * max delay) + buffer + // This ensures we can wait through all retry attempts with rate limit delays + long blockTimeoutMs = timeoutMsInstruction + + (rateLimitMaxAttempts * rateLimitMaxDelayMs) + + 30000; // 30 second buffer + logger.debug("Block timeout calculated: {}ms (request: {}ms, retries: {} * {}ms, buffer: 30000ms)", + blockTimeoutMs, timeoutMsInstruction, rateLimitMaxAttempts, rateLimitMaxDelayMs); + Map response = responseMono.block(Duration.ofMillis(blockTimeoutMs)); if (response == null) { return null;