Easiest way to do idle handling in Scala Actor?

I have a scala actor that does some work when a client requests it. When and only when no client is active, I would like the Actor to do some background processing.

What's the easiest way to do this? I can imagine two approaches:

  • Create a new thread that wakes up and wakes up periodically. Direct approach, but I would like to avoid creating another thread (to avoid unnecessary code, complexity and overhead).

  • The Actor class has a responseWithin method that can be used to timeout the actor itself. But the documentation says the method doesn't return. So, I'm not sure how to use it.

Edit; clarification:

Suppose a background task can be broken down into smaller units that can be independently processed.

+2


source to share


3 answers


Okay, I see I need to bet 2 cents. From the author's answer, I think that "priority admission" technology is exactly what is needed here. In the section, you can find the discussion "Erlang: Priority to get a question here on SO ". The idea is to accept high priority messages first and only accept other messages when there are no high priority messages.

As Scala actors are very similar to Erlang, the trivial code to implement this would look like this:



def act = loop {
  reactWithin(0) {
    case msg: HighPriorityMessage => // process msg
    case TIMEOUT =>
      react {
        case msg: HighPriorityMessage => // process msg
        case msg: LowPriorityMessage => // process msg
      }
  }
}

      

It works like this. The actor has a mailbox (queue) with messages. The argument receive

(or receiveWithin

) is a partial function, and the Actor library looks for a message in the mailbox that can be applied to that partial function. In our case, it would be an object only HighPriorityMessage

. So, if the Actor library finds such a message, it applies our partial function and we process the high priority message. Otherwise, reactWithin

with a timeout of 0, it calls our partial function with an argument TIMEOUT

, and we immediately try to process any possible message from the queue (since it is waiting for a message, we cannot rule out the possibility of receiving HighPriorityMessage

).

+6


source


It looks like the problem you are describing does not apply to the actor subsystem . Actor

designed for sequential processing of the message queue:

  • What happens if an actor completes a background task and a new task arrives?

The actor can only find out about it, he constantly checks it mailbox

, performing a background task. How would you implement this (for example, how would you code background tasks as a unit of work so that the actor can keep interrupting and checking the mailbox)?



  • What happens if the actor has many background tasks in the mailbox before the main task?

Are these background tasks removed or sent to another actor? If the latter, how can you prevent the cpu time for this actor to complete tasks?

All in all, this sounds a lot more like you need to learn some kind of networking software that can run in the background (like Data Synapse)!

+2


source


Just after I asked this question, I tried some totally weird code and it seems to work fine. I'm not sure though if there is a gotcha in it.

import scala.actors._

object Idling

object Processor extends Actor {
  start

  import Actor._

  def act() = {
    loop {

      // here lie dragons >>>>>
      if (mailboxSize == 0) this ! Idling
      // <<<<<<

      react {
        case msg:NormalMsg => {
          // do the normal work
          reply(answer)
        }

        case Idling=> {
          // do the idle work in chunks
        }

        case msg => println("Rcvd unknown message:" + msg)
      }

    }
  }
}

      

Explanation

Any code inside an argument loop

but prior to the call react

seems to be called when the Actor is waiting for a message. I am posting a message Idling

for myself here. In the handler for this message, I guarantee that the mailbox size is 0 before doing the processing.

+2


source







All Articles