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的更多相关文章

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

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

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

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

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

    在第一篇Proto.Actor博文中,HelloWorld的第一行真正代码是:    var props = Actor.FromProducer(() => new HelloActor()) ...

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

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

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

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

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

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

  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. MySQL ProxySQL相关维护说明

    背景: 前面的2篇文章MySQL ProxySQL读写分离使用初探和MySQL ProxySQL读写分离实践大致介绍了ProxySQL的使用说明,从文章的测试的例子中看到ProxySQL使用SQLIT ...

  2. Python3.7 dataclass使用指南

    本文将带你走进python3.7的新特性dataclass,通过本文你将学会dataclass的使用并避免踏入某些陷阱. dataclass简介 dataclass的使用 定义一个dataclass ...

  3. 服务器配置用户信息、ssh免密码登录和防火墙等安全配置

    一.登录服务器      1.回到根目录 cd ~      2.ssh + 用户名@服务器公网地址 ssh root@47.94.208.76      3.输入密码:注意输入法大小写 二.查看服务 ...

  4. DAL分页

    using System;using System.Collections.Generic;using LModel.DTO;using Newtonsoft.Json;using System.Da ...

  5. python学习笔记(八)、特殊方法、特性和迭代器

    1 新式类和旧式类 python类的工作方式在不断变化.较新的Python2版本有两种类,其中旧式类正快速退出舞台.新式类时Python2.2 引入的,提供了一些额外功能,如支持函数super 和 p ...

  6. React常见的15个问题

    在 jsComplete,我们管理一个专门用于帮助编程学习者 slack 帐户.我们常常会收到一些有趣的问题,但大多数问题都是常见问题. 我创建这个资源为了帮助 React.js学习者遇到这些常见的问 ...

  7. 程序员50题(JS版本)(一)

    程序1:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? for(var i=1,sum=0;i<=4;i++){ for(var j=1;j<=4;j++){ ...

  8. Apex 中的自定义迭代器

    迭代器 迭代器(iterator)可以遍历一个集合变量中的每个元素.Apex提供了Iterator接口来让开发者实现自定义的迭代器. Iterator接口 Iterator接口定义了两个函数: has ...

  9. vmware 开启VM的硬件cpu虚拟化功能

    物理机的cpu硬件虚拟化功能,通过开启bios中的设置,而vmware中创建的虚拟机也可以开启该特性,如下. 这样的话,就直接可以基于这些VM安装openstack计算节点.控制节点.网络节点了.

  10. Adapter刷新数据的坑

    adapter刷新数据的时候,要能够刷新成功,要保证每次刷新的时候都是改变数据源. 于是,我这样做了,在适配器的构造方法里面写到: private List<ListBean> listI ...