始终确保您可以在actor的react循环之外与actor进行通信以查找其状态。例如,我总是声明一个通过 MBean 调用的方法,如下所示的代码片段。否则很难判断你的 Actor 是否正在运行、是否已关闭、是否有大量消息队列等。
。
def reportState = {
val _this = this
synchronized {
val msg = "%s Received request to report state with %d items in mailbox".format(
_this, mailboxSize)
log.info(msg)
}
Actor.actor { _this ! ReportState }
}
Avoid !? wherever possible. You will get a locked system!
Always send a message from an Actor-subsystem thread. If this means creating a transient Actor via the Actor.actor method then so be it:
case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }
Add an "any other message" handler to your actor's reactions. Otherwise it is impossible to figure out if you are sending a message to the wrong actor:
case other => log.warning(this + " has received unexpected message " + other
Don't use Actor.actor for your primary actors, sublcass Actor instead. The reason for this is that it is only by subclassing that you can provide a sensible toString method. Again, debugging actors is very difficult if your logs are littered with statements like:
12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1
Document the actors in your system, explicitly stating what messages they will receive and precisely how they should calculate the response. Using actors results in the conversion of a standard procedure (normally encapsulated within a method) to become logic spread across multiple actor's reactions. It is easy to get lost without good documentation.
Always make sure you can communicate with your actor outside of its react loop to find its state. For example, I always declare a method to be invoked via an MBean which looks like the following code snippet. It can otherwise be very difficult to tell if your actor is running, has shut down, has a large queue of messages etc.
.
def reportState = {
val _this = this
synchronized {
val msg = "%s Received request to report state with %d items in mailbox".format(
_this, mailboxSize)
log.info(msg)
}
Actor.actor { _this ! ReportState }
}
Link your actors together and use trapExit = true - otherwise they can fail silently meaning your program is not doing what you think it is and will probably go out of memory as messages remain in the actor's mailbox.
I think that some other interesting choices around design-decisions to be made using actors have been highlighted here and here
I know this doesn't really answer the question, but you should at least take heart in the fact that message-based concurrency is much less prone to wierd errors than shared-memory-thread-based concurrency.
I presume you have seen the actor guidelines in Programming in Scala, but for the record:
Actors should not block while processing a message. Where you might want to block try to arrange to get a message later instead.
Use react {} rather than receive {} when possible.
发布评论
评论(2)
尽可能避免
!?
。您将得到一个锁定的系统!始终从 Actor 子系统线程发送消息。如果这意味着通过
Actor.actor
方法创建一个瞬态 Actor,那就这样吧:case ButtonClicked(src) =>; Actor.actor { 控制器 ! SaveTrade(trdFld.text) }
向演员的反应添加一个“任何其他消息”处理程序。否则无法确定您是否向错误的参与者发送了消息:
<代码>案例其他=> log.warning(this + " has receive an unexpected message " + other
不要使用
Actor.actor< /code> 对于你的主要参与者,而是 sublcas
Actor
这样做的原因是,只有通过子类化,你才能提供一个合理的toString
方法。如果您的日志中充斥着以下语句,则非常困难:12:03 [INFO] 发送 RequestTrades(2009-10-12) 到 scala.actors.Actor$anonfun$1
记录系统中的参与者,明确说明他们将收到哪些消息以及他们应该如何计算响应。使用参与者会导致标准过程(通常封装在方法中)转换为分布在多个参与者反应中的逻辑。如果没有良好的文档,很容易迷失方向。
始终确保您可以在actor的
react
循环之外与actor进行通信以查找其状态。例如,我总是声明一个通过MBean
调用的方法,如下所示的代码片段。否则很难判断你的 Actor 是否正在运行、是否已关闭、是否有大量消息队列等。。
将你的参与者链接在一起并使用
trapExit = true
- 否则它们可能会默默地失败,这意味着你的程序没有按照你的想法行事,并且可能会因为消息保留在参与者的邮箱中而导致内存不足.我认为围绕使用参与者做出的设计决策的一些其他有趣的选择已经被强调此处和这里
Avoid
!?
wherever possible. You will get a locked system!Always send a message from an Actor-subsystem thread. If this means creating a transient Actor via the
Actor.actor
method then so be it:case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }
Add an "any other message" handler to your actor's reactions. Otherwise it is impossible to figure out if you are sending a message to the wrong actor:
case other => log.warning(this + " has received unexpected message " + other
Don't use
Actor.actor
for your primary actors, sublcassActor
instead. The reason for this is that it is only by subclassing that you can provide a sensibletoString
method. Again, debugging actors is very difficult if your logs are littered with statements like:12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1
Document the actors in your system, explicitly stating what messages they will receive and precisely how they should calculate the response. Using actors results in the conversion of a standard procedure (normally encapsulated within a method) to become logic spread across multiple actor's reactions. It is easy to get lost without good documentation.
Always make sure you can communicate with your actor outside of its
react
loop to find its state. For example, I always declare a method to be invoked via anMBean
which looks like the following code snippet. It can otherwise be very difficult to tell if your actor is running, has shut down, has a large queue of messages etc..
Link your actors together and use
trapExit = true
- otherwise they can fail silently meaning your program is not doing what you think it is and will probably go out of memory as messages remain in the actor's mailbox.I think that some other interesting choices around design-decisions to be made using actors have been highlighted here and here
我知道这并不能真正回答问题,但您至少应该放心,基于消息的并发比基于共享内存线程的并发更不容易出现奇怪的错误。
我想您已经看过 Scala 编程 中的 Actor 指南,但郑重声明:
react {}
而不是receive {}
。I know this doesn't really answer the question, but you should at least take heart in the fact that message-based concurrency is much less prone to wierd errors than shared-memory-thread-based concurrency.
I presume you have seen the actor guidelines in Programming in Scala, but for the record:
react {}
rather thanreceive {}
when possible.