编写使用Scala演员应用在实践II [关闭](Writing applications with

2019-08-02 01:40发布

因为我的第一个问题就是这么长时间,我问这是一个单独的问题。 这是另外一个关于一个基于角色的应用程序的架构。

通过应用跟踪的消息路径

让我们来一段Java代码:

public void deleteTrades(User user, Date date) {
    PermissionSet ps = permissionService.findPermissions(user)
    if (ps.hasPermission("delete")) {
        Set<Trade> ts = peristence.findTrades(date);
        reportService.sendCancelReports(ts);
        positionService.updateWithDeletedTrades(ts);
    }
}

在此代码我有4个独立的部件和该过程需要它们之间的相互作用deleteTrades是明确定义的。 它完全包含在该方法deleteTrades

与模拟这种Actor秒和4名独立的演员代替我的4个组成部分,如何保持一个什么样的过程涉及轨道(在我心中)? 特别是,如果我使用的回避!? 运营商,那么很可能,我会发送消息ConditionalDeletePermissionActor ,这将发送消息GetTradesAndDeletePersistenceActor然后将发送更多的消息等等等等来处理删除代码将在我的应用程序,简直是俯拾即是。

这也意味着,几乎每一个演员需要把手上所有其他男演员(以邮件转发)。

正如我刚才的问题,人们如何面对呢? 是否有一个良好的建模工具,它可以让你保持跟踪的这一切? 人们使用!? 我在转弯太多的组件集成到Actor S'

Answer 1:

您可以使用5种成分,绝对。 有处理特定任务的行为,并有一个协调器为好。

这个问题你必须有,当然是你如何assynchronously连锁这一点。 那么,它实际上有点简单,但它可以掩盖的代码。 基本上,你发送的每个componenent你想要的答复。

react {
  case DeleteTrades(user,dates) => 
    PermissionService ! FindPermissions(user, DeleteTradesPermissions(dates) _)
  case DeleteTradesPermissions(dates)(ps) =>
    if (ps hasPermission "delete")
      Persistence ! FindTrades(date, DeleteTradesTradeSet _)
  case DeleteTradesTradeSet(ts) =>
    ReportService ! SendCancelReports(ts)
    PositionService ! UpdateWithDeletedTrades(ts)
}

这里我们使用钻营通过第一返回答案​​“日期”。 如果有大量的与互动的相关参数,这可能是最好保持在一个地方的HashSet的所有正在进行的交易的信息,只是通过接收答案的时候,你会用它来查找信息的令牌。

请注意,这个单一的演员可以处理多个并发操作。 在这种特殊情况下,只是删除交易,但你可以添加任意数量为它处理不同的动作。 当需要一个动作数据准备好,那么该动作仍在继续。

编辑

下面是这些类如何定义一个工作示例:

class Date
class User
class PermissionSet

abstract class Message
case class DeleteTradesPermission(date: Date)(ps: PermissionSet) extends Message
case class FindPermissions(u: User, r: (PermissionSet) => Message) extends Message

FindPermissions(new User, DeleteTradesPermission(new Date) _)

在哗众取宠和功能的一些解释。 类DeleteTradesPermission被令行禁止,这样你可以传递一个Date就可以了,而有一些其他的功能与完成它PermissionSet 。 这将是应答消息的模式。

现在,类FindPermissions接收作为第二参数的函数。 的演员接收到该消息将返回值传递给该函数,并将收到Message被发送作为回答。 在这个例子中,该消息将有两个Date ,其中主叫演员发送, PermissionSet ,该应答演员提供。

如果无需回答的问题,如的情况下DeleteTradesSendCancelReportsUpdateWithDeletedTrades这个例子的目的,那么你并不需要通过返回的消息的功能。

由于我们预计它会返回一个消息作为参数,这些邮件需要回答的功能,我们可以这样定义特征:

trait MessageResponse1[-T1] extends Function1[T1, Message]
trait MessageResponse2[-T1, -T2] extends Function2[T1, T2, Message]
...


Answer 2:

演员不应该被用来替代传统的服务组件而不用考虑。

大多数我们今天写的服务组件,通过培训,是无状态的。 无状态的服务组件更容易管理(没有消息类等),比演员。 其中之一,他们虽然缺少的东西,当比较的演员,是异步执行。 但是,当客户期待的结果,同步返回的大部分时间,同步无状态的服务组件是蛮好的工作。

演员是在有管理的内部状态一个不错的选择。 有没有必要做内部的任何同步“的行为()”来访问内部状态和担心竞争条件。 只要 ”!?” 没有内部“行为()”使用的,锁死应当以及最小化。

演员应该警惕,同时处理的消息做任何阻塞处理。 由于演员处理他们的消息顺序,任何它们阻塞等待I / O内部时间“ACT()”,它们不能处理其邮箱中的任何其它消息。 斯卡拉成语用在这里是启动另一个临时演员,做实际的阻塞操作。 这种反模式更会影响基于事件的(反应)的演员,因为它会阻止线程基于事件的男主角是捎带上也是如此。

据我所知,你的电话到服务组件的所有四个可能阻塞,所以管它应采取将它们转换为演员的时候,使他们的规模。



文章来源: Writing applications with Scala actors in practice II [closed]
标签: scala actor