烧杯测试系统包括一个central scheduler,它根据配方中定义的各种标准将排队的配方分配给可用的系统。
这是通过不断循环当前食谱队列并寻找可以处理该食谱的可用系统来处理的。当这种方法查询从数据库中检索每个配方的更新的系统状态信息时,它受到竞争条件的影响,其中队列中更靠后的任务有时不正确地在调度通道正在运行时变为可用的系统上给出第一次机会。
例如,假设我们有2个系统A和B,以及配方1(需要系统A)、2(可以在任何一个系统上运行)、3(也可以在任何一个系统上运行)。当调度过程开始时,系统A已经很忙,所以配方1没有可用的系统,我们继续查看配方2并将其分配给系统B。在后台,系统A完成它正在做的事情,并在数据库中将自己标记为可用。调度器现在继续考虑配方3,看到系统A可用,并将配方3分配给系统A。配方3设法跳过队列并声明系统A,即使配方1应该被给予它。
我正在尝试提出一个近期的解决方案,而不涉及完全重新设计调度逻辑(尽管我们也在探索这方面的一些长期想法)。
我目前最好的解决方案是打开一个单独的SQL Alchemy会话,作为调度过程开始时数据库状态的缓存,以及调度器所做的任何系统可用性状态更改。该事务将在调度过程结束时中止。在调度过程中,所有状态更改都将照常写入数据库,但也需要写入缓存连接。
这看起来真的很难看,所以我想知道是否有人有更好的想法来使用SQL Alchemy来处理这个问题。
发布于 2012-12-21 16:35:45
在思考了一段时间后,我意识到核心的一致性问题在于,当系统完成一项任务时,它实际上在数据库中被标记为空闲,即使当前有排队的配方可以在该系统上执行。
相反,我们需要做的是确保如果有配方可以在该系统上执行,系统会立即重新分配给队列中的第一个这样的配方,而不是永远放回空闲池中。类似地,如果添加了新系统或将其重新置于自动模式,则我们会立即为其分配一些工作,而不是让它进入空闲池。
因此,主调度循环最终将只处理将进入的新配方分配给当前空闲的系统的任务,而将排队配方分配给系统将更多地由事件驱动。
https://stackoverflow.com/questions/13983067
复制相似问题