From d084d9aa01027f92b925fd661c9f50338c208998 Mon Sep 17 00:00:00 2001 From: krestar Date: Wed, 19 Aug 2026 17:54:48 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20AI=20Runtime=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=ED=83=80=EC=9E=84=EC=95=84=EC=9B=83=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EA=B0=92=EC=9D=84=205=EB=B6=84=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AI Runtime overall timeout 기본값을 240초에서 300초로 변경 - AI_RUNTIME_OVERALL_TIMEOUT 환경변수 override 기능 유지 - 5분 최대 허용값 및 초과값 거부 정책 유지 - 관련 테스트, 예시 환경설정, 계약 문서의 기본값을 300초로 일치 --- .env.example | 2 +- docs/ai-runtime-contract.md | 4 ++-- .../infrastructure/http/AiRuntimeProperties.java | 2 +- src/main/resources/application.yaml | 2 +- .../infrastructure/http/AiRuntimePropertiesTest.java | 12 ++++++------ .../fowoco/server/airun/AiRunApiIntegrationTest.java | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index 5922587..0bae487 100644 --- a/.env.example +++ b/.env.example @@ -36,7 +36,7 @@ AI_DOCUMENT_CONVERSION_ENDPOINT=http://127.0.0.1:8000/api/v1/documents/convert AI_DOCUMENT_CONVERSION_TIMEOUT=60s # AI_RUNTIME_SERVICE_CREDENTIAL= AI_RUNTIME_CONNECT_TIMEOUT=2s -AI_RUNTIME_OVERALL_TIMEOUT=240s +AI_RUNTIME_OVERALL_TIMEOUT=300s AI_RUNTIME_MAX_RESPONSE_BYTES=1048576 AI_DOCUMENT_GENERATION_MAX_RESPONSE_BYTES=20971520 AI_RUNTIME_MAX_CONCURRENT_CALLS=8 diff --git a/docs/ai-runtime-contract.md b/docs/ai-runtime-contract.md index 7f2e03f..3771a4a 100644 --- a/docs/ai-runtime-contract.md +++ b/docs/ai-runtime-contract.md @@ -184,7 +184,7 @@ Slot 조회와 ANALYZE 호출은 수행하지 않습니다. 따라서 지원하 `AiAnalysisRequest`에 유지하지만 HTTP JSON에는 넣지 않습니다. 한 번의 PLAN 또는 ANALYZE 호출 제한시간은 `AI_RUNTIME_OVERALL_TIMEOUT`을 단일 기준으로 -사용합니다. 기본값은 실제 A.X CPU 추론 시간을 수용하는 `240s`이고 계약상 최대값은 +사용합니다. 기본값은 실제 A.X CPU 추론 시간을 수용하는 `300s`이고 계약상 최대값은 `5m`입니다. Client 요청은 먼저 `202 + aiRunId`를 반환하므로 이 제한시간 동안 HTTP 화면 요청을 붙잡지 않으며, 진행 상태는 SSE와 조회 API로 제공합니다. @@ -378,7 +378,7 @@ AI_RUNTIME_SERVICE_CREDENTIAL=<배포 환경 Secret> | 설정 | 기본값 | 의미 | | --- | --- | --- | | `AI_RUNTIME_CONNECT_TIMEOUT` | `2s` | AI 서버에 TCP 연결을 맺을 수 있는 최대 시간 | -| `AI_RUNTIME_OVERALL_TIMEOUT` | `15s` | 연결·요청·응답 수신 전체의 Server 상한 | +| `AI_RUNTIME_OVERALL_TIMEOUT` | `300s` | 연결·요청·응답 수신 전체의 Server 상한 | | `AI_RUNTIME_MAX_RESPONSE_BYTES` | `1048576` | 응답을 메모리에 받기 전 적용하는 최대 크기 | | `AI_DOCUMENT_GENERATION_ENDPOINT` | `http://127.0.0.1:8000/api/v1/documents/generate` | Renewal 문서 생성 API | | `AI_DOCUMENT_CONVERSION_ENDPOINT` | `http://127.0.0.1:8000/api/v1/documents/convert` | HWP·HWPX를 PDF 미리보기로 변환하는 API | diff --git a/src/main/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimeProperties.java b/src/main/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimeProperties.java index 67e98b1..889bc70 100644 --- a/src/main/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimeProperties.java +++ b/src/main/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimeProperties.java @@ -20,7 +20,7 @@ public final class AiRuntimeProperties implements AiRuntimeDeadlinePolicy { private URI documentConversionEndpoint = URI.create("http://127.0.0.1:8000/api/v1/documents/convert"); private String serviceCredential; private Duration connectTimeout = Duration.ofSeconds(2); - private Duration overallTimeout = Duration.ofMinutes(4); + private Duration overallTimeout = Duration.ofMinutes(5); private Duration documentConversionTimeout = Duration.ofSeconds(60); private int maxResponseBytes = 1_048_576; private int maxDocumentResponseBytes = MAX_DOCUMENT_RESPONSE_BYTES; diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index a82c693..cfb0a20 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -78,7 +78,7 @@ app: document-conversion-timeout: ${AI_DOCUMENT_CONVERSION_TIMEOUT:60s} service-credential: ${AI_RUNTIME_SERVICE_CREDENTIAL:} connect-timeout: ${AI_RUNTIME_CONNECT_TIMEOUT:2s} - overall-timeout: ${AI_RUNTIME_OVERALL_TIMEOUT:240s} + overall-timeout: ${AI_RUNTIME_OVERALL_TIMEOUT:300s} max-response-bytes: ${AI_RUNTIME_MAX_RESPONSE_BYTES:1048576} max-document-response-bytes: ${AI_DOCUMENT_GENERATION_MAX_RESPONSE_BYTES:20971520} max-concurrent-calls: ${AI_RUNTIME_MAX_CONCURRENT_CALLS:8} diff --git a/src/test/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimePropertiesTest.java b/src/test/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimePropertiesTest.java index b9e9e35..9d99673 100644 --- a/src/test/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimePropertiesTest.java +++ b/src/test/java/com/fowoco/server/aiintegration/infrastructure/http/AiRuntimePropertiesTest.java @@ -9,11 +9,11 @@ class AiRuntimePropertiesTest { @Test - void usesFourMinuteDeadlineByDefault() { + void usesFiveMinuteDeadlineByDefault() { AiRuntimeProperties properties = new AiRuntimeProperties(); - assertThat(properties.getOverallTimeout()).isEqualTo(Duration.ofMinutes(4)); - assertThat(properties.attemptDeadlineMs()).isEqualTo(240_000L); + assertThat(properties.getOverallTimeout()).isEqualTo(Duration.ofMinutes(5)); + assertThat(properties.attemptDeadlineMs()).isEqualTo(300_000L); assertThat(properties.getDocumentConversionTimeout()).isEqualTo(Duration.ofSeconds(60)); } @@ -21,10 +21,10 @@ void usesFourMinuteDeadlineByDefault() { void usesConfiguredOverallTimeoutAsAttemptDeadline() { AiRuntimeProperties properties = new AiRuntimeProperties(); - properties.setOverallTimeout(Duration.ofSeconds(180)); + properties.setOverallTimeout(Duration.ofSeconds(300)); - assertThat(properties.getOverallTimeout()).isEqualTo(Duration.ofSeconds(180)); - assertThat(properties.attemptDeadlineMs()).isEqualTo(180_000L); + assertThat(properties.getOverallTimeout()).isEqualTo(Duration.ofSeconds(300)); + assertThat(properties.attemptDeadlineMs()).isEqualTo(300_000L); } @Test diff --git a/src/test/java/com/fowoco/server/airun/AiRunApiIntegrationTest.java b/src/test/java/com/fowoco/server/airun/AiRunApiIntegrationTest.java index 3978529..ee37a71 100644 --- a/src/test/java/com/fowoco/server/airun/AiRunApiIntegrationTest.java +++ b/src/test/java/com/fowoco/server/airun/AiRunApiIntegrationTest.java @@ -213,7 +213,7 @@ void createsQueriesAnswersAndFinishesOneWorkerAnalysis() throws Exception { ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(AiAnalysisRequest.class); verify(runtimeClient, atLeast(3)).analyze(requestCaptor.capture(), any()); assertThat(requestCaptor.getAllValues()) - .allSatisfy(request -> assertThat(request.deadlineMs()).isEqualTo(240_000L)); + .allSatisfy(request -> assertThat(request.deadlineMs()).isEqualTo(300_000L)); assertThat(stageCount("PLAN", "PLAN_RUNTIME_CALL", "SUCCESS") - planBefore) .isEqualTo(1); assertThat(stageCount("ANALYZE", "SLOT_RESOLUTION", "SUCCESS") - slotBefore)