zoukankan      html  css  js  c++  java
  • 《通过C#学Proto.Actor模型》之Supervision

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

     子Actor发生异常后处理的策略有:

    Resume:立即恢复

    Restart:恢复之前停止Actor并重新创建它

    Stop:停止

    Escalate:上报到父级 

    Supervisor的通过Props.WithChildSupervisorStarategy()来实施的,这个方法第一个参数是接收异常和Actor的PID,以便按一定方式处理异常,第二个参数是重启的次数,第三个参数是两次重启的间隔(按照官方文档,两个连续重启时间大于间隔时间,次数会复位,但实则只按次数走,间隔不起作用)达到最大次数据,子Actor将重新生成。 

    码友看代码:

      1 using Proto;
      2 using System;
      3 using System.Collections.Generic;
      4 using System.Linq;
      5 using System.Threading.Tasks;
      6 
      7 namespace P006_Supervision
      8 {
      9     class Program
     10     {
     11         static void Main(string[] args)
     12         {
     13             //设置监督策略,指向SupervisiorMode方法,重启次数为3,两次之间间隔1s
     14             var props = Actor.FromProducer(() => new ShopingCatActor()).WithChildSupervisorStrategy(new OneForOneStrategy(SupervisorMode.Decide, 3, TimeSpan.FromSeconds(1)));
     15             var pid = Actor.Spawn(props);
     16             var user = new User { UserName = "gsw" };
     17 
     18             var sn = 1;
     19             while (true)
     20             {
     21                 Console.WriteLine($"{sn++}--------------------begin-----------------");
     22                 foreach (var goods in user.ShopingCat.Goodses)
     23                 {
     24                     Console.WriteLine(goods);
     25                 }
     26                 Console.WriteLine("---------------------end------------------");
     27                 Console.ReadLine();
     28                 pid.Request(user, pid);
     29             }
     30         }
     31     }
     32     /// <summary>
     33     /// Supervisor 模式
     34     /// </summary>
     35     class SupervisorMode
     36     {
     37         /// <summary>
     38         /// 用来处理异常发生的后续操作
     39         /// </summary>
     40         /// <param name="pid">PID</param>
     41         /// <param name="reason">异常原因,Exception类型</param>
     42         /// <returns></returns>
     43         public static SupervisorDirective Decide(PID pid, Exception reason)
     44         {
     45             Console.WriteLine("   异常发生:" + reason.Message + "   " + pid);
     46             switch (reason)
     47             {
     48                 //重新开始的异常
     49                 case RecoverableException _:
     50                     return SupervisorDirective.Restart;
     51                 //停止异常
     52                 case FatalException _:
     53                     return SupervisorDirective.Stop;
     54                 //其他都上报
     55                 default:
     56                     return SupervisorDirective.Escalate;
     57             }
     58         }
     59     }
     60     /// <summary>
     61     /// 购物车actor
     62     /// </summary>
     63     class ShopingCatActor : IActor
     64     {
     65         ShopingCat _shopingCat;
     66         public ShopingCatActor()
     67         {
     68             _shopingCat = new ShopingCat();
     69             Console.WriteLine("*******************actor ShopingCatActor************************");
     70         }
     71         public Task ReceiveAsync(IContext context)
     72         {
     73             PID childPid;
     74             if (context.Children == null || context.Children.Count == 0)
     75             {
     76                 var props = Actor.FromProducer(() => new GoodsActor());
     77                 childPid = context.Spawn(props);
     78             }
     79             else
     80             {
     81                 childPid = context.Children.First();
     82             }
     83             switch (context.Message)
     84             {
     85                 case User user:
     86                     childPid.Request(_shopingCat, childPid);
     87                     user.ShopingCat = _shopingCat;
     88                     break;
     89             }
     90             return Actor.Done;
     91         }
     92     }
     93     /// <summary>
     94     /// 商品actor
     95     /// </summary>
     96     class GoodsActor : IActor
     97     { 
     98         public Task ReceiveAsync(IContext context)
     99         {
    100             switch (context.Message)
    101             {
    102                 case ShopingCat shopingCat:
    103 
    104                     var goods = new Goods { Name = "红茶", Price = 3.0m, Describe = "统一" };
    105                     //用来随机产生异常
    106                     var random = new Random();
    107                     goods.Quantity = random.Next(1, 3) - 1;
    108                     if (goods.Quantity <= 0)
    109                     {
    110                         throw new RecoverableException("数量不能小于等于0");
    111                     }
    112                     else
    113                     {
    114                         shopingCat.Goodses.Add(goods);
    115                         Console.WriteLine($"添加 {goods} 到购物车里");
    116                     }
    117                     break;
    118             }
    119             return Actor.Done;
    120         }
    121     }
    122     /// <summary>
    123     /// 用户
    124     /// </summary>
    125     class User
    126     {
    127         public ShopingCat ShopingCat { get; set; } = new ShopingCat();
    128         public string UserName { get; set; }
    129     }
    130     /// <summary>
    131     /// 购物车
    132     /// </summary>
    133     class ShopingCat
    134     {
    135         public List<Goods> Goodses
    136         { get; set; } = new List<Goods>();
    137     }
    138     /// <summary>
    139     /// 商品
    140     /// </summary>
    141     class Goods
    142     {
    143         public string Name { get; set; }
    144 
    145         public int Quantity { get; set; }
    146 
    147         public decimal Price { get; set; }
    148 
    149         public string Describe { get; set; }
    150         public override string ToString()
    151         {
    152             return $"Name={Name},Quantity={Quantity},Price={Price},Describe={Describe}";
    153         }
    154     }
    155 
    156 }

    Demo中有三个实体类,用户类,购物车类,商品类,他们的关系一目了解,聚合关系。有两个Actor,购物车Actor(ShopingCatActor),商品Actor(GoodsActor),商品Actor是购物车Actor子Actor;ShopingCatActor下有监督策略,在

    SupervisorMode下的Decide方法中,处理不同的异常,采用不同的Actor策略。GoodsActor中,添加商品时根据数量来决定是否产生异常。

    看运行结果:

    注意看ID $1/$2,是在发生四次异常后才生成$1/$3的(这个与文档说法有出入,也许是我理解有问题,是重启3次,不是启动3次)

  • 相关阅读:
    2016-2017(2)数据结构课程小结
    顺序表2种结构体构造方法
    有理数四则运算的实验报告小结
    20165230 结对编程项目-四则运算 阶段总结
    20165230 《Java程序设计》实验二(Java面向对象程序设计)实验报告
    20165230 2017-2018-2 《Java程序设计》第7周学习总结
    20165230 2017-2018-2 《Java程序设计》第6周学习总结
    20165230 《Java程序设计》实验一(Java开发环境的熟悉)实验报告
    20165230 2017-2018-2 《Java程序设计》第5周学习总结
    20165230 2017-2018-2 《Java程序设计》第4周学习总结
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/9564010.html
Copyright © 2011-2022 走看看