2013-08-01 13 views
5

Buduję bibliotekę, która w ramach swojej funkcjonalności wysyła żądania HTTP. Aby to działało w wielu środowiskach, które będzie wdrażane, chciałbym móc pracować z Futures lub bez.Syncronous Scala Przyszłość bez osobnego wątku

Jedną z opcji jest skonfigurowanie przez bibliotekę typu jej typu odpowiedzi, aby można było utworzyć instancję biblioteki o typie Future lub instancję typu Id, w zależności od tego, czy używana jest asynchroniczna implementacja protokołu HTTP. (Id może być monadą Identity - wystarczającą do ujawnienia użytkownikom spójnego interfejsu)

Zacząłem od tego podejścia, ale jest skomplikowane. Zamiast tego chciałbym użyć wszędzie typu Future, w razie potrzeby boksując odpowiedzi synchroniczne w przyszłości. Rozumiem jednak, że korzystanie z kontraktów Futures zawsze pociąga za sobą pewien rodzaj wątku. To nie będzie latać w np. AppEngine (wymagane środowisko).

Czy istnieje sposób na stworzenie przyszłości z wartości, która zostanie wykonana na bieżącym wątku, a zatem nie spowoduje problemów w środowiskach, w których nie jest możliwe odrodzenie wątków?

(ps jako dodatkowy wymóg, muszę być w stanie przejechać zbudować bibliotekę z powrotem do Scala v2.9.1, które mogłyby ograniczyć funkcje dostępne w scala.concurrent)

+1

'Czy istnieje sposób na stworzenie przyszłości z wartości, która będzie być wykonane na bieżącym wątku 'Dlaczego warto korzystać z przyszłości? – Jatin

+0

Jak wyjaśniam, aby utworzyć spójny typ zwrotu w implementacjach – adamnfish

+1

Przykro mi, że nie zrozumiałem tego pytania. Jeśli masz na myśli, że masz już końcową wartość wyniku i potrzebujesz dla niego przyszłego opakowania, to może skorzystasz z 'Obietnicy'? – Jatin

Odpowiedz

3

Z tego co rozumiem chcesz wykonaj coś, a następnie zawiń wynik za pomocą Future. W takim przypadku, zawsze można użyć Promise

val p = Promise[Int] 
p success 42 
val f = p.future 

Stąd masz teraz future opakowanie zawierające ostateczną wartość 42

obietnica jest bardzo dobrze wyjaśnione here.

+0

Ach, oczywiście, dziękuję! Fantastyczny link również. Problem polega na tym, że nadal musisz dostarczyć ExecutionContxt (implicite lub w inny sposób). Nie jest dla mnie jasne, czy podany Kontekst Wykonawczy faktycznie zostanie użyty z tą metodą obietnicy, ale tak czy inaczej, to kończy się jak sprawdzane wyjątki w Javie, z kontekstem, który musi być zawarty w całej aplikacji, która pochłania przyszłość. – adamnfish

+3

Ponadto, obiekt Obietnica zawiera metodę, aby zrobić to nieco bardziej zwięźle: "Obiecuj pomyślny (42) .future". – adamnfish

+0

@adamnfish Nie potrzebujesz ExecutionContext dla powyższego bitu kodu. Nie zgłaszamy żadnej przyszłości gdziekolwiek. Myślę, że się z tym mylicie. Wystarczy "import scala.concurrent._". Proszę również zaakceptować odpowiedź, jeśli myślisz, że to odpowiada :) – Jatin

1

Wykonaj look w Scalaz wersji Future. Jest to oparte na mechanizmie Trampoline, który będzie wykonywany przez bieżący wątek, chyba że fork lub apply nie zostanie wywołane +, które całkowicie usuwa wszystkie importu ExecutionContext =)

+0

Bardzo interesujące podejście, bardzo dziękuję. Wolałbym nie uwzględniać scalazu (zwłaszcza, że ​​najnowsza wersja nie została stworzona do wersji 2.9.1), ale zlikwidowanie importu ExecutionContext byłoby tutaj bardzo przydatne. – adamnfish

Powiązane problemy