《通过C#学Proto.Actor模型》之Supervision
Supervision,字面意思是监督,是父Actor发现子Actor有异常发生后,对子Actor产用保种策略处理的机制,如果父Actor不处理,则往上传递。
子Actor发生异常后处理的策略有:
Resume:立即恢复
Restart:恢复之前停止Actor并重新创建它
Stop:停止
Escalate:上报到父级
Supervisor的通过Props.WithChildSupervisorStarategy()来实施的,这个方法第一个参数是接收异常和Actor的PID,以便按一定方式处理异常,第二个参数是重启的次数,第三个参数是两次重启的间隔(按照官方文档,两个连续重启时间大于间隔时间,次数会复位,但实则只按次数走,间隔不起作用)达到最大次数据,子Actor将重新生成。
码友看代码:
using Proto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; namespace P006_Supervision
{
class Program
{
static void Main(string[] args)
{
//设置监督策略,指向SupervisiorMode方法,重启次数为3,两次之间间隔1s
var props = Actor.FromProducer(() => new ShopingCatActor()).WithChildSupervisorStrategy(new OneForOneStrategy(SupervisorMode.Decide, , TimeSpan.FromSeconds()));
var pid = Actor.Spawn(props);
var user = new User { UserName = "gsw" }; var sn = ;
while (true)
{
Console.WriteLine($"{sn++}--------------------begin-----------------");
foreach (var goods in user.ShopingCat.Goodses)
{
Console.WriteLine(goods);
}
Console.WriteLine("---------------------end------------------");
Console.ReadLine();
pid.Request(user, pid);
}
}
}
/// <summary>
/// Supervisor 模式
/// </summary>
class SupervisorMode
{
/// <summary>
/// 用来处理异常发生的后续操作
/// </summary>
/// <param name="pid">PID</param>
/// <param name="reason">异常原因,Exception类型</param>
/// <returns></returns>
public static SupervisorDirective Decide(PID pid, Exception reason)
{
Console.WriteLine(" 异常发生:" + reason.Message + " " + pid);
switch (reason)
{
//重新开始的异常
case RecoverableException _:
return SupervisorDirective.Restart;
//停止异常
case FatalException _:
return SupervisorDirective.Stop;
//其他都上报
default:
return SupervisorDirective.Escalate;
}
}
}
/// <summary>
/// 购物车actor
/// </summary>
class ShopingCatActor : IActor
{
ShopingCat _shopingCat;
public ShopingCatActor()
{
_shopingCat = new ShopingCat();
Console.WriteLine("*******************actor ShopingCatActor************************");
}
public Task ReceiveAsync(IContext context)
{
PID childPid;
if (context.Children == null || context.Children.Count == )
{
var props = Actor.FromProducer(() => new GoodsActor());
childPid = context.Spawn(props);
}
else
{
childPid = context.Children.First();
}
switch (context.Message)
{
case User user:
childPid.Request(_shopingCat, childPid);
user.ShopingCat = _shopingCat;
break;
}
return Actor.Done;
}
}
/// <summary>
/// 商品actor
/// </summary>
class GoodsActor : IActor
{
public Task ReceiveAsync(IContext context)
{
switch (context.Message)
{
case ShopingCat shopingCat: var goods = new Goods { Name = "红茶", Price = 3.0m, Describe = "统一" };
//用来随机产生异常
var random = new Random();
goods.Quantity = random.Next(, ) - ;
if (goods.Quantity <= )
{
throw new RecoverableException("数量不能小于等于0");
}
else
{
shopingCat.Goodses.Add(goods);
Console.WriteLine($"添加 {goods} 到购物车里");
}
break;
}
return Actor.Done;
}
}
/// <summary>
/// 用户
/// </summary>
class User
{
public ShopingCat ShopingCat { get; set; } = new ShopingCat();
public string UserName { get; set; }
}
/// <summary>
/// 购物车
/// </summary>
class ShopingCat
{
public List<Goods> Goodses
{ get; set; } = new List<Goods>();
}
/// <summary>
/// 商品
/// </summary>
class Goods
{
public string Name { get; set; } public int Quantity { get; set; } public decimal Price { get; set; } public string Describe { get; set; }
public override string ToString()
{
return $"Name={Name},Quantity={Quantity},Price={Price},Describe={Describe}";
}
} }
Demo中有三个实体类,用户类,购物车类,商品类,他们的关系一目了解,聚合关系。有两个Actor,购物车Actor(ShopingCatActor),商品Actor(GoodsActor),商品Actor是购物车Actor子Actor;ShopingCatActor下有监督策略,在
SupervisorMode下的Decide方法中,处理不同的异常,采用不同的Actor策略。GoodsActor中,添加商品时根据数量来决定是否产生异常。
看运行结果:

