2011-09-18 67 views
2

生产者线程查询数据存储并将对象放入队列中。然后,每个消费者线程将从共享队列中拉出一个对象,并对外部服务进行非常长的调用。当呼叫返回时,消费者将该对象标记为已完成。如何防止共享队列中的重复值

我的问题是,我基本上必须等到队列为空之后,制作人才能再次添加它,否则我可能会让重复的邮件通过。

有人问IRC一个很好的问题,我想我会在这里添加答案。问题是,“为什么你的制作人制作重复?”答案基本上是制片人制作重复片,因为我们不跟踪每个对象的“发送”状态,只有“发送”或“未发送”。

有没有一种方法可以检查队列中的重复项?

回答

2

在我看来,在队列中有重复的对象并不是一个真正的问题;你只是想确保你只对每个对象执行一次处理。

如果是这样,我建议你有消费者线程使用一组来跟踪已经发现的对象。如果一个对象不在集合中,添加并处理它;如果它在集合中,则将其忽略为重复。

如果这将是一个长时间运行的系统,而不是一个集合,请使用OrderedDict跟踪所查看的对象。然后不时清理OrderedDict中最旧的条目。

0

你是指将对象标记为已完成是什么意思?你是否将对象留在队列中并更改标志?或者你的意思是你将对象标记为已经在数据存储中完成。如果前者,队列是如何变空的?如果是后者,为什么不在开始处理之前从队列中删除对象?

假设您希望能够处理处理失败而不丢失数据的情况,一种方法是创建一个单独的工作队列和处理队列。然后,当消费者从工作队列中抽取工作时,他们将其移至处理队列,并开始对外部服务的长时间运行呼叫。当它返回时,它可以标记数据完整并将其从处理队列中移除。如果为数据放入处理队列时添加字段,则可能会运行定期作业来检查超过特定时间的处理作业并尝试重新处理它们(在重新启动之前更新时间戳记)。

1

如果您在Queue模块中讨论类:在API之后,无法检测队列是否包含给定对象。