Jak włączyć Mono w bardzo asynchroniczny (nie jet!) wywołanie metody?

0

Pytanie

Mam metodę

@Service
public class MyService {
    public Mono<Integer> processData() {
        ... // very long reactive operation
    }
}

W normalnym strumieniu programu wzywam ta metoda asynchronicznie przez zdarzenie Kafki.

Dla celów testowania muszę przedstawić sposób jak usługi sieci web, ale metoda musi być przedstawiony jako asynchroniczny: zwrócić HTTP-kod 200 OK ("zlecenie") i kontynuować przetwarzanie danych w tle.

Normalnie czy (= czy nie ma żadnych niepożądanych efektów ubocznych) po prostu zadzwonić Mono#subscribe() i wrócić z metody kontrolera?

@RestController
@RequiredArgsConstructor
public class MyController {
    private final MyService service;

    @GetMapping
    public void processData() {
        service.processData()
            .subscribeOn(Schedulers.boundedElastic())
            .subscribe();
    }
}

Czy lepiej zrobić to tak (tutaj nie jestem pewna ostrzeżenie od IntelliJ, być może to samo, co https://youtrack.jetbrains.com/issue/IDEA-276018 ?):

public Mono<Void> processData() {
    service.processData()
        .subscribeOn(Schedulers.boundedElastic())
        .subscribe(); // IntelliJ complains "Inappropriate 'subscribe' call" but I think it's a false alarm in my case(?)
    return Mono.empty();
}

Lub jakieś inne rozwiązanie?

2

Najlepsza odpowiedź

3

Normalnie czy (= czy nie ma żadnych niepożądanych efektów ubocznych) wystarczy wywołać Mono#subscribe() i powrót z metody kontrolera?

Ma skutki uboczne, ale spokojnie można z nimi żyć:

  • To naprawdę jest ogień i zapomnij, co oznacza, że choć nigdy nie zostanie powiadomiony o sukcesie (że zdaje sobie sprawę większość ludzi), można również nigdy nie zostanie powiadomiony o awarii (co jest świadoma znacznie mniej ludzi).
  • Jeśli proces z jakiegoś powodu zawiesił, ten wydawca nigdy się nie zakończy, i nie będzie w stanie dowiedzieć się o tym. Ponieważ korzystasz z ograniczoną pulę elastycznych wątków, także połączy jeden z tych ograniczonych wątków na czas nieokreślony.

Pierwszy moment, z którym może być wszystko w porządku, czy może chcesz w jakiś sposób zalogować niektóre błędy dalej na tej biernej łańcuchu jako efekt uboczny, aby mieć, co najmniej, było wewnętrzne powiadomienie, jeśli coś pójdzie nie tak.

Co do drugiego punktu - polecam zainstalować (hojny) limit czasu dla wywołania metody, aby on, co najmniej, został odwołany, jeżeli nie zostało zakończone w określonym czasie i nie zawiesza się, zużywa zasoby. Jeśli wykonujesz asynchroniczne zadanie, to nie jest poważny problem, ponieważ ona po prostu zużywa mało pamięci. Jeśli обертываете blokowanie połączenia z elastycznym harmonogramie, to jednak jeszcze gorzej, ponieważ kojarzy się strumień w tej puli wątków na czas nieokreślony.

Chciałbym również zastanawiał się, po co w ogóle korzystać z ograniczoną elastyczny harmonogram tutaj jest on używany do przesyłania blokowanie połączeń, co, jak się wydaje, nie jest podstawą tej opcji korzystać. (Żeby było jasne, jeśli usługa jest zablokowana, należy całkowicie wkręcić ją w elastyczny harmonogram, ale jeśli nie, to nie ma do tego powodów.)

W końcu ten przykład:

public Mono<Void> processData() {
    service.processData()
        .subscribeOn(Schedulers.boundedElastic())
        .subscribe();
    return Mono.empty();
}

...to doskonały przykład tego, czego nie należy robić, ponieważ można stworzyć swego rodzaju "samozwańczy reaktywne metody" - może ktoś bardzo inteligentnie zapisać się na tego zwróconego wydawcy, myśląc, że to zakończy się, gdy główny wydawca zakończy, co, oczywiście, tu się nie dzieje. Za pomocą void zwracany typ i, w konsekwencji, nic się nie zwrócić-to jest właściwe rozwiązanie w tym scenariuszu.

2021-11-23 16:54:58
1

Twój wariant z następującym kodem naprawdę w porządku:

@GetMapping
public void processData() {
    service.processData()
        .subscribeOn(Schedulers.boundedElastic())
        .subscribe();
}

To jest właściwie to, co robisz w @Scheduled metoda, która nic nie zwraca, i wyraźnie zapisać się na Mono lub Flux tak, że elementy emitowane są.

2021-11-23 08:36:44

W innych językach

Ta strona jest w innych językach

Русский
..................................................................................................................
Italiano
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................