2010-01-23 77 views
0

我在Google App Engine上構建了一些東西,它可以充當iPhone應用程序的後端。在應用程序中,有一些互動通過他們的API推送到社交網絡。因此,典型的工作流程是這樣的:Google App Engine - 你如何處理DatastoreTimeoutException?

  1. 用戶使用iPhone應用程序做的「東西」
  2. App Engine應用程序是通過HTTP驚動
  3. App Engine的提醒,用戶做了社交網絡「的東西。」如果用戶要在該網絡上檢查他們的個人資料,他們將通過應用程序顯示他們的活動。所以,就用戶而言,他們可能做了什麼。
  4. App Engine需要自己做一些持久性,但是當它嘗試時,會引發DatastoreTimeException。現在數據處於一種怪異的狀態。

那麼處理這個問題的好方法是什麼?根據問題的性質,我很樂意將它包裝在「交易」中,但無法回滾發送到社交網絡的內容。所以,我正在思考如何處理DatastoreTimeException?我是否應該將它包裝在試塊中,並再次嘗試?向用戶顯示一個錯誤是否是一個更好的主意,然後當他們再次嘗試時,「跳過」社交網絡交互以便它不會被推出兩次?有沒有另一個想法,我沒有想到這裏?

回答

0

http://code.google.com/appengine/docs/java/javadoc/com/google/appengine/api/datastore/DatastoreTimeoutException.html

「當你試圖把,得到,或有太多的屬性刪除太多的實體或實體,或者如果數據存儲超載或遇到問題就會發生這種情況。」

如果您經常看到異常,我期望這是因爲數據存儲操作太大,因此重試並不會真正起到幫助作用。如果你只是防禦性地防範可能拋出異常的風險,那麼你可以再試一次(也許通過排隊這樣做的任務,但是如果你不能打數據存儲,誰能說你可以排隊任務)

如果你想成爲防彈強勁,可以保證操作你的社交網絡上執行是冪等(可重複),則:

  • 記到自己,您需要執行社交網絡操作。
  • 如果筆記未能存儲,中止並返回失敗。
  • 否則,嘗試社交網絡操作。
  • 如果成功,請刪除註釋。
  • 有一些任務或循環將來重試任何剩餘的筆記。

當然你必須要有點小心你給回iPhone客戶端的響應代碼,因爲成功可以採取時間 - 比iPhone應用程序的請求的持續時間長。所以你希望你的應用引擎請求也是冪等的,你可能想要某種取消。

如果你從社交網絡獲得的所有成功或失敗,如果成功,操作不能重複,那麼你有麻煩了。這是一種在網絡上提供的垃圾API,因爲僅僅因爲Web服務器向您發送成功的響應並不意味着您已收到響應,所以即使成功創建責任,調用者有時也無法知道他們已經成功。但它發生。

+0

實際上,重試通常是成功的;即使對於小型操作,您也會定期獲取數據存儲超時。 – geoffspear 2010-01-23 14:59:34

+0

這就是我的意思 - 如果因爲數據存儲故障而失敗,那麼重試就很好。如果因爲你的實體太大而失敗,那麼重試就會永遠流失。假設這是一個小故障,這個持續時間大概決定了你是否可以在一個簡單的循環中重試(在你的請求超時之前),或者你需要一個任務(因爲解決「怪異狀態」 )。但是我在應用引擎上沒有這方面的經驗。 – 2010-01-23 15:10:49

+0

該對象有幾個屬性 - 一個字符串,一個長,幾個日期和幾個整數。這可能會被視爲「太大」,或者可以肯定,這是一個小故障(這是我唯一看到它的時間)。 – bpapa 2010-01-24 02:29:34

0

我覺得這句話令人擔憂: 實際上,重試通常是成功的;即使對於小型操作,您也會定期獲取數據存儲超時。 - Wooble 1月23日14:59

如果GAE有可靠性問題,怎麼能認真對待GAE?通常你會發現數據存儲緩慢?你對這些例外頻率的估計是多少?

+0

這不是問題的答案 – bpapa 2010-01-26 18:34:33

0

這是任何分佈式系統的基本問題。一般來說,沒有簡單的「防彈」解決方案。如果可能的話,最好的選擇是確保你的一個或兩個操作是冪等的 - 也就是說,多次執行它們都沒有效果。對於數據存儲來說,這很簡單:如果指定了一個鍵名,多個put將會簡單地相互覆蓋。如果可能的話,你也應該在你的社交API中使用冪等性,以便在失敗的情況下安全地重新執行。

相關問題