Python线程:即使在重新启动应用程序后跟踪线程?

时间:2016-11-04 15:21:28

标签: python multithreading object

有没有办法通过使用某种线程对象的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。可能有一些很好的做法,如果是这样,请建议。

1 个答案:

答案 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