2009-08-21 12 views
6

Napisałem już kilka aplikacji za pomocą operatorów scala i interesuje mnie, w jaki sposób ludzie podeszli do niektórych napotkanych problemów lub poradzili sobie z nimi.Pisanie aplikacji z aktorami Scala w praktyce

Mnóstwo klas wiadomości lub!?

Mam aktora, który reaguje na operację użytkownika i musi spowodować, że coś się stanie. Powiedzmy, że to react s do wiadomości UserRequestsX(id). Ciągle mam problem z tym, że ponieważ chcę modularyzować moje programy, pojedynczy aktor sam w sobie nie jest w stanie ukończyć działania bez angażowania innych aktorów. Na przykład, przypuśćmy, że muszę użyć parametru id, aby pobrać kilka wartości, a następnie te muszą zostać usunięte przez innego aktora. Gdybym pisał normalny program w języku Java, mógłbym zrobić coś takiego:

public void reportTrades(Date date) { 
    Set<Trade> trades = persistence.lookup(date); 
    reportService.report(trades); 
} 

Co jest dość proste. Jednak używanie aktorów staje się trochę uciążliwe, ponieważ chcę uniknąć używania !?. Jeden aktor reaguje na komunikat ReportTrades(date), ale musi zapytać o transakcje PersistenceActor, a następnie ReportActor, aby je zgłosić. Jedynym sposobem znalazłem na to jest do zrobienia:

react { 
    case ReportTrades(date) => 
     persistenceActor ! GetTradesAndReport(date) 
} 

tak, że w moim PersistenceActor mam blok reagowania:

react { 
    case GetTradesAndReport(date) => 
     val ts = trades.get(date) //from persietent store 
     reportActor ! ReportTrades(ts) 
} 

Ale teraz mam 2 problemy:

  1. Muszę utworzyć dodatkowe klasy wiadomości do reprezentowania tego samego żądania (tj. "Transakcje raportów"). W rzeczywistości mam trzy w tym scenariuszu, ale mogę mieć o wiele więcej - staje się problemem śledzenie tych
  2. Co powinienem nazwać pierwszą i trzecią wiadomością ReportTrades? Mylące jest wywoływanie ich zarówno ReportTrades (lub jeśli tak, muszę umieścić je w osobnych pakietach). Zasadniczo nie ma czegoś takiego jak overloading klasa typu val.

Czy jest coś, czego mi brakuje? Czy mogę tego uniknąć? Czy powinienem po prostu zrezygnować i użyć !? Czy ludzie używają jakiejś struktury organizacyjnej, aby wyjaśnić, co się dzieje?

+0

Czy można bezpiecznie uzyskać dostęp do magazynu trwałego bezpośrednio w trybie "reagowania"? Myślałem, że nie możesz blokować operacji.Być może "otrzymanie" jest potrzebne dla tego konkretnego aktora. –

Odpowiedz

2

Dla mnie wiadomość ReportTrades miesza dwa różne pojęcia. Jedna jest Żądaniem, kolejność jest odpowiedzią. Mogą być na przykład nazwani GetTradesReport(Date) i SendTradesReport(List[Trade]). Lub, być może, ReportTradesByDate(Date) i GenerateTradesReport(List[Trade]).

+0

Ale mój punkt jest nadal ważny; Wszystkie te klasy są używane wyłącznie do przekazywania danych. Wczoraj napisałem kod, w którym musiałem "udekorować" żądanie informacjami od 4 oddzielnych aktorów. Nawet pozwalając na rozsądne nazewnictwo, jest to wiele mylących zajęć! –

+0

Cóż, takie klasy nigdy nie są używane tylko do przekazywania informacji. Są one używane do przekazywania informacji z jednego miejsca do drugiego w określonym celu. Jeśli odpowiednio je nazwiesz, poprawisz ogólną czytelność kodu. –

0

Czy są pewne zastrzeżenia do korzystania z reply? Lub przekazując trades wokół? Jeśli nie, to kod będzie prawdopodobnie wyglądać

react { 
    case ReportTrades(date) => persistenceActor ! GetTrades(date) 
    case Trades(ts) => // do smth with trades 
} 

i

react { 
    case GetTrades(date) => reply(Trades(trades.get(date))) 
} 

odpowiednio.

+0

Zgaduję, że nie mogę po prostu przekazać obiektu 'Trades' z powrotem do koordynatora, ponieważ * w jaki sposób będzie wiedział, które oryginalne polecenie zostało wywołane? * Na przykład, mogę mieć kilka rzeczy, które muszę zrobić: * DeleteTrades *, * ReportTrades *, * LoadTrades * itd. Koordynator będzie potrzebował uzyskać odpowiedź typu 'SomeTradesToReport',' SomeTradesToDelete' lub 'SomeTradesToLoad' (zakładając, że unikam'!? ') –

Powiązane problemy