2015-06-21 27 views
2

我在Django Admin(Django 1.8)中保存對象並將它們傳遞給Celery Task。不幸的是,我有一個錯誤[有時!]:「匹配查詢不存在」。我知道這是交易的問題,但解決這個問題的最好方法是什麼?在Django Admin中保存新對象並將其發送給Celery任務後,匹配查詢不存在

class MyModelAdmin(admin.ModelAdmin) 
    def save_model(self, request, obj, form, change): 
     super(MyAdmin, self).save_model(request, obj, form, change) 
     if not change: 
      celery_task.delay(obj.pk) 

@app.task() 
def celery_task(obj_pk): 
    MyModel.objects.get(pk=obj_pk) 

問題是,Django Admin中的整個視圖在transaction.atomic()塊中。有時芹菜會在交易結束時運行得更快。我想知道什麼是最好的方式來解決這個問題。在調用celery_task時添加一個eta是我想的一些令人毛骨悚然的想法(或者可能不是?) - celery_task.apply_async((obj.pk,), eta=+10 seconds)

+1

也許在這方面的一些有趣的聯繫:票證整合[後提交掛鉤(HTTPS:/ /code.djangoproject.com/ticket/21803)被接受(並且還有一個指向contrib包的鏈接)。除此之外,在我看來,'eta'連同配置重試間隔似乎不是一個令人毛骨悚然的想法(但對其他觀點感到好奇)。至少它保持簡單的方式。否則,您也可以運行一些獨立的作業,每隔X間隔檢查一次數據庫的新更改並從那裏觸發任務。 – sthzg

+0

爲什麼不嘗試在'post_save'信號上調用芹菜任務? – argaen

+1

@argaen'post_save'在事務塊中也被調用。 – User

回答

1

我認爲eta是一個好主意。但競爭狀態的可能性還是存在的,所以沿着eta可以retry a task在故障轉移:

@app.task(default_retry_delay=60, max_retries=3) # retry in 1 minute with maximum 3 retries 
def celery_task(obj_pk): 
    try: 
     MyModel.objects.get(pk=obj_pk) 
    except MyModel.DoesNotExist, exc: 
     celery_task.retry(exc=exc) 
相關問題