注意看ID $1/$2,是在发生四次异常后才生成$1/$3的(这个与文档说法有出入,也许是我理解有问题,是重启3次,不是启动3次)
《通过C#学Proto.Actor模型》之Supervision的更多相关文章
- 《通过C#学Proto.Actor模型》之 HelloWorld
在微服务中,数据最终一致性的一个解决方案是通过有状态的Actor模型来达到,那什么是Actor模型呢? Actor是并行的计算模型,包含状态,行为,并且包含一个邮箱,来异步处理消息. 关于Actor的 ...
- 《通过C#学Proto.Actor模型》之Mailbox
邮箱是Actor模型的一个重要组成部分,负责接收发过来的消息,并保存起来,等待Actor处理.邮箱中维护着两种队列,一种是存系统消息,另一个是存用户消息,系统省是指Started,Stoping,St ...
- 《通过C#学Proto.Actor模型》之Prpos
在第一篇Proto.Actor博文中,HelloWorld的第一行真正代码是: var props = Actor.FromProducer(() => new HelloActor()) ...
- 通过C#学Proto.Actor模型》之Remote
Proto.Actor中提供了基于tcp/ip的通迅来实现Remote,可以通过其Remot实现对Actor的调用. 先来看一个极简单片的远程调用. 码友看码: 引用NuGet包 Proto.Acto ...
- 《通过C#学Proto.Actor模型》之Persistence
Actor是有状态的,当每一步执行失败后,返回失败地方继续执行时,希望此时的状态是正确的,为了保证这一点,持久化就成了必要的环节了. Proto.Actor提供了三种方式执久化: Event Sour ...
- 《通过C#学Proto.Actor模型》之Behaviors
Behaviors就是Actor接收到消息后可以改变处理的方法,相同的Actor,每次调用,转到不同的Actor内方法执行,非常适合按流程进行的场景.Behaviors就通过在Actor内部实例化一个 ...
- 《通过C#学Proto.Actor模型》之PID
PID对象是代表Actor对象的进程,是能过Actor.Spawn(props)获取的:它有什么成员呢?既然代理Actor,首先有一个ID,标识自己是谁,Actor在Spawn时可以命名这个ID,否则 ...
- 《通过C#学Proto.Actor模型》之Spawning
Props是配置Actor和实例化Actor,那实例化后,就应该访问了,Props.Actor提供了Actor.Spawn(),Actor.SpawnPrefix(),Actor.SpawnNamed ...
- Proto.Actor模型
Proto.Actor模型 http://proto.actor/ https://github.com/axzxs2001/ProtoActorSample https://www.cnblogs. ...
随机推荐
- Linux 中Ctrl + s 的作用
在Linux下使用vim编辑程序时,常常会习惯性的按下Ctrl + s保存文件内容.殊不知,这一按不紧,整个终端再也不响应了. 事实上Ctrl + s在终端下是有特殊用途的,那就是暂停该终端,这个功能 ...
- JDK源码分析(7)之 Reference 框架概览
对于Reference类大家可能会比较陌生,平时用的也比较少,对他的印象可能仅停在面试的时候查看引用相关的知识点:但在仔细查看源码后发现Reference还是非常实用的,平时我们使用的类都是强引用的, ...
- QQ音乐的动效歌词是如何实践的?
本文由云+社区发表 作者:QQ音乐技术团队 一. 背景 1. 现状 歌词浏览已经成为音乐app的标配,展示和动画效果也基本上大同小异,主要是单行的逐字染色的卡拉OK效果和多行的滚动效果.当然,我们也不 ...
- Spring Boot 2.x (十):构建优雅的RESTful接口
RESTful 相信在座的各位对于RESTful都是略有耳闻,那么RESTful到底是什么呢? REST(Representational State Transfer)表述性状态转移是一组架构约束条 ...
- JQuery官方学习资料(译):Data方法
你可能经常会想需要通过元素来存储一些数据.在JavaScript中你可能需要给元素添加属性来实现这样的功能,但是在某些浏览器中,你可能还需要处理因此造成的内存泄露问题.JQuery提供了一个简 ...
- Linux-Kconfig总结与分析
使用Kconfig时,需要注意的地方 1.在Kconfig中定义的配置宏,前缀都没有"CONFIG_",只有编译内核时,自动生成autoconf.h才会出现前缀. 2.如果XX_d ...
- JAVA程序员面试30问(附带答案)
第一,谈谈final, finally, finalize的区别. 最常被问到.final修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能 ...
- 总结Linux下的软件安装
安装软件的最佳实践 虽然我们知道Linux下安装软件有三种方式,分别是源代码安装,rpm包安装和yum安装,但是从可控性和结合自己目前的水平来说,优先选择以下两种方式安装程序. 1,使用rpm包安装 ...
- Go开发之路 -- 指针类型
1. 普通类型,变量存的就是值,也叫值类型 2. 获取变量的地址,用&,比如: var a int, 获取a的地址:&a 3. 指针类型,变量存的是一个地址,这个地址存的才是值 4. ...
- vue的项目结构记录
vue的项目结构 不知道大家有没这样的情况,面对刚配置好的脚手架,创建的文件不知道该放哪个文件下,导致后面开发一些文件不好找,不利于维护. 接下来我说说我项目中的一些文件: 首先是components ...