播放枚举器挂

时间:2013-09-05 16:54:53

标签: node.js http scala proxy enumerator

我使用的是Play 2.1.2,我在使用Enumerator时遇到了一些问题,我正在寻求如何调试这个问题的想法。

我试图通过我的服务器传输一些S3数据。我可以从Amazon SDK获取InputStream来获取我的S3文件(getObject(bucket, key).getObjectContent())。然后,我使用InputStreamEnumerator[Array[Byte]]转换为Enumerator.fromStream

所有这些类型检查并在我的本地开发机器上它完美地工作。当我在Play中制定Result时,我只返回Ok.stream(enum)

当我将其部署到生产服务器时会出现问题。我第一次请求文件,它工作正常,我得到整个文件。但是随后它经常会逐渐通过(每次不同的数量),然后被卡住了#34;我按如下方式包装了Enumerator,以便能够记录枚举是否已完成:

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

正如预期的那样,在我的开发机器上(以及第一次在生产机器上),我收到了消息"内容完全枚举"。但在那之后,生产机器将开始下载文件,但它没有完成(在HTTP意义上和Enumerator意义上)。

我不确定如何调试它。显然,fromStream有一些魔力,我不知道如何弄清楚块之间发生了什么。我认为这可能是一个线程池问题所以我将整个响应包装在future { blocking { ... } }块中,但它似乎没有任何区别。

我试图避免从S3创建本地临时文件然后从中构建我的Enumerator的麻烦。使用fromStream创建Enumerator似乎是这样做的优雅方式......如果有效的话。

建议?

1 个答案:

答案 0 :(得分:0)

好的,所以我想我想出来了。事实证明,在Play方面,事情似乎正在发挥作用。我尝试了各种变体(构造枚举器的不同方法,创建临时文件等)。这并不重要。

做了什么重要的是我正在使用的代理。我正在使用node-http-proxy,如果我在代理服务器后面的服务器上发出请求,我会得到正确的响应(直接来自Play)。如果我在代理服务器外的服务器上发出请求,则会收到不正确的(空)响应。因此看起来代理正在“放弃”响应。

问题似乎是响应被stream调用分块,这导致代理问题。如果我重新制定我的回答:

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

然后播放使用Enumerator构建一个完整的响应(不是流式传输),然后事情再次起作用。当然,在这种情况下必须形成完整的响应是愚蠢的,但它确实有效。希望从长远来看,我能找到比这更好的解决方案,但这似乎现在有效。