Django模型中

时间:2017-07-10 20:27:34

标签: python django multithreading python-daemon

我是Python和Django的新手,所以如果有更好的方法,请告诉我。我想要做的是让每个设备(继承自models.Model)启动一个长时间运行的后台线程,该线程不断检查该设备的运行状况。但是,当我运行我的代码时,它似乎没有像守护进程一样执行,因为服务器缓慢而且不断超时。这个后台线程将(在大多数情况下)运行程序的生命周期。

以下是我的代码的简化版本:

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)

这似乎是一个非常简单的线程使用,但每次我搜索解决方案时,建议的方法是使用芹菜,这对我来说似乎有些过分。有没有办法让这个工作不需要像芹菜这样的东西?

2 个答案:

答案 0 :(得分:0)

当您在开发环境中开始时,设备数量可能非常低。因此,当您测试时,线程数可能是两位数。

但即使你让代码工作,这个线程问题也会迅速变得站不住脚。因此,使用带有celery beat的芹菜是更好的方法。

还要考虑到你是Django和Python的新手,试图掌握线程会增加更多的复杂性。使用芹菜最终会更加简单和整洁。

答案 1 :(得分:0)

正如@knbk在评论中提到的,“每次查询设备时,都会为每个返回的设备创建一个新线程”。这是我最初忽略的。

然而,我能够使用作为Django应用程序启动的单个后台线程来解决我的问题。这是一个更简单的方法,然后添加第三方库(如Celery)。

import { GlobalProvider } from '../providers/global.provider';

@Component({
  templateUrl: 'page1.html'
})
export class Page1Page{

  constructor(private _globalProvider : GlobalProvider) {}
     this.globalProvider.setUserName('John');
}