2016-12-02 46 views
0

我有一個涉及OAuth 1交互的微服務。我發現自己處於兩次運行具有完全相同起始狀態的Lambda函數具有非常不同的結果(其中狀態被視爲傳入的「事件」,環境變量和來自API網關的「stageParameters」)的情況。作爲泄漏狀態機的Lambda?

這裏有一個CloudWatch的日誌,顯示兩回至後端的運行: enter image description here

你可以看到,雖然初始狀態是相同的,執行路徑很快改變。在第二種情況下(失敗情況),您會看到日誌條目「Auth state changed:null」......這非常奇怪,因爲實際上,在之前記錄了,即使「處理程序」的第一行代碼是執行。這裏是功能處理程序的開始:

export const handler = (event, context, cb) => { 
    console.log('EVENT:\n', JSON.stringify(event, null, 2)); 

那麼這個過早的日誌條目來自哪裏呢?那麼,人們必須假設它在事前處決中有點遺漏。讓我來演示一下......它實際上是一個事件監聽器,它是在之前的執行過程中設置的。此功能與火力地堡DB和它連接這臺第一次交互的跟進:

auth.signInWithEmailAndPassword(username, password) 
    .then((result) => { 
    auth.onAuthStateChanged(this.watchAuthState); 

其中watchAuthState功能很簡單:

watchAuthState(user) { 
    console.log(`Auth state changed:\n`, JSON.stringify(user, null, 2)); 
} 

這似乎意味着,當我運行DB第二次我已經使用Firebase數據庫「初始化」,但顯然身份驗證已失效。我的頭號目標是回到預測狀態模型,並且每次都執行相同的操作。

如果有一些鬼鬼祟祟的方式在資源有用的方式重用Lambda執行之間的緩存狀態,那麼我認爲這也將是有趣的,但前提是我們可以在實現預測狀態機時做到這一點。

+1

我想這是由於您的代碼中的錯誤,由於JavaScript異步調用的不當處理。你可以發佈你的整個Lambda函數嗎? –

+0

不是很容易...它是打字稿和封閉來源。你如何解釋處理函數中的第一行執行不是第一次登錄? – ken

+0

好吧,我明白你現在在說什麼,發佈一個答案。 –

回答

3

關於日誌順序,請查看每行開始處的每個時間戳之後的ID。我相信這是調用ID。在你用橙色突出顯示的兩行中,它們來自函數的不同調用。 EVENT日誌是第一行從ID以754ee結尾的調用中記錄。 Auth state changed: null行是來自先前調用該函數的日誌條目,其調用ID結尾爲c40d5

看起來您在調用結束時將auth狀態設置爲null,但Firebase連接是全局性的,因此第二個函數調用認爲Firebase連接已經初始化,但由於身份驗證是無效。

我的頭號目標是回到預測狀態模型,並且每次都執行完全相同的操作。

然後你需要知道Lambda container reuse,而不是使用任何全局變量。

+0

調用ID的好處,它確實證明了我對之前運行中剩餘的內容所說的話。使用Typescript我一直保持連接存儲爲我的數據庫模塊的單例/靜態成員,看來問題出在哪裏。通過將所有狀態都帶回到實例的範圍中,狀態機再次變爲整體。 – ken

+0

它確實讓我懷疑是否有一個穩定但更優化的方式來做到這一點,但我認爲websocket連接總是會丟失,而這真的是我希望實現的最優化的優化。現在,我會堅持確定性狀態。 :) – ken