I am a Scala newbie trying to understand Futures. I typed in the following in the REPL:
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> val m = Future(println("Message"))
Message
m: scala.concurrent.Future[Unit] = Future(<not completed>)
scala> Future(println("Another Message"))
res4: scala.concurrent.Future[Unit] = Future(<not completed>)
Another Message
In the first case I am assigning a Future computation to a variable m. I haven't called m yet but the Future actually produces the "Message" string output. But I also get a Future(<not completed>) message. What is going on here? Has the future completed or not? The string output tells me it has. Can somebody clear this up for me?
A Future will start executing as soon as it is created (Depending on the ExecutionContext implementation and assuming resources are available for it to run.)
The fact that you see your message printed to the console indicates your Futures have completed.
Try the following and see what happens:
Future{
Thread.sleep(5000)
println("Message")
}
It is completed, what you see Future(<not completed>) is just the `toString() from the Future.
try:
import scala.concurrent.ExecutionContext.Implicits.global
val f = scala.concurrent.Future{
println("Message")
}
println(f.toString())
Future execute always eagerly.
Related
I am following the instructions on the cats IO website to run a sequence of effects in parallel:
My code looks like:
val maybeNonEmptyList: Option[NonEmptyList[Urls]] = NonEmptyList.fromList(urls)
val maybeDownloads: Option[IO[NonEmptyList[Either[Error, Files]]]] = maybeNonEmptyList map { urls =>
urls.parTraverse(url => downloader(url))
}
But I get a compile time error saying:
value parTraverse is not a member of cats.data.NonEmptyList[Urls]
[error] urls.parTraverse(url => downloader(url))
I have imported the following:
import cats.data.{EitherT, NonEmptyList}
import cats.effect.{ContextShift, IO, Timer}
import cats.implicits._
import cats.syntax.parallel._
and also i have the following implicits:
implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)
implicit val timer: Timer[IO] = IO.timer(ExecutionContext.global)
Why do i still get the problem?
This is caused because the implicit enrichment is being imported twice, so it becomes ambiguous
import cats.implicits._
import cats.syntax.parallel._
As of recent versions of cats, implicits imports are never required, only syntax
The recommended pattern is to do only import cats.syntax.all._
I am trying to execute something like this
scala> import scala.sys.process._
scala> Process("cat temp.txt")!
I will be doing this say in a Play Framework REST handler. I want this to return a future object so that I can map/flatMap on it and do further processing when the shell is done executing. How do I do that?
I think all you need is this.
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.sys.process._
val fs = Future("cat temp.txt".!!) // Future[String] = Future(<not completed>)
The file contents becomes one long string but you can split() it in the map() operation.
I am trying to use scala Futures to implement a threaded bulk get from a network service key/value store.
roughly
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
def bulkGet(keys: List[String])
val listFut = keys.map( future{ "network get request here" } )
val values = Future.sequence(listFut)
Await.result(values, Duration(10, SECONDS))
gives me a compile error
[info] Compiling 1 Scala source to .../target/scala-2.10/classes...
[error] .... type mismatch;
[error] found : scala.concurrent.Future[List[String]]
[error] required: scala.concurrent.Awaitable[scala.concurrent.Future[List[String]]]
[error] Await.result(values, Duration(10, SECONDS))
^
what am I doing wrong.
I am following the docs re: how to block on a result
http://docs.scala-lang.org/overviews/core/futures.html
Is a scala.concurrent.Future not by definition Awaitable? How do I coerce it to be?
If I fix the syntax in your example code (by putting the body of the def into a block, and replacing future{ "network get request here" } with _ => Future{ "network get request here" }), this compiles and works. The problem is in some other part of the code.
Works for me.
$ scala
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_65).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.{Duration, SECONDS}
def bulkGet(keys: List[String]) = {
val listFut = keys.map(_ => Future("network get request here"))
val values = Future.sequence(listFut)
Await.result(values, Duration(10, SECONDS))
}
// Exiting paste mode, now interpreting.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.{Duration, SECONDS}
bulkGet: (keys: List[String])List[String]
scala> bulkGet(List("foo", "bar", "baz"))
res0: List[String] = List(network get request here, network get request here, network get request here)
Here is a basic example of using schedule in Akka:
import akka.pattern
import akka.util.Timeout
import scala.concurrent.Await
import akka.actor.Actor
import akka.actor.Props
import akka.actor.ActorSystem
import akka.pattern.ask
import scala.concurrent.duration
object Application extends App {
val supervisor = ActorSystem().actorOf(Props[Supervisor])
implicit val timeout = Timeout(10 seconds)
import system.dispatcher
supervisor.scheduler.scheduleOnce(120 seconds) {
val future = supervisor ? Supervisor.Start
val resultIdList = Await.result(future, timeout.duration).asInstanceOf[List[MyIdList]]
supervisor ! resultIdList
}
}
I'm really confused of Akka's documentation. Here Having problems with Akka 2.1.2 Scheduler ('system' not recognized) was said that import system.dispatcher is not a package import but something else. What is that then?
What is system? Do I have to replace it with supervisor? Even if I didn't do that and keep using system, I'd have pretty much the same errors:
//(using system)
value scheduler is not a member of akka.actor.ActorRef
not found: value system
//or (using supervisor)
not found: value system
not found: value system
Try this ;)
val system = ActorSystem()
val supervisor = system.actorOf(Props[Supervisor])
(Posting as answer since does not fit as comment)
Marius, you were referring to another question which started with this line:
val system = akka.actor.ActorSystem("system")
That is the identifier 'system' the import statement is referring to.
The line
import system.dispatcher
means that the dispatcher member of the variable system will be available in scope (you can use the name 'dispatcher' to refer to 'system.dispatcher' from that point). This also means that since dispatcher is an implicit that it will be now available for implicit resolution. Please note that the signature of schedule is
scheduleOnce(delay: FiniteDuration, runnable: Runnable)(implicit executor: ExecutionContext): Cancellable
So it either needs an explicitly passed ExecutionContext, or an implicit one. By using the import statement you bring the dispatcher (which is an ExecutionContext) into scope, so you don't have to provide it manually.
In scala 2.9.x I used tools.nsc.Global directly to compile certain string into a class and execute it.
In scala 2.10, it is possible to replace it with something like the following:
import scala.reflect.runtime._;
val cm = universe.runtimeMirror(getClass.getClassLoader)
import scala.tools.reflect.ToolBox;
val tb = cm.mkToolBox()
tb.eval(tb.parse("class C; new C"))
And it works flawlessly. The only problem is that with old (deprecated) approach, I could get extremely pretty summary of all compilation failures using StoreReporter (with error messages, line numbers), and new approach just throws an exception on compilation error.
Is there some way to reify that?
scala> import scala.reflect.runtime._
import scala.reflect.runtime._
scala> val cm = universe.runtimeMirror(getClass.getClassLoader)
cm: reflect.runtime.universe.Mirror = JavaMirror with ...
scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox
scala> val tb = cm.mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl#712fe0c0
scala> tb.eval(tb.parse("class C; new D"))
scala.tools.reflect.ToolBoxError: reflective compilation has failed:
not found: type D
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.throwIfErrors(ToolBoxFactory.scala:312)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal.compile(ToolBoxFactory.scala:248)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:407)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.eval(ToolBoxFactory.scala:410)
...
scala> tb.frontEnd.infos
res1: ... = Set(Info(NoPosition,not found: type D,ERROR))