【问题标题】:Play Enumerator hanging播放枚举器挂起
【发布时间】:2013-09-09 14:49:50
【问题描述】:

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

我正在尝试通过我的服务器传输一些 S3 数据。我可以从 Amazon SDK 中为我的 S3 文件 (getObject(bucket, key).getObjectContent()) 获取一个 InputStream。然后,我使用 Enumerator.fromStreamInputStream 转换为 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 似乎是一种优雅的方式......如果它有效的话。

建议?

【问题讨论】:

    标签: node.js http scala proxy enumerator


    【解决方案1】:

    好的,所以我想我想通了。事实证明,在 Play 方面,事情似乎正在发挥作用。我尝试了各种变体(构建枚举器、创建临时文件等的不同方式)。没关系。

    没有重要的是我使用的代理。我正在使用node-http-proxy,如果我在代理后面的服务器上发出请求,我会得到正确的响应(直接来自 Play)。如果我在代理之外的服务器上发出请求,我会得到一个不正确的(空的)响应。所以看起来代理正在“丢弃”响应。

    问题似乎是响应被stream 调用分块,这导致代理出现问题。如果我将我的回复重新表述为:

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

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

    【讨论】:

    • 您找到解决此问题的其他方法了吗?
    • 没有。代理行为超出了我的控制范围,因此不幸的是,我不得不放弃分块响应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多