1

Beaker 测试系统包括一个中央调度程序,它根据配方中定义的各种标准将排队的配方分配给可用系统。

这是通过不断循环当前的配方队列并寻找可以处理该配方的可用系统来处理的。当这种方法查询从数据库中为每个配方检索更新的系统状态信息时,它会受到竞争条件的影响,即在队列中更靠后的任务有时会错误地在调度过程运行时可用的系统中进行第一次尝试。

例如,假设我们有 2 个系统 A 和 B,以及配方 1(需要系统 A)、2(可以在任一系统上运行)、3(也可以在任一系统上运行)。当调度通道开始时,系统 A 已经很忙,所以配方 1 没有可用的系统,我们继续查看配方 2 并将其分配给系统 B。在后台,系统 A 完成它正在做的事情并将自己标记为在数据库中可用。调度程序现在继续考虑方案 3,发现系统 A 可用并将方案 3 分配给系统 A。方案 3 已设法跳过队列并要求系统 A,即使方案 1 应该已获得它。

我正在尝试为此提出一个近期解决方案,该解决方案不涉及完全重新设计调度逻辑(尽管我们也在这方面探索一些更长期的想法)。

我目前拥有的最佳解决方案是打开一个单独的 SQL Alchemy 会话,纯粹作为调度过程开始时数据库状态的缓存,以及调度程序所做的任何系统可用性状态更改。此事务将在调度过程结束时中止。在调度过程中,所有状态更改都将照常写入数据库,但也需要写入缓存连接。

不过这看起来真的很难看,所以我想知道是否有人对如何使用 SQL Alchemy 处理这个问题有更好的想法。

4

1 回答 1

0

经过一段时间的思考,我意识到核心一致性问题在于,当系统完成任务时,它实际上在数据库中被标记为空闲,即使当前有队列中的配方可以在该系统上执行。

相反,我们需要做的是确保如果有可以在该系统上执行的配方,系统会立即重新分配给队列中的第一个这样的配方,而不是被放回空闲池中。同样,如果添加新系统或将其重新置于自动化模式,那么我们会立即为其分配一些工作,而不是让它进入空闲池。

因此,主调度循环最终将仅处理将进入当前空闲系统的新配方分配的任务,而将排队的配方分配给系统将更多地是事件驱动的。

那时,管理对数据库的并发访问以确保两个系统不会开始尝试处理相同的配方,这只是一个典型的问题。

于 2012-12-21T08:35:45.123 回答