《通过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. ...
随机推荐
- 网络编程第六讲Select模型
网络模型第六讲Select模型 一丶Select模型是什么 以前我们讲过一个迭代模型.就是只服务一个客户端连接.但是实际网络编程中.复杂的很多. 比如一个 C/S架构程序 (客户端/服务端) 客户端很 ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(8)- 镜像文件(.bin/.hex/.s19)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的image文件(.bin, .hex, .s19). 今天这节课是痞子衡<ARM Cortex-M文件那些事>主 ...
- Win10系统简单开启热点
介绍 笔记本电脑使用的都是无线网卡,我们可以通过这网卡来开启热点供手机使用,说起开热点,大家都是想到的使用360随身wifi或者是猎豹wifi来开启热点吧,我个人不太喜欢使用这些软件,原因因为有DNS ...
- Maven项目POM文件错误,提示“Plugin execution not covered by lifecycle configuration”的解决方案
一. 问题 Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-depend ...
- excel函数2
1截取函数的应用 实例: 2.日期的年周月星期数据处理
- opencv3.2.0图像处理之高斯滤波GaussianBlur API函数
/*高斯滤波:GaussianBlur函数 函数原型: void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double s ...
- Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法
前言: 今天我想把百度地图的定位集成到项目中来,想写个小小的案例,实现一下,但在集成百度地图时首先要申请秘钥,申请秘钥要用到SHA1值,所以今天就来总结一下怎样去获取这个值吧,希望对大家有帮助. 正常 ...
- C++ 文件操作(简易的学籍管理系统)
这是一个简易的学籍管理系统,大一时居然三个人写了一千多行......年少无知啊!欢迎摘果实! 1 #include <iostream> #include <fstream> ...
- sqlbulkcopy 批量插入数据
批量插入 Datetable数据 通过sqlbulkcopy 插入1百万条数据 用时 10秒钟 (有兴趣的小伙伴可以去测试) /// <summary> /// /// </sum ...
- Linux内存描述之高端内存--Linux内存管理(五)
1. 内核空间和用户空间 过去,CPU的地址总线只有32位, 32的地址总线无论是从逻辑上还是从物理上都只能描述4G的地址空间(232=4Gbit),在物理上理论上最多拥有4G内存(除了IO地址空间, ...