2016-12-14 114 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)