【问题标题】:Concurrent processing via scala singleton object通过 scala 单例对象进行并发处理
【发布时间】:2014-08-10 22:32:04
【问题描述】:

我正在尝试在功能测试中构建一个简单的编排引擎,如下所示:

object Engine {
  def orchestrate(apiSequence : Seq[Any]) {
    val execUnitList = getExecutionUnits(apiSequence) // build a specific list
    schedule(execUnitList) // call multiple APIs
  }

在下面调用的方法(getExecutionUnits 和 schedule)中,我应用的模式是我逐步构建一个列表(因此,不是 val 而是一个 var),遍历列表并调用特定 API 并运行每个都有一些自定义验证。

我知道 scala 中的对象有点等同于单例(因此在我的例子中只有一个 Engine 实例)。如果我期望同时调用 100 次 Orchestrate 方法,我想知道这是否是一个合适的模式。我不管理 Engine 对象中的任何其他内部变量,我只是对方法中提供的参数进行操作。假设 schedule 方法最多需要 10 秒,我担心并发访问时的行为。如果client1、client2和client3同时调用这个方法,会不会有2个客户端排队被我当前正在处理的客户端阻塞?

是否有更安全的惯用方式来处理用例?您是否建议使用演员来包装“编排”方法来处理并发请求?

编辑:澄清一下,这两个方法(getExecutionUnits 和 schedule)是绝对必要的,并按顺序调用。此外, schedule 方法依次调用多个 API(1 到 10 之间的任意位置),并且它们也按顺序执行很重要。截至目前,我有一个简单的 for 循环,一次处理 1 个 Api,等待响应,然后在适当的情况下移动到下一个。

【问题讨论】:

    标签: multithreading scala singleton-methods


    【解决方案1】:

    我不管理 Engine 对象中的任何 其他 内部变量,我只是根据方法中提供的参数进行操作。

    如果您在 Engine 中使用任何变量,这将不起作用。但是,根据您的描述,您似乎没有:您在getExecutionUnits 方法中有一个本地变量,并且(可能)在schedule 中有一个本地变量,它使用getExecutionUnits 的返回值初始化。这种情况应该没问题。

    如果client1、client2和client3同时调用这个方法,会不会有2个客户端排队被我当前正在处理的客户端阻塞?

    不,如果你不添加任何同步(如果引擎本身没有状态,你不应该)。

    你是否推荐使用actor来封装“orchestrate”方法来处理并发请求?

    如果你将它封装在一个actor中,那么客户端在引擎处理一个请求时被阻塞等待。

    【讨论】:

    • 我使用的唯一变量是方法的本地变量,以便增量构建列表或在处理后分配值(引擎本身没有变量来管理任何全局状态)。我的理解是当有超过 1 个时演员会发光(因此通过消息传递处理更快)。我并不是要过度设计,但是如果我将这个“引擎”提取到它自己的 RESTful Web 服务中,我是否可以完全利用 Actor 来实现更高的吞吐量和并发性?
    • @BSJ 在所描述的情况下,没有。只需使用 Netty 之类的东西(如果您想异步处理请求,还可以使用 Java 的线程池)。演员只会增加开销而没有好处(据我所知,没有看到实际代码)。如果您需要管理 Engine 的某些内部状态,或者在不同请求之间进行交互,答案会有所不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 2021-01-18
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多