【问题标题】:How can I "break up" a long running server side function in a Meteor app?如何“分解” Meteor 应用程序中长时间运行的服务器端功能?
【发布时间】:2015-12-10 18:55:41
【问题描述】:

作为流星应用程序的一部分,我有一个服务器端,它通过对集合的插入/更新获取信息的 POST 消息以提供给 Web 客户端。到目前为止,一切都很好。但是,有时这些更新可能相当大(每 5 秒一次 50K 记录)。在我开始使用批处理插入包,然后使用 Mongo 的低级 batch.find.update() 和 batch.execute() 之前,我很难跟上这一点。

但是,即使有 50K 记录,仍然有大量的处理在进行(它会进行一些计算、分析等)。我希望能够“线程化”该逻辑,以便主事件循环可以继续进行。但是,我不确定是否有一种真正简单的方法可以在 Meteor 中为此创建“真实”线程。因此,我想知道至少“批处理”工作的最佳/正确方法,以便每 N(例如 1K 左右)记录我可以释放事件循环以处理其他事件(例如某些客户端 DDP消息等)。然后再做 1K 记录,等等,直到完成我需要的许多记录。

我认为解决方案在于使用 Fibers/Futures——这似乎是 Meteor 的方式——但我并不肯定这是正确的或像“setTimeout()”和/或“setImmediate( )”更合适。

TIA!

【问题讨论】:

    标签: node.js meteor


    【解决方案1】:

    Meteor 不是万能的工具。我认为您应该将流星应用程序与批处理分离。设置一个单独的流星实例,或者更好地设置一个纯 node.js 服务器来处理这些请求和批处理。它看起来像这样:

    mongo 中的更新会很快反映在流星中。我有类似的情况,并使用节点服务器进行一些批量数据收集,然后将其传递到 cassandra 数据库。然后我使用 pig latin 对该数据运行一些批处理操作,然后将其插入 mongo。我的流星应用程序几乎可以立即反应性地显示新数据。

    【讨论】:

    • 我其实已经想到了——但这应该是一个“简单”的轻量级独立应用程序——数据实际上在被查看后被丢弃等等。它实际上都被包裹起来了一个在 Windows 下运行的 C#/.NET 桌面应用程序。所以我希望我可以只使用单个“节点”应用程序来获取它,因为该数据确实不是持久的(每次运行新数据库)。但是,它可能会下降到你的解决方案。:) 嗯......我还认为你的方法需要我弄清楚如何让 REPLSET 和 OPLOG 拖尾在这个“动态”临时环境中工作.. ??
    【解决方案2】:

    您可以在服务器方法中调用this.unblock() 以允许代码在后台运行,并立即从该方法返回。请参见下面的示例。

    Meteor.methods({
      longMethod: function() {
        this.unblock();
        Meteor._sleepForMs(1000 * 60 * 60);
      }
    });
    

    【讨论】:

    • 这是一个有趣的答案——但不确定它是否会对我的情况有所帮助,与你的例子不同——它会执行 _sleepForMs()——无论如何它都会有效地放弃控制——我有一个漂亮的CPU 密集型功能仍然会占用正在运行的线程并且不允许其他事情发生。因此,做一批工作的想法——发布——回来做另一批,等等。或者我可能错过了 unblock() 的一些东西。 :)
    • unblock 的作用是允许方法在完成处理 .unblock() 调用之后的任何操作之前返回。如果您不使用 unblock,该方法将等到您的繁重操作完成后再将其最终结果返回给客户端。至于您的进程非常繁重并占用了所有可用的服务器资源,我无能为力,抱歉:)
    猜你喜欢
    • 1970-01-01
    • 2016-07-14
    • 1970-01-01
    • 2021-08-14
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 2013-02-01
    相关资源
    最近更新 更多