共享数据(需要加锁)
传递消息
基于 Channel 的消息传递(消息队列)
基于 Actor 模型的消息传递
Actor 的创建和调度的效率高。
Actor 模型更接近现实世界,现实世界也是分布式的、异步的、基于消息的、尤其 Actor 对于异常(失败)的处理、自愈、监控等都更符合现实世界的逻辑。
An actor is allowed to do several things, including:
class CounterActor {
constructor() {
this.count = 0;
}
onReceive(message) {
if (message.type === 'plus-one') {
this.count += 1;
}
return this.count;
}
}
A simplified example in JavaScript
The complexity of actors is relatively low, and that is because the complexity is usually hidden in the actor frameworks that are used to run these types of primitives in the end.
actix is the low-level actor framework that powers actix-web, a high-performance web framework for the Rust programming language.
pub trait Actor {
// Actor execution context type
type Context: ActorContext;
// Start new asynchronous actor, returns address of newly created actor.
fn start(self) -> Addr<Self>
where Self: Actor<Context = Context<Self>> { ... }
// lifecycle events
fn started(&mut self, ctx: &mut Self::Context) { ... }
fn stopping(&mut self, ctx: &mut Self::Context) -> Running { ... }
fn stopped(&mut self, ctx: &mut Self::Context) { ... }
}
pub trait ActorContext {
// Actor execution state
fn state(&self) -> ActorState;
// Initiate stop process and switch to a stopping state
fn stop(&mut self);
// Terminate actor execution and switch to stopped state
fn terminate(&mut self);
}
pub struct Context<A> where A: Actor<Context = Context<A>> { ... }
impl<A> ActorContext for Context<A> where A: Actor<Context = Self> { ... }
pub enum ActorState {
Started,
Running,
Stopping,
Stopped,
}
pub trait Message {
// The type of value that this message will resolved with
// if it is successful.
type Result: 'static;
}
pub trait Handler<M>
where
Self: Actor,
M: Message,
{
type Result: MessageResponse<Self, M>;
// Method is called for every message received by this Actor
fn handle(&mut self, msg: M, ctx: &mut Self::Context) -> Self::Result;
}
use actix::prelude::*;
// `PlusOne` message implementation
struct PlusOne;
impl Message for PlusOne {
type Result = u32;
}
// `CounterActor` implementation
struct CounterActor {
count: u32,
}
impl CounterActor {
pub fn new() -> CounterActor {
CounterActor { count: 0 }
}
}
impl Actor for CounterActor {
type Context = Context<Self>;
}
impl Handler<PlusOne> for CounterActor {
type Result = u32;
fn handle(&mut self, _msg: PlusOne, _ctx: &mut Context<Self>) -> u32 {
self.count += 1;
self.count
}
}
CounterActor example in Rust