我曾经研究过Akka角色(非类型化),最近开始编写Akka类型化角色,发现有两种实现方式,一种是函数式的,另一种是面向对象的(类似于旧的)。
我对理解函数式和面向对象方式的状态封装很感兴趣,所以为函数式写了一个方法,为面向对象方式写了一个类。
功能方式:
def webSocketConnections(l: List[ActorRef[Message]] = List.empty): Behavior[WebSocketMsg] = {
Behaviors.receive[WebSocketMsg] {
(context, message) => {
message match {
case Model.UserAdded(actorRef) => webSocketConnections(actorRef :: l)
case Model.BroadcastToAll(msg) =>
context.spawnAnonymous(broadCastActorBehaviour) ! Broadcast(l, msg)
Behaviors.same
}
}
}
}
面向对象的方法
class WebSocketConnectionMaintainer(actorContext: ActorContext[WebSocketMsg]) extends
AbstractBehavior[WebSocketMsg](actorContext) {
private var actorRefL: List[ActorRef[Message]] = List.empty
override def onMessage(msg: WebSocketMsg): Behavior[WebSocketMsg] = {
msg match {
case Model.UserAdded(actorRef) =>
actorRefL = actorRef :: actorRefL
Behaviors.same
case Model.BroadcastToAll(msg) =>
actorContext.spawnAnonymous(broadCastActorBehaviour) ! Broadcast(actorRefL, msg)
Behaviors.same
}
}
}
如果您观察到这两种情况,在函数方式的情况下,状态被封装为参数,不确定它是否会有堆栈安全方面的问题,因为它可能会在大量调用后由于堆栈溢出错误而崩溃,对吗?
但是如果你观察面向对象的方式,它只是直接改变列表,不会导致任何堆栈溢出问题。
我发现的另一个问题是,我只能使用context.spawn
来生成函数式的方式参与者,但在面向对象的情况下,我需要一个特定类型的上下文。如果我想同时创建函数式和面向对象的参与者,该怎么办?
1条答案
按热度按时间pb3skfrl1#
关于栈的安全问题,简单的回答是,表观递归是蹦床式的,所以它不会破坏栈。参见this StackOverflow question。
要生成一个OO定义的类型化参与者,可以使用
Behaviors.setup
,它注入上下文: