2013-10-30 14 views
18

Próbuję zrozumieć ideę i cel scalazowego pakietu równoległego, głównie klasy Future i Task, ale kiedy używam ich w niektórych aplikacjach, jest to daleki od prostego sekwencyjnego analogu, podczas gdy scala.concurrent.Future, działa więcej niż lepiej. Czy ktokolwiek może podzielić się swoim doświadczeniem z pisaniem aplikacji współbieżnej/asynchronicznej z metodą skalase, w zasadzie, jak poprawnie zastosować jej metodę async? Jak rozumiem ze źródeł async nie używa osobnego wątku, takiego jak wywołanie standardowych future lub fork/apply metod z scalazu, więc dlaczego nazywa się to async? Czy to oznacza, że ​​aby uzyskać rzeczywistą współbieżność z skalą zawsze muszę zadzwonić pod numer fork(now(...)) lub apply?Mała pomoc w zrozumieniu Skalaza Przyszłość i zadanie

Odpowiedz

17

Nie jestem ekspertem od skalowania, ale spróbuję ci trochę pomóc. Pozwól mi spróbować odpowiedzieć na twoje pytania jeden po drugim:

1) Czy ktokolwiek może podzielić się swoimi doświadczeniami na temat pisania aplikacji współbieżnych/asynchronicznych za pomocą metody scalaz, w zasadzie, jak poprawnie używać tej metody asynchronicznej?

Niech najpierw przyjrzeć async podpisem:

def async[A](listen: (A => Unit) => Unit): Future[A]

To może być nieco tajemniczy na początku, tak jak zawsze jest to dobry pomysł, aby spojrzeć na testach na rozumie możliwych przypadków użycia. W https://github.com/scalaz/scalaz/blob/scalaz-seven/tests/src/test/scala/scalaz/concurrent/FutureTest.scala można znaleźć następujący kod:

"when constructed from Future.async" ! prop{(n: Int) => 
    def callback(call: Int => Unit): Unit = call(n) 
    Future.async(callback).run must_== 
} 

Jak wiemy z podpisem Future.async prostu zbudować nową przyszłość przy użyciu funkcji podpisu (A => Unit) => Unit. Oznacza to, że Future.async przyjmuje funkcję parametru, która przy danym wywołaniu wywołuje wszystkie wymagane obliczenia i przekazuje wynik do tego wywołania zwrotnego.
Co jest ważne, aby zauważyć, że Future.async nie uruchamia żadnych obliczeń na sobie, tylko przygotowuje strukturę, aby uruchomić je później.

2) Jak rozumiem ze źródeł async nie używa oddzielnego wątku, takiego jak wezwanie do standardowej przyszłości, czy też metody fork/apply z prac scalaz, więc dlaczego nazywa się to async?

Masz rację. Wydaje się, że tylko fork i apply działają przy użyciu wątków, co łatwo zauważyć na podpisach zawierających implicit pool: ExecutorService. Nie mogę mówić tutaj o autorach, ale przypuszczam, że asynchronizacja jest powiązana z oddzwanianiem. Oznacza to, że zamiast blokować w przyszłości, aby uzyskać wynik na końcu, użyjesz asynchronicznego wywołania zwrotnego.

3) Czy to oznacza, że ​​aby uzyskać rzeczywistą współbieżność z skalą zawsze muszę zadzwonić do fork (teraz (...)) lub złożyć wniosek?

Z tego, co mogę powiedzieć, tak. Zauważ, że kiedy tworzysz Future używając składni Future(x), używasz tutaj metody apply, więc jest to rodzaj domyślnego zachowania (co jest w porządku).

Jeśli chcesz lepiej zrozumieć projekt Futures Skalaz, mogę polecić Ci przeczytanie "Functional Programming in Scala". Wierzę, że ta książka została napisana przez głównych współpracowników Scalaz, a rozdział 7 omawia projektowanie API dla czysto funkcjonalnej biblioteki równoległości. To nie jest dokładnie to samo, co Scalaz Future, ale widać wiele podobieństw.

2

Możesz także przeczytać wspaniałą Timothy Perrett blog post o Scalaz Task and Future, która obejmuje wiele nie tak oczywistych szczegółów.

1

async służy do dostosowania asynchronicznego interfejsu API opartego na oddzwanianiu jako Future. Nazywa się to async, ponieważ oczekuje się, że będzie on używany z czymś, co działa asynchronicznie, być może wywołując wywołanie zwrotne z innego wątku gdzieś w dalszej linii. Jest to "prawdziwa" współbieżność, pod warunkiem, że API, do którego dzwonisz, używa go asynchronicznie (np. Używam Future.async z częściami asynchronicznymi pakietu SDK AWS, takimi jak AmazonSimpleDBAsyncClient).

Jeśli chcesz „prawdziwy” współbieżności z scalaz Task API bezpośrednio trzeba użyć rzeczy jak fork lub gatherUnordered, jak wielu z domyślnego API do bycia bezpiecznym/deterministyczne i restartowalne z współbieżności tylko na wyraźne życzenie.

Powiązane problemy