Korzystanie z odpowiedzi podmiotu w bieżącym procesie podmiotu

0

Pytanie

Jestem w szoku z powodu tego, jak należy rozwiązywać ten scenariusz nieblokujące sposób.

Rozważmy dwóch aktorów Actor1 i Actor2

Wewnątrz Actor1

Map<Int, Int> foo() {
     List<String> finalList = foo_2();
     Map<Int, Int> finalMap = // do stuff with finalList to get Map<Int, Int>;

     return finalMap;
}

List<String> foo_2() {
    
     CompletableFuture<List<String>> Querylist = ask(Actor2)
     Querylist.get();
     
     return QueryList;
}

Obecnie w granicach foo_2, Querylist.get() to blokowanie połączenia. Chcę się jakoś rozwiązać ten problem nieblokujące sposób. Założyłem zasilacz wiadomości dla Actor2 wewnątrz Actor1 więc wszelkie wiadomości, które Actor2 wysyłanie będą przetwarzane Actor1.

Użyłem następujące podejście do zmiany zablokowanego połączenia

Map<Int, Int> foo() {
     CompletionStage<List<String>> finalList = foo_2();
     finalList.whenComplete(
        // what to do here? 
     )
     // Map<Int, Int> finalMap = // do stuff with finalList to get Map<Int, Int>;

     return finalMap;
}

CompletionStage<List<String>> foo_2() {
    
     CompletionStage<List<String>> Querylist = ask(Actor2)
     
     
     return QueryList;
}

Nie jestem pewien, jak prawidłowo używać konstrukcję CompletionStage, aby uzyskać ten sam wynik, który otrzymałem podczas wywołania blokady futures.get ().

2

Najlepsza odpowiedź

1

Jeśli używasz typowy kod Akka (w tym z tagu), w ogóle nie trzeba będzie w przyszłości lub adapter wiadomości. Po prostu użyj ActorContext.ask.

Zobacz dokumentację dla żądania-odpowiedzi z prośbą między dwoma uczestnikami.

W szerokim znaczeniu, można by pozbył się foo i foo_2 metody, przenieś kartę wiadomości, który skonfigurowałeś, w ActorContext.ask zadzwoń i wymień przypadki, w których dzwonili wcześniej foo z apelem do ActorContext.ask. Jeśli odpowiedź, że twój aktor wysyła wiadomość, która doprowadziła do życzenie, zależy od odpowiedzi na pytanie, to dobrą praktyką jest umieszczanie wymaganych części stanu w komunikat, który generuje zasilacz.

2021-10-25 00:19:07

Dziękuję za odpowiedź, to jest to co ja w końcu zajął. Czy wiesz, jaka jest różnica między wykonaniem .tell() i wykorzystaniem ActorContext.ask()? Czy jest różnica w tym, że wyraźnie przekazuje do "obsługi" w ActorContext.ask() ?
PyWalker2797

Ostatecznie, ask wykonuje całą pracę na temat interakcji zapytania i odpowiedzi za ciebie: on zbudowany na podpowiedzi (w końcu, bardziej lub mniej wszystko w Akka jest). W szerokim sensie, ask rodzi podmiotu i wprowadza link do tego podmiotu jako adres do odpowiedzi wysyłanej wiadomości. Gdy ten podmiot otrzymuje komunikat, wykonuje adapter i przekazuje dostosowany odpowiedź podmiotowi, który przesłał żądanie; ten podmiot planuje również komunikat dla siebie po upływie czasu oczekiwania, który przekształca się w komunikat o czasie oczekiwania.
Levi Ramsey

Ponieważ rodzi podmiotu w celu uzyskania odpowiedzi, jest nieco mniej skuteczne, niż rejestracja karty wiadomości, zapytania i planowanie limitu czasu dla siebie. Jednak u ciebie może być dowolnie wiele zapytań z różnymi adapterami w locie: z adapterem tell + możesz przekroczyć limit jednego zasilacza dla każdego rodzaju (rejestracja innego zasilacza do jednego i tego samego typu może być nieprzewidywalna i dziedziczenie może również prowadzić do chaosu przy takim podejściu). Podejście tell + adapter ma to tę zaletę, że pozwala uzyskać kilka odpowiedzi.
Levi Ramsey

To wiele wyjaśnia. Można z grubsza wiadomo, jak duże są koszty?
PyWalker2797

Nie można także pomóc mi się z innym pytaniem.- stackoverflow.com/questions/69725512/...
PyWalker2797

Koszty są niewielkie: zużycie kilkuset bajtów pamięci i prawdopodobnie dodatkowe opóźnienie w uzyskaniu odpowiedzi na pytanie w chwilę lub około tego.
Levi Ramsey
1

Można użyć pipeToSelfpatrz https://doc.akka.io/docs/akka/current/typed/interaction-patterns.html#send-future-result-to-selfaby wysłać wynik zapytania samemu aktorowi. Zamiast próbować uzyskać wartość dla finalList bezpośrednio w foo(), co jest możliwe tylko przy zablokowanym getwynik foo() może być wysłany samemu wykonawcy, a w tym przypadku ty taktujesz go, jak każdy inny komunikat. W tym celu należy stworzyć pewien rodzaj wiadomości.

Należy również spojrzeć na CompletionStage metody, najważniejsze thenApply (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html#thenApply-java.util.function.Функция -), która pozwala na konwersję wyniki, na przykład, aby utworzyć Map z finalListi, na przykład, MapMessage z Map. Następnie można by poradzili sobie z MapMessage jak i inne wiadomości w актере.

2021-10-25 00:12:28

Witam, dziękuję za odpowiedź. Ostatecznie zgodziłem się z przyjętym odpowiedzią, ponieważ wydaje się bardziej идиоматичным.
PyWalker2797

W innych językach

Ta strona jest w innych językach

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