《通过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. ...
随机推荐
- Python机器学习笔记 使用scikit-learn工具进行PCA降维
之前总结过关于PCA的知识:深入学习主成分分析(PCA)算法原理.这里打算再写一篇笔记,总结一下如何使用scikit-learn工具来进行PCA降维. 在数据处理中,经常会遇到特征维度比样本数量多得多 ...
- Java提高班(一)Thread详解
一.概述 在开始学习Thread之前,我们先来了解一下 线程和进程之间的关系: 线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位. 线程不能够独立执行,必须依存在应用程序中,由应用程 ...
- Spring之事件监听(观察者模型)
目录 Spring事件监听 一.事件监听案例 1.事件类 2.事件监听类 3.事件发布者 4.配置文件中注册 5.测试 二.Spring中事件监听分析 1. Spring中事件监听的结构 2. 核心角 ...
- [JavaScript] canvas 合成图片和文字
Canvas Canvas 是 HTML5 新增的组件,就像一个画板,用 js 这杆笔,在上面乱涂乱画 创建一个 canvas <canvas id="stockGraph" ...
- 【转载】C#中自定义Sort的排序规则IComparable接口
C#中的List集合在排序的时候,如果不使用Lambda表达式进行排序的话,一般调用Sort()方法进行排序,如果希望Sort()方法排序后的结果跟我们预想的效果一致或者按照我们自定义的规则排序,则需 ...
- MEF 基础简介 三
MEF导出类的方法和属性 首先来说导出属性,因为这个比较简单,和导出类差不多,先来看看代码,主要看我加注释的地方,MusicBook.cs中的代码如下: using System; using Sys ...
- WordPress在Centos下Apache设置伪静态方法
1.设置httpd.conf文件 1.1 添加或取消注释这段代码 LoadModule rewrite_module modules/mod_rewrite.so 1.2 运行httpd -M查看这个 ...
- bitset用法小结
bitset bitset大概就是类似于bool数组一样的东西 但是它的每个位置只占1bit(特别特别小) bitset的原理大概是将很多数压成一个,从而节省空间和时间(暴力出奇迹) 一般来说bits ...
- 驰骋工作流引擎JFlow与activiti的对比之4种包含多实例的模式
1. 无同步的多实例(MIwithout) 在流程中,一个活动可以激活多个实例,每个实例相互独立,并不需要在后面进行同步. 例子:比如用户购买了N本书,于是后续的支付账单.更新客户可以以本书为单位各自 ...
- Vmware workstation V2V
错误提示 检查虚拟机文件是否有快照,用WORKSTATION打开虚拟机后删除所有快照再使用converter导入 检查VMx文件中声明的vmdk路径是否与文件实际路径相 ...