2016-11-04 10 views
0

ある種のID /スレッドオブジェクトの参照を使用してスレッドが実行されているかどうかを調べる方法はありますか。スレッドが実際に特定の時刻に実行されているかどうかを知ることができます。Pythonスレッド:アプリケーションを再起動してもスレッドを追跡できますか?

私は、スレッドモードのアプリケーションで製造プロセスを開始する機能を持っています。サーバーの再起動がなく、何も間違っていない場合は、すべてがバックグラウンドで正常に完了します。

しかし、たとえばサーバが再起動され、スレッドが実行されていたときには、それらはうまくいっても終了しますが、スレッドの完了後にのみ変更されるため、

私はこれらの製造指図をチェックする予定のスケジューラを考えていましたが、製造指図を実行するための関連スレッドが見つからなければ、それは死んでいるとみなされ、再起動する必要があります。

どうすれば適切に追跡できますか?

私はこのコードを持っている:jobが作成された場合、何かがうまくいかないとき

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() 

は、だから今の部分で、それが立ち往生することができます。それはもうデータベースで更新されないので、「実行中」の状態で立ち往生します。

スレッドの寿命を追跡するシングルトンクラスを使用する必要があります。そのため、定期的に実行されるcronジョブをチェックして、実際に実行されているスレッドと予期せず殺されたスレッドを判断できます。

P.S.おそらくそれを行うためのいくつかの良い習慣があります、もしそうなら、アドバイスをしてください。

+0

私はあなたのスクリプトが完全に消去された場合( 'kill -9'と言う)、スレッドの状態を知る唯一の方法は、それらのスレッド彼らの進歩を書いている...どこか(ファイル、データベース...) – BorrajaX

答えて

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

関連する問題