how to kill computation of a scala parallel collection

368 views Asked by At

I want to use

val c = collection.par.map{ f(_) }

This should call f in parallel to create collection c.

but, I am not in control of function f.

for some input arguments, f has a bug and goes into an infinite loop.

Some evil person outside has discovered this kind of data argument that exercises the bug in function f. So they then submit tons of them to the system as a denial-of-service attack.

So, even if I have perfect cooperation from the author of function f, it is a function doing complicated things and can have bugs.

If I have some other thread/actor/thingy running along side, then how can it stop the calculations of the infinite loop inside the creation of the parallel collection?

And related... what if I don't even know there is an infinte loop, but my code just takes a branch where it decides it no longer needs c at all, and drops all reference to my parallel collection c above. Will the computation go on forever, or will it stop when the object is reclaimed by GC?

2

There are 2 answers

3
wheaties On BEST ANSWER

As far as I'm aware, there is no good way to kill a computation within the map function of a parallel computation without you, yourself, building in a means of throwing an InteruptException. Even then, I do not know what, if anything, that might accomplish. However, if you had to do so...

class MyInteruptableFunction[+A,-B](f: A => B, waitCap: Long) extends (A => B){
  def apply(that: A) ={
    val timer = new Timer
    timer schedule (new MyTaskThatThowsAnException, waitCap)
    val out = f(that)
    timer cancel ()
    out
  }
}

Then do this:

val c = collection.par.map{ new MyInterruptableFunction(f, 42) } //42 is the answer!

It's ugly, verbose, and error prone (your task can complete and still the error can be thrown!) So if it's an "I have no choice but to do this" then do it but please, fix the problem on their end. Raise hell with their manager. Do everything you can to make their lives difficult. I'm sure you have but...

1
Rex Kerr On

How do you deal with such an f in a single-threaded context?

Java doesn't provide very good options for handling non-termination. The best you can usually manage is to wrap the non-terminator in its own thread and call the (unsafe!) Thread.stop method. By far the superior option is to not have non-terminating fs in the first place.