CCR: лучшая практика для обработки ошибок с использованием причинно-следственных связей

Имея сложную последовательность задач, реализация обработки ошибок может быстро раздуть код при использовании блоков try/catch и таких вещей, как приемники Choice на PortSet<ActualResult, Exception> для каждой маленькой задачи.

К счастью, CCR, кажется, предлагает механизм для обработки исключений в более общем виде для графика задач: причинно-следственные связи. Типичный пример выглядит так:

Port<Exception> exceptionPort = new Port<Exception>();
Dispatcher.AddCausality(new Causality("some job", exceptionPort));
Arbiter.Activate(
  dispatcherQueue,
  Arbiter.Receive(false, exceptionPort, ex => Console.WriteLine(ex)));
// now schedule the real tasks

В моем случае у меня есть вычислительное приложение, использующее CCR для реализации сценария разброса / сбора, разделяющего "задания" на кучу распараллеленных задач. (Кроме того, одновременно может быть запущено более одного из этих заданий.) В случае сбоя одного задания я хочу остановить все оставшиеся задания в задании, но не любое другое задание. (Результаты бесполезны для меня, если мне не хватает части головоломки, поэтому продолжение работы над этим будет просто пустой тратой процессорного времени.)

Вопрос в том, как лучше всего осуществить остановку.

Одна идея будет:

  1. Создать один Dispatcher экземпляр и сохранить его в течение всего срока службы приложения.
  2. Создать новый DispatcherQueue за каждую "работу" (группу задач). Добавить Causality сразу после создания DispatcherQueue,
  3. В обработчике очереди исключений вызовите Suspend() на DispatcherQueue,
  4. Перед удалением очереди диспетчера удалите причинно-следственную связь.

Интересно, можно ли считать это предложение лучшей практикой или есть лучший подход для решения такого, вероятно, довольно распространенного сценария.

1 ответ

Похоже, это хороший способ для меня.

Другие вопросы по тегам