A little help on understanding Scalaz Future and Task
Asked Answered
T

4

17

I'm trying to understand the idea and purpose behind scalaz concurrent package, primarily Future and Task classes, but when using them in some application, it's now far from simple sequential analog, whereas scala.concurrent.Future, works more then better. Can any one share with his experience on writing concurrent/asynchronous application with scalaz, basically how to use it's async method correctly? As i understand from the sources async doesn't use a separate thread like the call to standard future, or fork/apply methods from scalaz works, so why it is called async then? Does it mean that in order to get real concurrency with scalaz i always have to call fork(now(...)) or apply?

Te answered 30/10, 2013 at 19:52 Comment(0)
D
17

I'm not a scalaz expert, but I'll try to help you a little bit. Let me try answer your questions one by one:

1) Can any one share with his experience on writing concurrent/asynchronous application with scalaz, basically how to use it's async method correctly?

Let's first take a look at async signature:

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

This could be a bit cryptic at first, so as always it's good idea to look at tests to understands possible use cases. In https://github.com/scalaz/scalaz/blob/scalaz-seven/tests/src/test/scala/scalaz/concurrent/FutureTest.scala you can find the following code:

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

As we know from signature Future.async just construct new Future using function of signature (A => Unit) => Unit. What this really means is that Future.async takes as parameter function which for given callback makes all required computations and pass the result to that callback.
What is important to note it that Future.async does not run any computations on itself, it only prepare structure to run them later.

2) As i understand from the sources async doesn't use a separate thread like the call to standard future, or fork/apply methods from scalaz works, so why it is called async then?

You are correct. Only fork and apply seems to be running anything using threads, which is easy to notice looking at the signatures which contains implicit pool: ExecutorService. I cannot speak for the authors here, but I guess async is related to the callback. It means that rather than blocking on Future to get it result at the end you will use asynchronous callback.

3) Does it mean that in order to get real concurrency with scalaz i always have to call fork(now(...)) or apply?

From what I can say, yes. Just notice that when you are creating Future using syntax Future(x) you are using apply method here, so this is kind of default behavior (which is fine).

If you want to better understand design of Scalaz Futures I can recommend you reading "Functional Programming in Scala". I believe this book is written by main Scalaz contributors and chapter 7 discusses designing API for purely functional parallelism library. It's not exactly the same as Scalaz Future, but you can see many similarities.

Drafty answered 28/12, 2013 at 12:28 Comment(0)
A
2

You can also read wonderful Timothy Perrett blog post about Scalaz Task and Future which covers many not so obvious details.

Atheling answered 2/12, 2014 at 13:24 Comment(0)
E
1

async is used to adapt an async, callback-based API as a Future. It's called async because it's expected that it will be used with something that runs asynchronously, perhaps calling the callback from another thread somewhere further down the line. This is "real" concurrency, provided the API you're calling really uses it asynchronously (e.g. I use Future.async with the async parts of the AWS SDK like AmazonSimpleDBAsyncClient).

If you want "real" concurrency from the scalaz Task API directly you need to use things like fork or gatherUnordered, as many of the APIs default towards being safe/deterministic and restartable, with concurrency only when explicitly requested.

Enrich answered 2/12, 2014 at 13:33 Comment(0)
T
1

When composing Tasks with map and flatMap you can get a performance win by not using fork, see:

http://blog.higher-order.com/blog/2015/06/18/easy-performance-wins-with-scalaz/

Twoseater answered 6/1, 2016 at 14:6 Comment(1)
This answer could be improved by referencing the blog but including the relevant information here. There's no way to rely on a blog existing in the future.Femme

© 2022 - 2024 — McMap. All rights reserved.