2017-10-29 3 views
0

를 호출 할 때 내가 작업 foobar 바운드 작업 속성 self.request` :도발 셀러리`직접

@app.task(bind=True) 
def foobar(self, owner, a, b): 
    if already_working(owner): # check if a foobar task is already running for owner. 
     register_myself(self.request.id, owner) # add myself in the DB. 
    return a + b 

가 어떻게이 self.request.id 속성을 조롱 할 수 있습니까? 이미 모든 것을 패치하고 .delay/.apply_async을 사용하는 대신 직접 작업을 호출하지만 self.request.id의 값은 None 인 것처럼 보입니다. (DB와의 실제 상호 작용을 수행 할 때마다 테스트가 실패하는 등 ...).

참고로 Django를 프레임 워크로 사용하고 있지만이 문제는 사용하는 환경에 관계없이 동일하다고 생각합니다.

+0

이 이해가되지 않습니다. 그 임무는 수업의 일부입니까? 그렇다면 보여주십시오. 그렇지 않다면 '자기'를 갖지 않을 것입니다. 그리고 어떤 경우에도 요청은 요청의 일부로 실행되지 않으므로 왜 'self.request'가 발생합니까? –

+0

@DanielRoseman 당신은 이미 셀러리를 사용 했습니까? 그렇지 않다면 미리 읽어보십시오. http://docs.celeryproject.org/en/latest/userguide/tasks.html#bound-tasks; 데코레이터는 클래스에서 함수를 래핑합니다. – Raito

답변

0

면책 조항 : 음, 어딘가에 문서화되어 있지 않다고 생각합니다.이 대답은 구현에 따라 다를 수 있습니다.

셀러리는 자신의 작업을 celery.Task 인스턴스로 랩핑합니다. 사용자 작업 기능 등으로 celery.Task.run 메서드를 바꾸는 지 알지 못합니다.

하지만, 직접 작업을 호출 할 때, 당신은 __call__를 호출하고 등 작업 ID를 포함하는 컨텍스트를 밀어거야 ...

그래서 아이디어는 첫째, __call__와 셀러리 일반적인 동작을 무시하는 것입니다 :

  • 예를 들어 제어 된 작업 ID : foobar.push_request(id=1)을 푸시합니다.
  • 그런 다음 run 메서드를 foobar.run(*args, **kwargs)이라고합니다.

예 :

@app.task(bind=True) 
def foobar(self, name): 
    print(name) 
    return foobar.utils.polling(self.request.id) 

@patch('foobar.utils.polling') 
def test_foobar(mock_polling): 
    foobar.push_request(id=1) 
    mock_polling.return_value = "done" 
    assert foobar.run("test") == "done" 
    mock_polling.assert_called_once_with(1)