有没有办法通过使用某种线程对象的ID /引用来跟踪线程是否正在运行,所以我会知道线程是否真的在某个特定时间运行。
我的功能可以在线程模式下启动应用程序上的制造流程。如果没有服务器重启并且没有出错,则一切都在后台正常完成。
但是,如果例如服务器重新启动,并且当任何线程正在运行时,它们将被杀死,但是某些订单的生成停留在运行状态,因为它仅在线程完成后才会更改。
我在想一些会检查这些生产订单的调度程序,如果它找不到运行生产订单的相关线程,那么它会认为它已经死了,必须重新启动。
但我怎样才能正确追踪?
我有这段代码:
from threading import Thread
def action_produce_threaded(self):
thread = Thread(target=self.action_produce_thread)
thread.start()
return {'type': 'ir.actions.act_window_close'}
def action_produce_thread(self):
"""Threaded method to start job in background."""
# Create a new database cursor.
new_cr = sql_db.db_connect(self._cr.dbname).cursor()
context = self._context
job = None
with api.Environment.manage():
# Create a new environment on newly created cursor.
# Here we don't have a valid self.env, so we can safely
# assign env to self.
new_env = api.Environment(new_cr, self._uid, context)
Jobs = self.with_env(new_env).env['mrp.job']
try:
# Create a new job and commit it.
# This commit is required to know that process is started.
job = Jobs.create({
'production_id': context.get('active_id'),
'state': 'running',
'begin_date': fields.Datetime.now(),
})
new_cr.commit()
# Now call base method `do_produce` in the new cursor.
self.with_env(new_env).do_produce()
# When job will be done, update state and end_date.
job.write({
'state': 'done',
'end_date': fields.Datetime.now(),
})
except Exception as e:
# If we are here, then we have an exception. This exception will
# be written to job our job record and committed changes.
# If job doesn't exist, then rollback all changes.
if job:
job.write({
'state': 'exception',
'exception': e
})
new_cr.commit()
new_cr.rollback()
finally:
# Here commit all transactions and close cursor.
new_cr.commit()
new_cr.close()
所以现在在创建job
的部分,当出现问题时它会卡住。它将停留在“运行”状态,因为它不再在数据库中更新。
我是否应该使用一些可以在生命周期内跟踪线程的单例类,因此一些定期运行的cronjob可以检查它并确定哪些线程正在运行以及哪些线程被意外杀死?
P.S。可能有一些很好的做法,如果是这样,请建议。
答案 0 :(得分:0)
我能够通过编写单例类来解决这个问题。现在它跟踪实时线程,如果服务器重新启动,所有对活动线程的引用都将消失,我再也找不到它了(只有新启动才会找到)。所以我肯定知道哪些线程已经死了,可以安全地重启,哪些线程不能。
我不知道这是否是解决此类问题的最佳方法,但现在是:
class ObjectTracker(object):
"""Singleton class to track current live objects."""
class __ObjectTracker:
objects = {}
@classmethod
def add_object(cls, resource, obj):
"""Add object and resource that goes it into class dict."""
cls.objects[resource] = obj
@classmethod
def get_object(cls, resource):
"""Get object using resource as identifier."""
return cls.objects.get(resource)
@classmethod
def pop_object(cls, resource):
"""Pop object if it exists."""
return cls.objects.pop(resource, None)
instance = None
def __new__(cls):
"""Instantiate only once."""
if not ObjectTracker.instance:
ObjectTracker.instance = ObjectTracker.__ObjectTracker()
return ObjectTracker.instance
def __getattr__(self, name):
"""Return from singleton instance."""
return getattr(self.instance, name)
def __setattr__(self, name):
"""Set to singleton instance."""
return setattr(self.instance, name)
P.S。这被用作我的单身人士的起始示例:http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Singleton.html#id4