我正在使用带有 python 的应用程序引擎
我每天都有一系列值(value)观任务要做。这些值存储在目标属性下的“项目”值中:
myproject1.targets=['foo','bar','foo2','bar2','foo3','bar3','foo4','bar4','foo5','bar5']
我的目标是对每个值的 url: url_to_my_worker
进行排队调用,并以该值作为参数。
我的数据库中目前只有一个项目对象。
我运行schedule_daily_projects_tasks,它基本上为每个配置文件对象排队schedule_daily_profile_tasks
class schedule_daily_projects_tasks(webapp.RequestHandler):
def post(self):
key=self.request.get('key')
pro=project.get(key)
profiles=my_profile.gql("WHERE project=:1",pro)
logging.info(profiles)
for profile in profiles:
taskqueue.add(url='/control/schedule_daily_profile_tasks', params={'key': profile.key()})
然后为每个配置文件运行“schedule_daily_profile_tasks”。
class schedule_daily_profile_tasks(webapp.RequestHandler):
def post(self):
key=self.request.get('key')
profile=my_profile.get(key)
pro=profile.project
for i in range(1, 6):
now=datetime.now()
tim=datetime(year=now.year, month=now.month, day=now.day, hour=8+i)
screen_name=pro.targets.pop()
taskqueue.add(url='/url_to_my_worker', params={'profk': key, 'screen_name':screen_name}, eta=tim)
pro.put()
假设我的数据库中有 5 个配置文件对象:profile1 到 profile5 因此,如果一切顺利,我应该有 5 个任务排队到 url '/url_to_my_worker',并带有参数:
1) params={'profk': profile1.key(), 'screen_name':'bar5'}
2) params={'profk': profile2.key(), 'screen_name':'foo5'}
3) params={'profk': profile3.key(), 'screen_name':'bar4'}
4) params={'profk': profile4.key(), 'screen_name':'foo4'}
5) params={'profk': profile5.key(), 'screen_name':'bar3'}
但相反,我得到:
1) params={'profk': profile1.key(), 'screen_name':'bar5'}
2) params={'profk': profile2.key(), 'screen_name':'bar5'}
3) params={'profk': profile3.key(), 'screen_name':'bar5'}
4) params={'profk': profile4.key(), 'screen_name':'bar5'}
5) params={'profk': profile5.key(), 'screen_name':'bar5'}
我认为任务运行得太快,因此 n°2 在 n°1 “弹出”之前开始。因此 myproject1.targets 具有相同的值。
如何确保列表中的每个值仅使用一次?
非常感谢
最佳答案
您遇到的问题或多或少如您所描述的那样:您已将多个尝试同时修改同一数据存储对象的任务排入队列。由于您没有使用事务,因此多个任务最终会检索相同的数据,执行相同的操作,然后覆盖彼此的结果。
您可以使用数据存储事务来避免这种情况,但更好的解决方案是重组您的任务,以便只有一个任务正在修改每个数据存储实体。这样,您就无需担心同步或事务问题。
关于python - 处理带有排队任务的列表。如何确保列表中的每个值仅使用一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11492864/