2017-07-10 13 views
1

私はPythonとDjangoの新機能ですので、これを行うより良い方法があれば教えてください。私がしようとしているのは、各Device(models.Modelから継承)が長時間実行されているバックグラウンドスレッドを起動して、そのデバイスの正常性を常にチェックすることです。しかし、私のコードを実行すると、デーモンのように実行されているようには見えません。サーバーは遅くて絶えずタイムアウトしています。このバックグラウンドスレッドは(ほとんどの場合)プログラムの寿命を延ばします。以下は Djangoモデルで長時間実行されているバックグラウンドスレッド

は、私のコードの簡易版である:

class Device(models.Model): 
    active = models.BooleanField(default=True) 
    is_healthy = models.BooleanField(default=True) 
    last_heartbeat = models.DateTimeField(null=True, blank=True) 

    def __init__(self, *args, **kwargs): 
     super(Device, self).__init__(*args, **kwargs) 
     # start daemon thread that polls device's health 
     thread = Thread(name='device_health_checker', target=self.health_checker()) 
     thread.daemon = True 
     thread.start() 


    def health_checker(self): 
     while self.active: 
      if self.last_heartbeat is not None: 
       time_since_last_heartbeat = timezone.now() - self.last_heartbeat 
       self.is_healthy = False if time_since_last_heartbeat.total_seconds() >= 60 else True 
       self.save() 
       time.sleep(10) 

これは、スレッドの非常に単純な使用のように思えるが、私は解決策を検索するたびに、提案されたアプローチはにやり過ぎのように思えるセロリを使用することです私。セロリのようなものを必要とせずにこれを動作させる方法はありますか?

+0

テーブルにはいくつのデバイスのエントリが存在しますか?デバイスのステータスを確認する必要がある時間間隔はどのくらいにする必要がありますか? –

+0

これは私のアプリケーションだった場合は、[カスタム管理コマンド](https://docs.djangoproject.com/en/1.11/howto/custom-management-commands/)をcronにするか、[セロリ]でタスクをスケジュールしますhttp://www.celeryproject.org/) – danihp

+0

新しい 'Device'インスタンスが初期化されるたびに新しいバックグラウンドスレッドを開始しています。デバイスを照会するたびに、返されるデバイスごとに新しいスレッドが作成されます。これにより、何百ものスレッドではなくても、数多くのスレッドが迅速に作成されます。これにより、サーバーが停止し、Webページを処理するスレッドからリソースが取り除かれます。私はちょうどセロリを使用し、適切にそれを言うと思います。 – knbk

答えて

0

@knbkは、「デバイスを照会するたびに、返されるデバイスごとに新しいスレッドが作成されます。これは私が最初に見落としたものです。

しかし私はDjangoアプリケーションとして開始された1つのバックグラウンドスレッドを使用して問題を解決することができました。これはサードパーティのライブラリ(セロリなど)を追加する方がはるかに簡単なアプローチです。

class DeviceApp(AppConfig): 
    name = 'device_app' 

    def ready(self): 
     # start daemon thread that polls device's health 
     thread = Thread(name='device_health_checker', target=self.device_health_check) 
     thread.daemon = True 
     thread.start() 

def device_health_check(self): 
    while (true): 
     for device in Device.objects.get_queryset(): 
      if device.last_heartbeat is not None: 
       time_since_last_heartbeat = timezone.now() - device.last_heartbeat 
       device.is_healthy = False if time_since_last_heartbeat.total_seconds() >= 60 else True 
       device.save() 
     time.sleep(10) 
0

開発環境では、デバイスの数が非常に少なくなる可能性があります。だから、スレッドの数はおそらく2桁の数字になります。

しかし、このスレッドの問題は、コードを稼働させてもデバイスの数を増やすにつれて、急速に普及しなくなります。したがって、celery beatでセロリを使用する方が良い方法です。

また、DjangoとPythonの初心者であることを考えてみましょう。さらにスレッドをマスターすると、さらに複雑になります。これにセロリを使用すると、最後にもっと簡単できれいになります。

関連する問題