Wonay
Wonay

Reputation: 1250

Stream with value changing from outside input

I want to do

while(isRunning) {
   // do something
}

And be able from another thread to do isRunning = false and the above loop to stop.

However, I would like to do that in a more scala-like way.

One approach that I tried is :

object Watcher {
  var run: Boolean = true
  def getIsRunning: Stream[Boolean] = {
    { Thread.sleep(1000); run } #:: getIsRunning
  }
}

And then I was going to do:

Watcher.getIsRunning.takeWhile { isRunning => 
  if (isRunning) { 
     println("I am running")
  } else {
     println("I am not running")
  }
  isRunning
}

But it ( now obviously ) does not work because takeWhile return another stream and does not behave like a while loop which re-evaluate the value of run every time.

Is there a way to do what I want?

Upvotes: 1

Views: 39

Answers (1)

Dima
Dima

Reputation: 40510

I am not sure what you are referring to by "now obviously" ... it's not obvious to me why you think this should not work (in fact, I think, it should). I don't quite see why it needs to be so complicated (and what's wrong with a while loop), but functionally, there doesn't seem anything wrong with it ...

Another (arguably, even more "scala-like") way to do it, is using futures:

   def whileRunning(f: => Unit): Future[Unit] = Future(f).flatMap {
     case _ if isRunning => whileRunning(f)
     case _ => Future.successful
   }         

Now, you can do whileRunning(doWork) ... and it's not blocking, so you can actually do isRunning=true some time later (make sure it's @volatile).

Upvotes: 3

Related Questions