Mam takie zadanie:
Użytkownik podaję listę parametrów, a aplikacja w określonym interwale czasowym dla każdego parametru wykonuje zapytanie REST do zewnętrznego API. Określone wyniki chcę następnie publikowac poprzez Spring Events i odbierać w innym serwisie. Chciałbym się upewnić co do poprawności mojego rozwiązania.
Mam sobie pojedynczego workera, który jest odpowiedzialny za wykonanie zapytania, przefiltrowanie i obublikowanie wynikow.
@RequiredArgsConstructor
public class Worker implements Runnable {
private final RestClient client;
private final ApplicationEventPublisher publisher;
private final String query;
@Override
public void run (){
final var response = client.invoke("external-service.com/api/stuff?" + query);
final var filteredResponse = filter(response);
publisher.publishEvent(new MyEvent(this, filteredResponse ));
}
private Response filter(final Response response) {
// do some filtering here
}
}
No i serwis który buduje mi tych workerów a nastepnie ich uruchamia
@Service
public class WorkerService {
private final Set<Worker> workers = new HashSet<>();
public WorkerService(final QueryRepository queryRepository, final RestClient restClient, final ApplicationEventPublisher eventPublisher) {
queryRepository.getSearchQueries().forEach(query -> workers.add(new Worker(restClient, eventPublisher, query)));
}
@PostConstruct
private void initWorkers() {
final var executors = Executors.newScheduledThreadPool(workers.size());
workers.forEach(worker -> executors.scheduleAtFixedRate(worker, 0, 5, TimeUnit.SECONDS));
}
}
No i teoretycznie wszystko działa, zastanawia mnie jednak czy aby na pewno ;) Obecnie operuje na kilku query, co gdy pojawi się ich 500, 1000, albo więcej?
Dodatkowo, chcę zmniejszych interwal z 5 do powiedzmy 1 sekundy. Samo zadanie workera jednak może trwać dłużej, pojedyncze query może wymagać kilku zapytań REST (wyniki są pageowane). Czy w takim przypadku kolejne wywołanie danego workera odbędzie sie 1 sekunę po zakończeniu poprzedniego zadania? Czy co sekundę będzie odpalana metoda run()
, bez względu na to że poprzednie wywołanie jeszcze trwa?
Poza tym, wszystkie instancje workera korzystają z tego samego RestClient
, który ma wstrzyknięty RestTemplate
- czy to nie będzie problem przy większej ilości workerów?