缓存读取,使用SQL Alchemy立即写入

时间:2012-12-21 01:26:55

标签: python sqlalchemy

Beaker测试系统包括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处理这个问题有任何更好的想法。

1 个答案:

答案 0 :(得分:0)

在对此进行了一段时间的反思后,我意识到核心一致性问题在于,当系统完成任务时,它实际上在数据库中被标记为空闲,即使当前存在可以执行的排队配方那个系统。

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

因此,主调度循环最终只会处理分配当前处于空闲状态的系统的新配方的任务,而将排队配方分配给系统将更多地受事件驱动。

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