2016-12-14 9 views
0

Я пытаюсь выполнить некоторую задачу в очереди отложенных задач, и мне нужно выполнить другую задачу при успешном завершении задачи в отложенной очереди. Скажем, например, мне нужно удалить все файлы, хранящиеся по заданному пути, а затем, после успешного удаления всех файлов, я хочу снова начать создавать файлы.Отложенная очередь в Google App Engine

Ниже приведен пример кода того, как я пытаюсь его достичь в настоящее время. К сожалению, это вызывает следующее исключение:

raise PermanentTaskFailure(e) PermanentTaskFailure: 'module' object has no attribute 'DeleteTitanFiles'

Другая задача, которую необходимо выполнить после удаления файлов в отсроченной очереди не обязательно должна быть другая задача, это может быть что угодно, даже простое утверждение печати. Дело в том, что после выполнения удаления элемент управления должен вернуться к следующему оператору.

from google.appengine.ext import ndb 
from google3.apphosting.contrib.titan.files import files 
from google.appengine.ext import deferred 
import logging 

TITAN_FILES_PATH = '/lovish-abc/' 

BATCH_SIZE = 250 

range_titan = 0 

def _GetFileCount(): 
    return files.Files.count(TITAN_FILES_PATH, recursive=True) 

file_count = _GetFileCount() 

print _GetFileCount() 

def CreateTitanFiles(path, start): 
    logging.warning('In the CreateTitanFiles method') 
    filecount = _GetFileCount() 
    if filecount < 1000: 
     range_titan = start + BATCH_SIZE 
     for z in xrange(start, range_titan): 
      titan_files = files.File(TITAN_FILES_PATH + 'file' + str(z) + '.json') 
      titan_files.write(content='adasdad') 
     logging.info("######sdgdgds") 
     deferred.defer(
      CreateTitanFiles, TITAN_FILES_PATH, range_titan) 



def DeleteTitanFiles(path): 
    logging.info('In the DeleteTitanFiles method') 

    filecount = _GetFileCount() 

    if filecount > 0: 
     titan_files = files.Files.list(
      TITAN_FILES_PATH, limit=BATCH_SIZE) 
     titan_files.delete() 
    else: 
     CreateTitanFiles(TITAN_FILES_PATH, 0) 


def CallDeleteTitanFiles(path): 
    logging.warning('In the CallDeleteTitanFiles method') 

    filecount = _GetFileCount() 

    while filecount > 0: 
     try: 
      deferred.defer(DeleteTitanFiles, TITAN_FILES_PATH) 
      filecount = _GetFileCount() 
      logging.info('calling again') 
      print filecount 
     except Exception, e: 
      raise e 

CallDeleteTitanFiles(TITAN_FILES_PATH) 

Любые предложения для достижения желаемых результатов?

+2

Почему вы звоните 'CallDeleteTitanFiles' на уровне модуля? Это будет выполнено, когда модуль сначала импортируется, что, конечно же, не то, что вы хотите. –

+0

Я пытался выполнить это на интерактивной консоли, поэтому должен был предоставить точку входа CallDeleteTitanFiles (TITAN_FILES_PATH) просто ставит метод DeleteTitanFiles в очередь –

ответ

0

Эта записка от Limitations of the deferred libraryможет быть связано, почему вы получаете эту ошибку:

  • You can't pass a method defined in the request handler module.

The last point above deserves special attention: passing a method defined in the request handler module - the module specified as a request handler in app.yaml - will not work. You can call deferred.defer from the request handler module, but the function you are passing to it must be defined elsewhere!

Для выполнения кода в интерактивной консоли вы делаете не необходимости экземпляр вызова в модуль.

Предполагая, что ваш модуль называется my_module.py вы могли бы вызвать CallDeleteTitanFiles() в консоли, как это вместо:

from my_module import CallDeleteTitanFiles, TITAN_FILES_PATH 
CallDeleteTitanFiles(TITAN_FILES_PATH) 
Смежные вопросы