diff --git a/src/main/java/com/olympus/hermione/HermioneApplication.java b/src/main/java/com/olympus/hermione/HermioneApplication.java index 2ed5d07..91aa3f5 100644 --- a/src/main/java/com/olympus/hermione/HermioneApplication.java +++ b/src/main/java/com/olympus/hermione/HermioneApplication.java @@ -4,10 +4,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication(scanBasePackages = {"com.olympus.hermione", "com.olympus"}) @EnableFeignClients(basePackages = "com.olympus.feign") @EnableAsync +@EnableScheduling public class HermioneApplication { public static void main(String[] args) { diff --git a/src/main/java/com/olympus/hermione/config/ChromaWarmupService.java b/src/main/java/com/olympus/hermione/config/ChromaWarmupService.java new file mode 100644 index 0000000..bc2ff57 --- /dev/null +++ b/src/main/java/com/olympus/hermione/config/ChromaWarmupService.java @@ -0,0 +1,72 @@ +package com.olympus.hermione.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.time.Duration; + +/** + * Service per mantenere Chroma "sveglio" ed evitare cold start + * Esegue un warmup all'avvio e periodicamente ogni 5 minuti + */ +@Component +public class ChromaWarmupService { + + private static final Logger logger = LoggerFactory.getLogger(ChromaWarmupService.class); + + @Value("${spring.ai.vectorstore.chroma.client.host}") + private String chromaHost; + + @Value("${spring.ai.vectorstore.chroma.client.port}") + private String chromaPort; + + private final RestTemplate restTemplate; + + public ChromaWarmupService() { + this.restTemplate = new RestTemplate(); + // Timeout generosi per il warmup + this.restTemplate.setRequestFactory(new org.springframework.http.client.SimpleClientHttpRequestFactory() {{ + setConnectTimeout((int) Duration.ofSeconds(30).toMillis()); + setReadTimeout((int) Duration.ofSeconds(60).toMillis()); + }}); + } + + /** + * Esegue il warmup all'avvio dell'applicazione + */ + @EventListener(ApplicationReadyEvent.class) + public void warmupOnStartup() { + logger.info("Starting Chroma warmup on application startup..."); + performWarmup(); + } + + /** + * Esegue il warmup ogni 5 minuti per mantenere Chroma attivo + */ + @Scheduled(fixedRate = 300000) // TEST: 30 secondi (cambiare a 300000 per production) + public void scheduledWarmup() { + logger.info("Performing scheduled Chroma warmup..."); + performWarmup(); + } + + private void performWarmup() { + String healthUrl = chromaHost + ":" + chromaPort + "/api/v1/heartbeat"; + + try { + long startTime = System.currentTimeMillis(); + restTemplate.getForObject(healthUrl, String.class); + long duration = System.currentTimeMillis() - startTime; + + logger.info("Chroma warmup successful ({}ms)", duration); + } catch (Exception e) { + logger.warn("Chroma warmup failed: {}", e.getMessage()); + // Non blocchiamo l'applicazione se il warmup fallisce + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6ad84ce..228e145 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -77,15 +77,3 @@ jsp-parser-module.url: http://jsp-parser-module-service.olympus.svc.cluster.loca spring.security.oauth2.resourceserver.jwt.issuer-uri= https://sts.windows.net/e0793d39-0939-496d-b129-198edd916feb/ - -# ------------------------------ -# SPRING AI RETRY / TIMEOUTS -# ------------------------------ -spring.ai.retry.max-attempts=3 -spring.ai.retry.backoff.delay=2000 -spring.ai.retry.backoff.max-delay=20000 -spring.ai.retry.backoff.multiplier=2 - -# Timeout for HTTP clients used by Spring AI / Chroma -spring.ai.vectorstore.http.connect-timeout=10000 -spring.ai.vectorstore.http.read-timeout=20000 \ No newline at end of file