2015-07-21 90 views
7

,我發現了以下錯誤在我的芹菜工人的一個奇怪的錯誤:與Redis的芹菜

2015-07-21T15:02:04.010066+00:00 app[worker.1]: Traceback (most recent call last): 
2015-07-21T15:02:04.010069+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/celery/app/trace.py", line 296, in trace_task 
2015-07-21T15:02:04.010070+00:00 app[worker.1]:  on_chord_part_return(task, state, R) 
2015-07-21T15:02:04.010073+00:00 app[worker.1]:  deps.delete() 
2015-07-21T15:02:04.010074+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/celery/result.py", line 773, in delete 
2015-07-21T15:02:04.010071+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/celery/backends/base.py", line 587, in on_chord_part_return 
2015-07-21T15:02:04.010078+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/celery/backends/base.py", line 329, in delete_group 
2015-07-21T15:02:04.010076+00:00 app[worker.1]:  (backend or self.app.backend).delete_group(self.id) 
2015-07-21T15:02:04.010079+00:00 app[worker.1]:  return self._delete_group(group_id) 
2015-07-21T15:02:04.010081+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/celery/backends/base.py", line 499, in _delete_group 
2015-07-21T15:02:04.010082+00:00 app[worker.1]:  self.delete(self.get_key_for_group(group_id)) 
2015-07-21T15:02:04.010083+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/celery/backends/redis.py", line 172, in delete 
2015-07-21T15:02:04.010084+00:00 app[worker.1]:  self.client.delete(key) 
2015-07-21T15:02:04.010085+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/redis/client.py", line 824, in delete 
2015-07-21T15:02:04.010087+00:00 app[worker.1]:  return self.execute_command('DEL', *names) 
2015-07-21T15:02:04.010088+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/redis/client.py", line 565, in execute_command 
2015-07-21T15:02:04.010089+00:00 app[worker.1]:  return self.parse_response(connection, command_name, **options) 
2015-07-21T15:02:04.010090+00:00 app[worker.1]: File "/app/.heroku/python/lib/python2.7/site-packages/redis/client.py", line 579, in parse_response 
2015-07-21T15:02:04.010091+00:00 app[worker.1]:  return self.response_callbacks[command_name](response, **options) 
2015-07-21T15:02:04.010093+00:00 app[worker.1]: ValueError: invalid literal for int() with base 10: 'QUEUED' 

我感到奇怪的是,我沒有看到調用int在堆棧跟蹤的最後一行。 QUEUED可能是作爲工人的身份出現的。我正在使用它作爲這樣的自定義工作狀態:

@before_task_publish.connect 
def update_sent_state(sender=None, body=None, **kwargs): 
    # the task may not exist if sent using `send_task` which 
    # sends tasks by name, so fall back to the default result backend 
    # if that is the case. 
    task = current_app.tasks.get(sender) 
    backend = task.backend if task else current_app.backend 
    logging.debug("Setting status for %s" % body["id"]) 

    backend.store_result(body['id'], None, "QUEUED") 

這裏有什麼問題?


萬一它是相關的,這裏是我的任務的代碼。我只打電話直接取fetch

@app.task 
def fetch(url_or_urls, subscribe=None): 
    """This fetches a (list of) podcast(s) and stores it in the db. It assumes that it only gets called 
    by Podcast.get_by_url, or some other method that knows whether a given podcast has 
    already been fetched. 

    If *subscribe* is given, it should be a User instance to be subscribed to the given podcasts.""" 
    if isinstance(url_or_urls, basestring): 
     url_or_urls = [url_or_urls] 
    body = _store_podcasts.s() 
    if subscribe: 
     body.link(_subscribe_user.s(user=subscribe)) 
    return chord([_fetch_podcast_data.s(url) for url in url_or_urls])(body) 

@app.task 
def _fetch_podcast_data(url): 
    return do_fetch(url) # This function returns a dict of podcast data. 

@app.task 
def _store_podcasts(podcasts_data): 
    """Given a list of dictionaries representing podcasts, store them all in the database.""" 
    podcasts = [Podcast(**pdata) for pdata in podcasts_data] 
    return Podcast.objects.insert(podcasts) 

@app.task 
def _subscribe_user(podcasts, user): 
    """Subscribe the given users to all the podcasts in the list.""" 
    return user.subscribe_multi(podcasts) 

還有什麼可以在這裏相關嗎?如圖pip freeze


庫版本:

redis==2.10.3 
celery==3.1.18 
+0

你可以提供芹菜和redis-py版本嗎?我有一些觀點需要調查,但是你的錯誤跟蹤行號與我的不一樣。 – mrorno

+0

@mrorno「pip freeze」顯示的版本:'redis == 2.10.3','celery == 3.1.18' – bigblind

回答

2

redis python包預期來自DEL動作的響應總是整數,我假設是刪除的行的計數。

對int的調用發生在最後一行(return self.response_callbacks[command_name](response, **options)),其中self.response_callbacks['DEL']等於int

作爲一種變通方法,你可以繼承的redis.client.StrictRedis並設置DEL響應回調比int其他的東西,只要確保你熟悉的含義。

+0

爲什麼它沒有得到int?就我而言,我不是在與Celery討論Redis。 – bigblind

+0

如果您異步調用它,它將返回一個http://celery.readthedocs.org/en/latest/reference/celery.result.html。一旦任務完成,實際結果(可能是整數)將在該結果的結果屬性中可訪問。 – garnertb

+0

當然,並且該結果存儲在redis中。看起來像Celery正在做一些清理工作,刪除中間組結果,並且在那個文件中的某個地方,redis獲取我的任務狀態而不是刪除計數。這是如何發生的?如果它是相關的,我將添加我打給該問題的任務的代碼。 – bigblind

3

無需工作代碼就很難調試這樣的錯誤。這是我想它可能是。 讓我們從這裏開始:

http://celery.readthedocs.org/en/latest/_modules/celery/backends/base.html#BaseBackend.store_result

def store_result(self, task_id, result, status, 
       traceback=None, request=None, **kwargs): 
    """Update task state and result.""" 
    result = self.encode_result(result, status) 
    self._store_result(task_id, result, status, traceback, 
         request=request, **kwargs) 
    return result 

它調用ecnode_result。讓我們看看

def encode_result(self, result, status): 
     if status in self.EXCEPTION_STATES and isinstance(result, Exception): 
      return self.prepare_exception(result) 
     else: 
      return self.prepare_value(result) 

它看起來像「狀態」預計是從預定義的STATE常量的東西。

它的代碼是在這裏

http://celery.readthedocs.org/en/latest/_modules/celery/states.html#state

這裏文檔

http://celery.readthedocs.org/en/latest/reference/celery.states.html

這看起來並不像他們希望看到類似「QUEU ED「在那裏。嘗試其中一個預定義的。

+0

芹菜任務有一個'update_state()'方法,在那裏你可以提供任何字符串,我期待成說。文檔:http://celery.readthedocs.org/en/latest/userguide/tasks.html#custom-states – bigblind

+0

嗯'task.update_state'似乎做我正在做同樣的事情:'self.backend.store_result (task_id,meta,state)',其中meta默認爲None。 – bigblind

+0

你能嘗試預定狀態的東西,所以我們可以保證的問題是,我們正在尋找。 – singer