как убить вычисление параллельной коллекции scala

я хочу использовать

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

Это должно вызывать f параллельно для создания коллекции c.

но я не контролирую функцию f.

для некоторых входных аргументов f имеет ошибку и переходит в бесконечный цикл.

Какой-то злой человек снаружи обнаружил такой аргумент данных, который использует ошибку в функции f. Затем они отправляют тонны их в систему как атаку типа «отказ в обслуживании».

Таким образом, даже если автор функции f отлично сотрудничает со мной, это функция, выполняющая сложные задачи и в ней могут быть ошибки.

Если у меня есть какой-то другой поток/актер/штучка, работающий рядом, то как он может остановить вычисления бесконечного цикла внутри создания параллельной коллекции?

И связанный с этим ... что, если я даже не знаю, что существует бесконечный цикл, но мой код просто берет ветвь, где он решает, что ему больше не нужен c, и удаляет все ссылки на мою параллельную коллекцию c выше. Будет ли вычисление продолжаться вечно или оно остановится, когда объект будет возвращен сборщиком мусора?


person Mike Beckerle    schedule 19.12.2013    source источник
comment
Пожалуйста, почините разбитое окно! не программируйте вокруг него!   -  person Stefan Kunze    schedule 19.12.2013
comment
Я должен добавить эту деталь: функция f — это чистая функция, без мутаций, без использования потоков/актеров/забавных дел. Но это пишет кто-то, кто работает в какой-то другой компании, а не я.   -  person Mike Beckerle    schedule 19.12.2013
comment
Я был недостаточно ясен. Я отредактировал вопрос, чтобы уточнить (надеюсь).   -  person Mike Beckerle    schedule 20.12.2013


Ответы (2)


Насколько мне известно, нет хорошего способа убить вычисление в функции map параллельного вычисления без того, чтобы вы сами не встроили средство генерирования InteruptException. Даже тогда, я не знаю, что, если вообще что-нибудь, это может привести. Однако, если бы вам пришлось это сделать...

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
  }
}

Затем сделайте следующее:

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

Это уродливо, многословно и подвержено ошибкам (ваша задача может быть завершена, но ошибка все равно может быть выдана!) Так что, если это «у меня нет другого выбора, кроме как сделать это», тогда сделайте это, но, пожалуйста, исправьте проблему с их стороны. Поднимите ад с их менеджером. Делайте все возможное, чтобы усложнить им жизнь. Я уверен, что у тебя есть, но...

person wheaties    schedule 19.12.2013
comment
Да, все говорят, что нужно сотрудничать с автором функции f, но вот сценарий: автор функции f полностью сотрудничает. Но снаружи какой-то злой человек вычислил, что отправив в систему особенно структурированный фрагмент данных, она вызовет ошибку в функции f и вызовет бесконечный цикл. Следовательно, атака типа «отказ в обслуживании» с отправкой большого количества таких сообщений приведет к сбою системы. Я хочу исключить эту возможность, всегда имея возможность убить параллельную активность. - person Mike Beckerle; 20.12.2013
comment
Я отредактировал исходный пост, так как предыдущий комментарий действительно соответствует всем ответам. - person Mike Beckerle; 20.12.2013
comment
Я собираюсь принять это решение. Он прекрасно инкапсулирует goop, поэтому мой код не слишком загроможден. Он использует только таймер, а не код потока, который делает предположения о том, как коллекции par используют потоки. Я думаю, что состояние гонки между f(that) и истечением времени таймера неизбежно при любом решении этой проблемы. - person Mike Beckerle; 20.12.2013

Как вы справляетесь с таким f в однопоточном контексте?

Java не предоставляет очень хороших возможностей для обработки незавершения. Лучшее, что вы обычно можете сделать, это обернуть нетерминатор в его собственный поток и вызвать (небезопасный!) метод Thread.stop. На сегодняшний день лучший вариант — вообще не иметь непрерывных f.

person Rex Kerr    schedule 19.12.2013
comment
Хорошая точка зрения. Тогда эта проблема не касается параллельной обработки. Я просто столкнулся с проблемой в этом контексте. - person Mike Beckerle; 20.12.2013