1

I have the following piece of code:

actor {
  loop {
     react {
       case SomeEvent =>
         //I want to submit a piece of work to a queue and then send a response 
         //when that is finished. However, I don't want *this* actor to block
         val params = "Some args"
         val f: Future[Any] = myQueue.submitWork( params );
         actor {
           //await here
           val response = f.get
           publisher ! response
         }

     }
  }
}

As I understood it, the outer actor would not block on f.get because that is actually being performed by a separate actor (the one created inside the SomeEvent handler).

Is this correct?

1 Answer 1

2

Yes, that is correct. Your outer actor will simply create an actor and suspend (wait for its next message). However, be very careful of this kind of thing. The inner actor is started automatically on the scheduler, to be handled by a thread. That thread will block on that Future (that looks like a java.util.concurrent.Future to me). If you do this enough times, you can run into starvation problems where all available threads are blocking on Futures. An actor is basically a work queue, so you should use those semantics instead.

Here's a version of your code, using the Scalaz actors library. This library is much simpler and easier to understand than the standard Scala actors (the source is literally a page and a half). It also leads to much terser code:

actor {(e: SomeEvent) => promise { ... } to publisher }

This version is completely non-blocking.

Sign up to request clarification or add additional context in comments.

8 Comments

But if I'm sending work to a queue and get a (juc) Future back, how can I avoid blocking in the case where I don't control the queue API (i.e. if I can't re-implement the work queue so that the publisher is given events upon work completing)?
Can you submit arbitrary code to the work queue? If so, you could submit a Unit-valued computation that ends by sending a message to one of your actors. And simply ignore the Future[Unit]
I've edited the question to make it a bit clearer exactly what I'm calling when I submitWork. Basically no, I can't submit arbitrary runnables/callables. However, I wrote all the code originally, so it looks like I'll just have to make an API change :-)
If the work queue is a Java API that you wrote, consider refactoring it with a Better Future: apocalisp.wordpress.com/2008/09/02/a-better-future
Also, consider that it might be OK to block in your case. If this system isn't highly concurrent, or if nothing will ever depend on the value in the Future.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.