2013-02-20 29 views
2

我有一個應用程序正在消耗一些數據的App Engine。解析完這些數據後,它會知道它需要在一段時間內執行某些操作 - 可能不會持續幾個小時或幾周。未來在App Engine上遙遠的時間執行任務的最有效方式是什麼?

什麼是在App Engine上執行一段任意時間後執行一段代碼的最佳方式?

我認爲使用Countdown MillisEtaMillis從一個TaskQueue會工作,但沒有看到任何人做同樣的事情的證據,特別是對於如此長的時間框架。

這是最好的方法,還是有更好的方法?

回答

2

如果您能夠將數據存儲中的對象與所有相關信息一起保存以供將來處理(包括應該開始處理對象數據時),則可以使用cron作業定期查詢數據存儲/時間範圍過濾器,並在適當的時間觸發處理上述任何對象。

-1

我認爲taskQueue是一個很好的策略,但有一個大問題「如果推送任務成功創建,它最終將被刪除(任務成功執行後最多七天)。」 Source

我會改用datastore。這裏是您可以採取的一種策略:

  1. 一旦您完成「解析數據」,將記錄插入數據存儲區。
  2. 根據創建/插入日期檢查當前日期,查看自您的工作完成/開始後經過了多長時間等 (很明顯,您不想每分鐘都做一次,也可以做一次 一天或每小時)
  3. 執行下一個任務,只要第2步中的條件通過了您所需的「任意時間量」,您就需要執行該任務。

這裏是你如何可以將記錄添加到數據存儲......讓你開始..

Entity parsDataHolder = new Entity("parsing_data_done", guestbookKey); 
    parsDataHolder.setProperty("date", date); 

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); 
datastore.put(parsDataHolder) 
+0

這將導致運行的後端實例像......一個星期直,只是爲了一個任務。這似乎有點低效。 – 2013-02-21 01:01:33

+0

這樣做效果不佳,會在GAE上花費大量財富。 – 2014-12-19 08:21:54

+0

@JonathanNewmuis你對我的第一個答案是正確的,我更新了我的回覆。感謝您花時間幫助我改進我的答案。另外,如果你給我投票,那也會讓我振作起來:) – 2014-12-19 17:57:09

0

我做了以下內容:

  1. 排隊與任務延遲配置如你所說。讓任務處理以已知方式更改數據存儲區條目(例如:設置標誌)。

  2. 有一個stragglers低頻cron作業,用於執行任何已被某個入隊任務忽略的處理(例如:任務中發生未捕獲的異常)。

爲此,請確保由任務和cron作業調用的處理是冪等的。

Enjoy?

2

我們成功使用TaskQueue的倒計時參數在註冊後7天向其他需求發送電子郵件給客戶。

任務隊列是核心/基本的API /服務是相當可靠的 - 我認爲這是去與任務隊列ETA /倒計時,除非你是最好的辦法:

  • 需要的能力編程看到的是在隊列中
  • 需要編程能力從隊列
1

刪除特定的任務我使用任務隊列的調度。在QueueConstants中宣佈最多30天,並在QueueImpl中應用。

//Returns the maximum time into the future that a task may be scheduled. 
    private static final long MAX_ETA_DELTA_MILLIS = 2592000000L; 

1000毫秒* 60 *60米* 24小時*30天= 2592000000ms

private long determineEta(TaskOptions taskOptions) { 
Long etaMillis = taskOptions.getEtaMillis(); 
Long countdownMillis = taskOptions.getCountdownMillis(); 
if (etaMillis == null) { 
    if (countdownMillis == null) { 
    return currentTimeMillis(); 
    } else { 
    if (countdownMillis > QueueConstants.getMaxEtaDeltaMillis()) { 
     throw new IllegalArgumentException("ETA too far into the future"); 
    } 
    if (countdownMillis < 0) { 
     throw new IllegalArgumentException("Negative countdown is not allowed"); 
    } 
    return currentTimeMillis() + countdownMillis; 
    } 
} else { 
    if (countdownMillis == null) { 
    if (etaMillis - currentTimeMillis() > QueueConstants.getMaxEtaDeltaMillis()) { 
     throw new IllegalArgumentException("ETA too far into the future"); 
    } 
    if (etaMillis < 0) { 
     throw new IllegalArgumentException("Negative ETA is invalid"); 
    } 
    return etaMillis; 
    } else { 
    throw new IllegalArgumentException(
     "Only one or neither of EtaMillis and CountdownMillis may be specified"); 
    } 
} 

}

相關問題