因为我的第一个问题太长了,所以我作为一个单独的问题来问这个问题。这是另一个关于基于演员的应用程序的体系结构的。
通过应用程序跟踪消息路径
让我们拿出一段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个独立的角色,我如何(在我的脑海中)跟踪一个过程所涉及的内容?特别是如果我避免使用!?操作符,那么很可能我将向我的PermissionActor发送消息ConditionalDelete,后者将向我的PersistenceActor发送消息GetTradesAndDelete,然后再发送更多的消息等等。处理删除的代码将散布在我的应用程序中。
这也意味着几乎每个参与者都需要对其他每个参与者都有一个句柄(为了转发消息)。
和我之前的问题一样,人们是如何处理这个问题的?有一个好的建模工具可以让你跟踪这一切吗?人们是否使用!?,我是否将太多的组件转换为Actor?
发布于 2009-08-21 17:49:54
你肯定用了5个组件。有演员在处理特定的任务,也有一个策划者。
当然,您必须考虑的问题是,您如何同步地将其链接起来。实际上,这有点简单,但它可以模糊代码。基本上,您向每个组件发送所需的答复。
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。
如果没有预期的答案,例如本例中的DeleteTrades、SendCancelReports和UpdateWithDeletedTrades,则不需要传递返回消息的函数。
由于我们期望一个函数将消息作为参数返回给那些需要回答的消息,所以我们可以定义如下特征:
trait MessageResponse1[-T1] extends Function1[T1, Message]
trait MessageResponse2[-T1, -T2] extends Function2[T1, T2, Message]
...发布于 2009-08-22 03:37:29
不应在没有考虑的情况下使用行为者来取代传统的服务组件。
通过培训,我们现在编写的大多数服务组件都是无状态的。无状态服务组件比参与者更容易管理(sans、消息类等)。但是,与参与者相比,他们缺少的是异步执行。但是,当客户机在大多数情况下期望结果同步返回时,同步无状态服务组件对作业来说是可以的。
当有内部状态需要管理时,参与者是一个很好的人选。没有必要在"act()“内部进行任何同步,以访问内部状态并担心竞争条件。只要“!”如果不是在"act()“中使用,那么死锁也应该最小化。
在处理消息时,参与者应该对任何阻塞处理保持警惕。由于参与者按顺序处理他们的消息,每当他们在"act()“中等待I/O时,他们就无法处理邮箱中的任何其他消息。这里使用的Scala成语是启动另一个执行实际阻塞操作的临时参与者。这种反模式会更多地影响基于事件(React)的参与者,因为它阻塞了线程,基于事件的参与者也是猪背的。
据我所知,您对服务组件的所有四个调用都可能阻塞,因此,在将它们转换为参与者时,应该注意使它们扩展。
https://stackoverflow.com/questions/1310964
复制相似问题