2012-04-22 55 views
1

我怎樣才能可靠地檢測到,在我的代碼深處,是否從任務隊列調用處理程序的當前調用?如何可靠地檢測到代碼正在從任務隊列中執行?

我的理解是,在GAE/J,如果我檢查了HttpServletRequest對象,我可以檢查是否following headers設置:

  • X-AppEngine-QueueName
  • X-AppEngine-TaskName
  • X-AppEngine-TaskRetryCount
  • X-AppEngine-FailFast
  • X-AppEngine-TaskETA

其中任何這些頭文件的存在表明處理程序正在被任務隊列調用。

但是說我需要做檢測的代碼部分深處在幾個抽象層中,在那裏我不能訪問HttpServletRequest對象,有什麼方法可以可靠地檢測當前執行環境是否正在從任務隊列調用還是不?

我所希望的是,有可能是喜歡方便的東西:

SystemProperty.environment.value() == Value.TaskQueue 

類似於我們可以檢查代碼是否在GAE或在開發服務器使用SystemProperty.environment.value() == Value.Development正在執行的方式。

+0

什麼阻止你在'doPost()'中檢查頭並將結果傳遞給你的抽象邏輯,例如作爲'fromTaskQueue'布爾值? – alex 2012-04-22 13:52:53

+0

@alex:需要檢查的部分被深埋在抽象層中,我想保持我的體系結構鬆散耦合,傳遞變量會使其不那麼靈活。 – 2012-04-22 14:19:05

+0

抽象層的要點是抽象;你不應該避免這種抽象破壞你的代碼嗎? – 2012-04-23 01:39:54

回答

0

我最終檢查了請求頭是否包含X-AppEngine-TaskName,並且,由於AlexR的建議,將檢查結果存儲在線程局部變量中。

基於以下埃裏克Willigers評論,原來谷歌已經放棄從外部請求X-AppEngine-TaskName頭,從保護那些試圖僞造頭惡意攻擊者的應用程序,因此這似乎是最安全的方法爲止。

+1

如果惡意攻擊者試圖設置X-AppEngine-TaskName頭,它們將不會成功 - 在請求到達您的應用程序之前,欺詐頭將被丟棄。 – 2012-07-03 09:57:38

+0

@EricWilligers:很高興知道,謝謝澄清! – 2012-07-03 10:41:58

-1

嘗試檢查堆棧跟蹤:new Throwable().getStackTrace()。這將返回一個StackTraceElement的數組。您可以遍歷該數組,並確定典型的從隊列調用的類+方法。

+0

這是一種可能的方法,我們也可以使用'Thread.currentThread()。getStackTrace()'來獲得堆棧跟蹤而不用構建'Throwable'對象。儘管如此,如果Google將來會更改調用步驟,那麼使用此方法進行檢查可能會返回不正確的結果。 – 2012-04-22 14:25:12

+1

您可以使用可以訪問HttpSession的HttpFilter。它可以提取您提到的屬性並將一些自定義標誌放入ThreadLocal。然後你可以在代碼的其他地方使用這個值,在那裏你不能訪問HttpSession。 – AlexR 2012-04-22 14:37:53

+0

@AlexR:IMO這是一個正確的方法。把它變成一個答案,我會upvote。 – 2012-04-22 15:17:44

相關問題