0
votes

I was working with Scala Actors to try implementing some scheduler algorithm.

The scheduler receives two functions which during their calculation call some "interact" function. For example:

def func1(x:Int, y:Int)(scheduler:MyScheduler):Int = {
   var z = 0
   if (scheduler.interact(1)) {
       return 7
   }
   z = x * y
   for (c <- 1 to 10) {
       if (scheduler.interact(z)) {
           return z
       }
       z = z * c
   }
   z
}

Now the scheduler needs to run both functions sequentially, and whenever an execution of a function reaches an "interact", the scheduler decides whether to let the same function continue or pause it and wake up the other function calculation.

You can think about it like running python generators, with a scheduler that decides which generator's next() to call every time.

I implemented this using Scala Actors - each function is executed in an actor, and the interact operation reply some value to the main thread (the scheduler) and calls "receive" to wait for a message from the main thread.

Notice that I cannot use "react" instead of "receive", because I need the execution to break out from the receive-block (and return from the "interact" function).

Then I thought to improve the implementation by making my actors run always on the main thread using SingleThreadedScheduler.

However, it seems that unlike "react", the "receive" function try to create a new thread which blocks the execution.

Is there something between "react" and "receive", in which the execution leave the block like in "receive" but avoid creating a new thread like in "react"? Or maybe I could limit the number of threads to 1 in some other way?

A-Posteriori I read about scala continuations, but this requires too many code changes (and you would agree that scala continuations is a little bit complex to use...).

Thanks

1

1 Answers

0
votes

This kind of challenge is evidence that the actor model is not always the right abstraction. As you say, continuations usually make things more complex and, for those reading your code, perhaps rather obscure even.

My own preference is to find a way to reason clearly about what the threads are actually going to be doing. Fortunately, this is possible using the excellent JCSP API (from UKC). Although this is a Java API, it works ok in Scala too, and is mature and stable (there is an Oxford Uni pure Scala project but this may not be mature yet). JCSP implements Hoare's CSP, a mathematical algebra but which is easy to use once you realise it's event driven. Actors can easily be modelled in JCSP but not vice versa.

In your application, your scheduler will have its own CS-Process (aka Java thread) and will determine its own state and lifecycle based on the events it receives. That allows it to invoke the two functions in sequence, not overlapped concurrently, yet be part of a wider suite of thread activity.

http://www.cs.kent.ac.uk/projects/ofa/jcsp/ provides the background materials. The jar is at http://mvnrepository.com/artifact/org.codehaus.jcsp/jcsp