2016-12-14 109 views
0

我正试图在延迟任务队列中执行一些任务,并且需要在延迟队列中成功完成任务时执行另一个任务。举个例子,我需要删除存储在给定路径中的所有文件,之后在成功删除所有要再次开始创建文件的文件后。Google App Engine中的延迟队列

下面是我如何试图实现它的示例代码。不幸的是,它会引发以下异常:

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

其他任务在延期队​​列中删除文件后执行并不一定是另一个任务,它可以是任何东西,即使是简单的print语句。重点是,控制应执行删除后返回到下一个语句。

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)