2013-09-05 30 views
0

我正在使用Play 2.1.2,我在Enumerator上遇到了一些麻煩,我正在尋求關於如何調試的想法。發現計算器懸掛

我想通過我的服務器流一些S3數據。我可以從Amazon SDK獲得一個InputStream用於我的S3文件(getObject(bucket, key).getObjectContent())。然後我使用Enumerator.fromStream將該InputStream變成Enumerator[Array[Byte]]

所有這種類型檢查,並在我的本地開發機器上,它都完美的作品。當我在Play中制定我的Result時,我只返回Ok.stream(enum)

將問題部署到生產服務器時出現問題。我第一次請求文件時,它工作得很好,我得到了整個文件。但隨後的時間會頻繁地中途(每次不同),然後「卡住」。我裹Enumerator如下,以能夠登錄枚舉是否完成:

val wrapped = enum.onDoneEnumerating { println("Contents fully enumerated"); } 
Ok.stream(wrapped); 

正如預期的那樣,我的機器(和在生產機器第一次通過),我得到的消息「上的內容完全列舉」。但是在那之後,生產機器將開始下載文件,但是它沒有完成(在HTTP意義上和在Enumerator意義上)。

我不知道如何調試。很明顯,fromStream做了一些神奇的事情,我不知道如何弄清楚塊之間發生了什麼。我認爲這可能是一個線程池問題,所以我將整個響應封裝在future { blocking { ... } }塊中,但似乎沒有任何區別。

我試圖避免從S3創建本地臨時文件,然後從那裏建立我的Enumerator的麻煩。使用fromStream創建Enumerator看起來像是這樣做的優雅方式...如果它工作。

對此提出建議?

回答

0

好的,所以我覺得我明白了這一點。事實證明,在Play方面,事情似乎有效。我嘗試了各種變體(構造枚舉器的不同方法,創建臨時文件等)。這並不重要。

什麼確實事情是我正在使用的代理。我正在使用node-http-proxy,如果我在服務器後面的服務器上發出請求,我會得到正確的響應(直接來自播放)。如果我在代理之外的服務器上發出請求,我會得到一個不正確的(空的)響應。所以看起來代理正在「放棄」響應。

看來問題在於響應被stream調用分塊,並且這導致代理的問題。如果我重新制定我的反應是:

SimpleResult(header = ResponseHeader(200), body = enum) 

然後播放使用Enumerator來構建一個完整的響應(非流)和東西再工作。當然,在這種情況下必須形成完整的答案是愚蠢的,但它確實有效。希望從長遠來看,我可以找到比這更好的解決方案,但現在看起來似乎有效。

+0

您是否找到解決此問題的另一種方法? – Jaap

+0

不是。代理行爲超出了我的控制範圍,所以我不得不滿足於擺脫分塊回答。 –