2012-12-15 4 views
2

셀러리의 결과 및 오류와 관련된 일반적인 전략을보다 잘 이해하려고합니다.셀러리 - 오류 처리 및 데이터 저장

요청한 경우 상태/상태 및 결과가 저장되는 것을 확인합니다.이 데이터는 언제 사용합니까? 오류 처리 및 데이터 저장이 작업 내에 포함되어야합니까? 나는 사용자의 주소를 goeocodes 지오 코딩 작업이

: 여기

할 경우에 내 목표를 더 잘 이해하는 데 도움이, 샘플 시나리오입니다. 작업이 실패하거나 성공하면 사용자에게 알려주는 데이터베이스의 필드를 업데이트하고 싶습니다. (오류 처리) 성공시 지오 코딩 된 데이터를 데이터베이스 (데이터 저장소)에 삽입하고 싶습니다.

어떤 접근 방식을 취해야합니까?

답변

1

나는 셀러리 자신에 대한 느낌을 여전히 얻고 있다고 말함으로써 이것을 서언하게한다. 즉, 나는이 문제를 어떻게 해결할 것인가에 대한 일반적인 성향을 가지고 있으며 아무도 반응을 보이지 않았기 때문에 나는 그 기회를 줄 것이다.

필자가 작성한 내용을 토대로 비교적 단순한 (비록 최적화되지 않은 것으로 생각되지만) blog comment spam task example from the documentation의 넓은 윤곽을 따르는 것이 해결책입니다.

app.models.py

class Address(models.Model): 

    GEOCODE_STATUS_CHOICES = (
    ('pr', 'pre-check'), 
    ('su', 'success'), 
    ('fl', 'failed'), 
) 

    address = models.TextField() 
    ... 
    geocode = models.TextField() 
    geocode_status = models.CharField(max_length=2, 
            choices=GEOCODE_STATUS_CHOICES, 
            default='pr') 

class AppUser(models.Model): 
    name = models.CharField(max_length=100) 
    ... 
    address = models.ForeignKey(Address) 

app.tasks.py

from celery import task 
    from app.models import Address, AppUser 
    from some_module import geocode_function #assuming this returns a string 

    @task() 
    def get_geocode(appuser_pk): 
    user = AppUser.objects.get(pk=appuser_pk) 
    address = user.address 

    try: 
     result = geocode_function(address.address) 
     address.geocode = result 
     address.geocode_status = 'su' #set address object as successful 
     address.save() 
     return address.geocode #this is optional -- your task doesn't have to return anything 
           on the other hand, you could also choose to decouple the geo- 
           code function from the database update for the object instance. 
           Also, if you're thinking about chaining tasks together, you    
           might think about if it's advantageous to pass a parameter as 
           an input or partial input into the child task. 

     except Exception as e:  
     address.geocode_status = 'fl' #address object fails 
     address.save() 
     #do something_else() 
     raise #re-raise the error, in case you want to trigger retries, etc 

app.views.py

from app.tasks import * 
from app.models import * 
from django.shortcuts import get_object_or_404 

    def geocode_for_address(request, app_user_pk): 
     app_user = get_object_or_404(AppUser, pk=app_user_pk) 

    ...etc.etc. --- **somewhere calling your tasks with appropriate args/kwargs 

나는 t을 생각 자신이 위에서 간략히 설명한 최소 요구 사항을 충족합니다. 나는 의도적으로 당신이 그것을 방아쇠를 당길 원한다는 느낌이 없으므로 의도적으로 미개발 된 견해를 남겼습니다. 주소를 지오 코딩 할 수없는 경우 ("사용자에게 알리는 데이터베이스의 필드를 업데이트하고 싶습니다.") 사용자 알림을 원할 수도 있습니다. 이 요구 사항의 세부 사항에 대해 더 많이 알지 못하면 HTML 템플릿 (instance.attribute 값이 X, 템플릿의 q를 표시하는 경우) 또는 django.signals (user.address.geocode_status가 실패로 전환 할 때 신호를 보냅니다. 예를 들어 사용자에게 전자 메일로 알려서 알려줍니다.

위의 코드에 대한 의견에서 위의 get_geocode 작업의 구성 요소 부분을 디커플링하고 연결하는 가능성에 대해 언급했습니다. 예외 처리를 get_geocode 태스크에서 분리하는 방법, 사용자 정의 오류 처리기 태스크를 작성하고 link_error parameter (예 : add.apply_async ((2, 2), link_error = error_handler.s()를 사용하여 예외 처리를 생각할 수도 있습니다. error_handler은 app.tasks.py에서 작업으로 정의되었습니다.) 또한 주 작업 (get_geocode)을 통해 오류를 처리할지 또는 연결된 오류 처리기를 통해 오류를 처리 할지를 선택하는 경우 훨씬 많은 정보를 얻고 싶다고 생각합니다. 여러 종류의 오류를 처리하는 방법에 대한 구체적인 내용 (예 : 잘못된 형식의 주소 데이터와 다른 연결 오류가있는 경우)

나는 더 나은 접근 방법이있을 것으로 생각하며 방금 독창적 인 방법을 이해하기 시작했습니다. 연결 작업, 그룹 및 화음 등을 사용하여 얻을 수 있기를 바랍니다. 가능성의 일부를 밖으로. 모범 사례를 추천하기 위해 다른 사람들에게 남겨 두겠습니다.