2015-11-11 9 views
6

Załóżmy, że mam zbiór obliczeń, które chcę uruchomić asynchronicznie za pomocą core.async, ale niestety kilka funkcji zależy od wyjścia z innych funkcji. W jaki sposób mam zamiar uporządkować to wszystko w moim kodzie, jednocześnie uzyskując najlepszą wydajność?W jaki sposób jednoznacznie struktura zależności między kanałami core.async?

Kilka możliwych rozwiązań Natknąłem się

  • Prismatic's Graph - wydaje się rozsądne, chociaż nie testowałem go z core.async kanałów; fakt, że wymaga użycia fnk, jest dla mnie trochę zniechęcający, ponieważ wymaga zakupu w DSL dla definicji funkcji, ale jeśli to najlepsze rozwiązanie, to nie mam nic przeciwko.
  • Javelin cells - tylko dla ClojureScript (obecnie) i używa FRP zamiast CSP jako implementacji, ale wykonuje bardzo dobrą robotę polegającą na modelowaniu zależności między obliczeniami za pomocą komórek formuły.
  • - stworzone do obliczeń rozproszonych (jako konkurencja dla Apache Storm, itp.), Ale ma abstrakcję "workflow", która obsługuje zależności między obliczeniami i działa z core.async. Wydaje się to być najbliższym mojemu problematycznemu obszarowi, ale nie jestem pewien, czy potrzebuję nakładu wszystkich funkcji zarządzania klastrem.

Jakie jest rozwiązanie kanoniczne dla tego problemu?

Edit: dodano Onyx

+0

Czy [obietnica] (https: // clojuredocs.org/clojure.core/promise) działa? –

+0

Jakiś szczególny powód, dla którego nie uważasz odpowiedzi na twoje pytanie? –

Odpowiedz

1

nie sądzę jest kanoniczny sposób go rozwiązać, core.async jest tak nowy, że niewiele osób dały mu szansę. Gdybym miał wybierać między trzema opcjami, które zrobiłbym z wykresem, został on wdrożony i przetestowany w produkcji na pewien czas, a do uruchomienia go nie jest potrzebny Clojurescript. Jeśli interesuje Cię rozwiązanie FRP, spójrz na Java Reactive Extensions, powiązania Clojure dla niego istnieją w RxClojure.

1

Na to pytanie trudno odpowiedzieć, ponieważ w pytaniu brakuje szczegółowych informacji na temat przypadku użycia. Biblioteki takie jak Graph, Javelin i Onyx mają różne przypadki użycia, które wykraczają poza samo obliczanie zależności.

Jeśli chciałbyś mieć wątek lub przejść blok, zależy od wyników wygenerowanych w innej części systemu, sugerowałbym tylko użycie prymitywów core.async bez żadnych dodatkowych bibliotek.

Najbardziej podstawowym rozwiązaniem do wykonania oczekiwania na inny wątek aktywności jest użycie blokowania podczas pobierania wartości z kanałów. Spowoduje to zatrzymanie wątku (lub przejście do bloku), gdy na tym kanale nie będą dostępne żadne wartości.

Jak widać w poniższym przykładzie, wykonanie obliczenia zależy od aktywności wykonanej w innym wątku jest bardzo łatwe.

(let [c (chan)] 
    (thread (>!! c “hello”)) 
    (assert (= “hello” (<!! c))) 
    (close! c) 

Dostępne są również bardziej rozbudowane mechanizmy. Funkcja Alts!! zapewnia możliwość oczekiwania na wielu kanałach w tym samym czasie. Kilka różnych smaków funkcji pipeline umożliwia modelowanie współbieżności w sposób podobny do przepływu danych.

Czy napotkasz jakieś szczególne problemy, które nie mogą być jasno wyrażone za pomocą funkcji wbudowanych?

+0

Może to zamiast tego? (niech [c (chan)] (idź (> !! c "cześć")) (assert (= "cześć" ( ctpenrose

Powiązane problemy