CCR:使用因果关系处理错误的最佳实践

发布于 2024-07-29 17:19:48 字数 1076 浏览 9 评论 0原文

对于复杂的任务序列,在对每个小任务使用 try/catch 块和 PortSet 上的 Choice 接收器等内容时,实现错误处理会很快使代码变得臃肿。

值得庆幸的是,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 来实现分散/聚集场景,将“作业”拆分为一堆并行任务。 (除此之外,这些作业中的多个可以同时运行。)如果一项任务失败,我想停止该作业中的所有剩余任务,但不停止任何其他作业。 (如果我遗漏了一块拼图,结果对我来说毫无用处,因此继续解决这个问题只会浪费 CPU 时间。)

问题是实现停止的最佳方法是什么。

一种想法是:

  1. 创建一个 Dispatcher 实例并在应用程序生命周期内保留它。
  2. 为每个“作业”(一组任务)创建一个新的 DispatcherQueue。 创建 DispatcherQueue 后立即添加 Causality
  3. 在异常队列的处理程序中,对 DispatcherQueue 调用 Suspend()
  4. 在处理调度程序队列之前,请删除因果关系。

我想知道这个建议是否可以被视为最佳实践,或者是否有更好的方法来处理这种可能相当常见的情况。

Having a complex sequence of tasks, implementing error handling can quickly bloat the code when using try/catch blocks and stuff like Choice receivers on PortSet<ActualResult, Exception> for every little task.

Thankfully the CCR seems to offer a mechanism to handle exceptions in a more general way for a graph of tasks: causalities. A typical example looks like this:

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

In my case, I have a computing intensive application using the CCR to implement a scatter/gather scenario, splitting "jobs" into a bunch of parallelized tasks. (Besides that, more then one of these jobs can run at the same time.) In case that one task fails, I want to to stop all the remaining tasks in the job, but not any other job. (The results are of no use to me if I'm missing a piece of the puzzle, so continuing to work on this would be just a waste of CPU time.)

The question is what the best way would be to implement the stopping.

One idea would be:

  1. Create one single Dispatcher instance and keep it over application lifetime.
  2. Create a new DispatcherQueue for every "job" (a group of tasks). Add the Causality immediately after creating the DispatcherQueue.
  3. In the handler for the exception queue, call Suspend() on the DispatcherQueue.
  4. Before disposing the dispatcher queue, remove the causality.

I wonder if this suggestion can be regarded best practice, or if there is a better approach to deal with such a - probably fairly common - scenario.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黑凤梨 2024-08-05 17:19:48

对我来说这似乎是一个很好的方法。

Seems like a good way to way to go about it to me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文