在第一篇Proto.Actor博文中,HelloWorld的第一行真正代码是:

   var props = Actor.FromProducer(() => new HelloActor());

这个返回的变量props就是一个Props的对象,它是负责创Actor实例,以及配置Actor实例,并且产Actor上下文Context(类似asp.net中的Context)。

Props对象产生通常是用Actor.FromProducer或Actor.FromFunc产生,不过也可能实例化,实体例时可以给Actor做一系列配置,如下代码:

 using Proto;
using Proto.Mailbox;
using System;
using System.Threading.Tasks; namespace P002_CustomProps
{
class Program
{
static void Main(string[] args)
{
var props = new Props()
//用道具代理返回一个IActor实例
.WithProducer(() => new MyActor())
//默认调度器用线程池,邮箱中最多300个消息吞吐量
.WithDispatcher(new ThreadPoolDispatcher { Throughput = })
//默认邮箱使用无界队列
.WithMailbox(() => UnboundedMailbox.Create())
//默认策略在10秒的窗口内最多重新启动子Actor 10次
.WithChildSupervisorStrategy(new OneForOneStrategy((who, reason) =>
SupervisorDirective.Restart, , TimeSpan.FromSeconds()))
//可以将中间件链接起来以拦截传入和传出消息
//接收中间件在Actor接收消息之前被调用
//发送者中间件在消息发送到目标PID之前被调用
.WithReceiveMiddleware(
next => async c =>
{
Console.WriteLine($"Receive中间件 1 开始,{c.Message.GetType()}:{c.Message}");
await next(c);
Console.WriteLine($"Receive中间件 1 结束,{c.Message.GetType()}:{c.Message}");
},
next => async c =>
{
Console.WriteLine($"Receive中间件 2 开始,{c.Message.GetType()}:{c.Message}");
await next(c);
Console.WriteLine($"Receive中间件 2 结束,{c.Message.GetType()}:{c.Message}");
})
.WithSenderMiddleware(
next => async (c, target, envelope) =>
{
Console.WriteLine($"Sender中间件 1 开始, {c.Message.GetType()}:{c.Message}");
await next(c, target, envelope);
Console.WriteLine($"Sender中间件 1 结束,{c.Message.GetType()}:{c.Message}");
},
next => async (c, target, envelope) =>
{
Console.WriteLine($"Sender中间件 2 开始,{c.Message.GetType()}:{c.Message}");
await next(c, target, envelope);
Console.WriteLine($"Sender中间件 2 结束,{c.Message.GetType()}:{c.Message}");
})
// 默认的 spawner 构造 Actor, Context 和 Process
.WithSpawner(Props.DefaultSpawner); //从props衍生pid,pid代理一个actor的地址
var pid = Actor.Spawn(props);
//把Hello对象交给HelloActor处理
pid.Tell(new MyEntity
{
Message = "我是MyEntity的Message,请求"
});
Console.ReadLine();
}
} public class MyActor : IActor
{
public Task ReceiveAsync(IContext context)
{
if (context.Message is MyEntity myEntity)
{
Console.WriteLine(myEntity.Message);
context.Tell(context.Sender, new MyEntity() { Message = "我是MyEntity的Message,应答" });
}
return Actor.Done;
}
}
public class MyEntity
{
public string Message { get; set; }
}
}

你会发现,Demo中,总有一个实例类+一个Actor类,这是构成Actor模型的必备,Actor类就是主体,实体类就是Actor类运算的载体,所以它们总是如影随形。

第15 行到第21 行代码含意以后会解释。

这里说Recevie和Sender的中间件,这里很像一个AOP,可以在调用某个行为前后作处理统一的处理,比如日志,权限等统一的规则,也和asp.net core里的中件间如出一辙【如里你是一个asp.net core码友,熟悉的Context,熟悉的next(),还有熟悉的Middleware】。

现在可以自己运行一下分析一下结果吧:

