pf-sdn/src/main/java/ru/kirillius/pf/sdn/service/DomainUpdaterService.java

90 lines
3.0 KiB
Java

package ru.kirillius.pf.sdn.service;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import ru.kirillius.pf.sdn.Util.WorkerUtils;
import ru.kirillius.pf.sdn.api.Networking.DomainResolver;
import java.net.Inet4Address;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@Service
@RequiredArgsConstructor
@Slf4j
public class DomainUpdaterService {
private final DomainCacheService domainCacheService;
private final DomainResolver domainResolver;
private final ExecutorService executor;
private final SubscriptionService subscriptionService;
public List<Inet4Address> getActualAddresses(String domain) {
var cached = domainCacheService.load(domain, true);
if (!cached.isEmpty()) {
var resolved = domainResolver.getAddresses(domain);
while (!resolved.isDone() && !resolved.isCancelled()) {
Thread.yield();
}
if (resolved.isDone()) {
try {
domainCacheService.update(domain, resolved.get());
cached.addAll(resolved.get());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
return cached;
}
private Future<?> worker;
private final RuntimeConfigService configService;
@PostConstruct
private void initialize() {
worker = executor.submit(() -> new WorkerUtils.LoopedWorker() {
@Override
protected void doWork() {
subscriptionService.getSubscriptions().forEach(subscription -> {
var scope = subscription.getScope();
if (scope.getResolveDomains().isEmpty()) {
return;
}
scope.getDomains().forEach(domain -> {
var future = domainResolver.getAddresses(domain);
while (!future.isDone() && !future.isCancelled()) {
Thread.yield();
}
if (future.isDone()) {
try {
domainCacheService.update(domain, future.get());
} catch (InterruptedException | ExecutionException e) {
log.error("Domain {} resolve failed", domain);
}
}
});
});
WorkerUtils.waitForTimer(() -> Duration.ofMinutes(configService.getConfig().getDomainResolveInterval()));
}
});
}
@PreDestroy
private void destroy() {
if (worker != null) {
worker.cancel(true);
worker = null;
}
}
}