使用 Django Celery 添加视图计数器到对象
这并不重要,但这是此问题的后续问题。
我想记录数据库中每个对象被查看的次数。假设我们有一个包含多个实例的 Person 模型。我们希望使用 Django Celery 来记录每个实例在 Person 模型中被查看的次数,以避免等待数据库写入。
目前我正在这样做:
from celery.decorators import task
class Person(models.Model):
name = models.CharField(max_length=50)
class Stats(models.Model):
person = models.ForeignKey('Person', unique=True)
@task
def addView(self):
se = StatEvent()
se.save()
self.views.add(se)
class StatEvent(models.Model):
date = models.DateTimeField(auto_now_add=True)
然后,每次调用列出人员页面的视图时,我都会获取所有人员,并像这样更新统计信息:
person.get_stats().addView.delay(person.get_stats())
然后返回要在浏览器中显示的人员列表。我认为统计信息的更新会异步发生,但在显示页面之前有一个明显且较长的延迟,这一点可以通过在 Celery 命令窗口中为每个添加显示一个 print
语句来确认。该页面仅在最后一次统计数据更新后才会呈现。
如何确保用户不会等待数据库更新完成?
更新
我认为这可能与没有足够的工作进程来单独处理每个人有关,所以我制作了一个接受人员列表作为参数的函数,并将其用作任务被处决。因此,队列中只有一个任务:
@task(ignore_result=True)
def addViews(persons):
for person in persons:
stats = listing.get_stats()
se = StatEvent()
se.save()
stats.views.add(se)
但是,当打印到控制台时,如下所示:
print "adding"
print tasks.addClicks(persons)
print "done"
然后,“添加”和“完成”步骤之间存在明显的延迟,并且函数的返回值为 None.
Not that it matters, but this is a follow-up to this question.
I want to keep a count of how many times each object in my database has been viewed. Let's say we have a Person
model, with several instances. We want to keep a counter of how many times each instance has been viewed in the Person
model, using Django Celery to avoid waiting for the database writes.
At the moment I'm doing this:
from celery.decorators import task
class Person(models.Model):
name = models.CharField(max_length=50)
class Stats(models.Model):
person = models.ForeignKey('Person', unique=True)
@task
def addView(self):
se = StatEvent()
se.save()
self.views.add(se)
class StatEvent(models.Model):
date = models.DateTimeField(auto_now_add=True)
Then, every time the view is called which lists a page of persons, I get all persons, update the statistics like this:
person.get_stats().addView.delay(person.get_stats())
where after I then return the list of persons to be displayed in the browser. I thought that the updating of the statistics would happen asynchronously, but there's a clear and long delay before the page is displayed, which is confirmed by having a print
statement shown for each addition in the Celery command window. The page is only rendered once the last statistic has been updated.
How do I ensure that the user doesn't wait for the database update to finish?
Update
I thought it might have something to do with there not being enough worker processes to process each person separately, so I instead made a function that accepts a list of persons as parameter, and used this as the task to be executed. So, only one task in the queue:
@task(ignore_result=True)
def addViews(persons):
for person in persons:
stats = listing.get_stats()
se = StatEvent()
se.save()
stats.views.add(se)
However, when print to the console, like this:
print "adding"
print tasks.addClicks(persons)
print "done"
Then there's a clear delay between the "adding" and "done" step, and the returned value of the function is None
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,我最初对工人不足的怀疑是正确的。我的新函数将所有内容都放在一个任务中解决了这个问题 - 我只是在最后一个
tasks.addClicks(persons)
调用中错过了.delay
。Turns out my original suspicion about there not being enough workers was correct. My new function that put everything in one task solved the problem - I was just missing the
.delay
in that lasttasks.addClicks(persons)
call.