《通过C#学Proto.Actor模型》之Prpos的更多相关文章

  1. 《通过C#学Proto.Actor模型》之 HelloWorld

    在微服务中,数据最终一致性的一个解决方案是通过有状态的Actor模型来达到,那什么是Actor模型呢? Actor是并行的计算模型,包含状态,行为,并且包含一个邮箱,来异步处理消息. 关于Actor的 ...

  2. 《通过C#学Proto.Actor模型》之Mailbox

    邮箱是Actor模型的一个重要组成部分,负责接收发过来的消息,并保存起来,等待Actor处理.邮箱中维护着两种队列,一种是存系统消息,另一个是存用户消息,系统省是指Started,Stoping,St ...

  3. 通过C#学Proto.Actor模型》之Remote

    Proto.Actor中提供了基于tcp/ip的通迅来实现Remote,可以通过其Remot实现对Actor的调用. 先来看一个极简单片的远程调用. 码友看码: 引用NuGet包 Proto.Acto ...

  4. 《通过C#学Proto.Actor模型》之Persistence

    Actor是有状态的,当每一步执行失败后,返回失败地方继续执行时,希望此时的状态是正确的,为了保证这一点,持久化就成了必要的环节了. Proto.Actor提供了三种方式执久化: Event Sour ...

  5. 《通过C#学Proto.Actor模型》之Behaviors

    Behaviors就是Actor接收到消息后可以改变处理的方法,相同的Actor,每次调用,转到不同的Actor内方法执行,非常适合按流程进行的场景.Behaviors就通过在Actor内部实例化一个 ...

  6. 《通过C#学Proto.Actor模型》之Supervision

    Supervision,字面意思是监督,是父Actor发现子Actor有异常发生后,对子Actor产用保种策略处理的机制,如果父Actor不处理,则往上传递. 子Actor发生异常后处理的策略有: R ...

  7. 《通过C#学Proto.Actor模型》之PID

    PID对象是代表Actor对象的进程,是能过Actor.Spawn(props)获取的:它有什么成员呢?既然代理Actor,首先有一个ID,标识自己是谁,Actor在Spawn时可以命名这个ID,否则 ...

  8. 《通过C#学Proto.Actor模型》之Spawning

    Props是配置Actor和实例化Actor,那实例化后,就应该访问了,Props.Actor提供了Actor.Spawn(),Actor.SpawnPrefix(),Actor.SpawnNamed ...

  9. Proto.Actor模型

    Proto.Actor模型 http://proto.actor/ https://github.com/axzxs2001/ProtoActorSample https://www.cnblogs. ...

随机推荐

  1. Java开发知识之Java中的集合Set接口以及子类应用

    ---恢复内容开始--- Java开发知识之Java中的集合Set接口以及子类应用 一丶Set接口以及作用 在上一讲.我们熟悉了接口的实现图.以及自己各有的子类. List接口主要存储的数据是可以重复 ...

  2. 痞子衡嵌入式:微控制器CPU性能测试基准(EEMBC-CoreMark)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是微控制器CPU性能测试基准CoreMark. 在嵌入式系统行业用于评价CPU性能指标的标准主要有三种:Dhrystone.MIPS.Co ...

  3. Spring AOP中的JDK和CGLib动态代理哪个效率更高?

    一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...

  4. Linux基础命令第三天

    1,vim编辑器 命令模式下: pageup 往上翻页 pagedown 往下翻页 H 光标移动到屏幕首行 gg 光标动荡到文档的首行,如果前面加上n,表示移动到n行 G 移动文档最后一行 /name ...

  5. Spring学习心得--------bean-Factory

    在学习Spring框架的过程中发现,Spring中的bean不仅是对javabean的一种封装,让你可以通过beanfactoryAPI读取自己配置的beans.xml文件来实现javabean的设置 ...

  6. @RequestParam Map<String, Object> paramMap

    @RequestParam 请求方式 url = "/edit?device=${device}&type=${type}" Controller @RequestMapp ...

  7. js 向上和向下取整

    Math.ceil(x),Math.floor(x) ◎Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数:◎Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近 ...

  8. 原生js实现数据单向绑定

    Object.defineProperty()方法直接在对象上定义一个新属性,或修改对象上的现有属性,并返回该对象. Object.defineProperty(obj, prop, descript ...

  9. Linux基础学习(全)

    使用的Linux发行版本为Redhat 1.Linux(RedHat)基础学习-命令行使用入门 2.Linux(RedHat)基础学习-文件寻址与管理 3.Linux(RadHat)基础学习-vim编 ...

  10. Vue.js如何在一个页面调用另一个同级页面的方法

    使用场景: 页面分为header.home.footer三部分,需要在home中调用header中的方法,这两个没有相互引入 官方给出方法: 需要在展示页里调用顶部导航栏页里的方法,两者之间没有引用关 ...