日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Actor-ES框架:Actor编写-ESGrain与ESRepGrain

發(fā)布時(shí)間:2023/12/4 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Actor-ES框架:Actor编写-ESGrain与ESRepGrain 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
ESGrain
生命周期

Ray中ESGrain繼承自Grain擴(kuò)展了Grain的生命周期。Grain的生命周期參加文檔附錄:1-Grain生命周期-譯注.md

ESGrain重寫了Grain的OnActivateAsync方法。ESGrain的初始化過程如下:

  • 初始化ESGrain中的State

    • 調(diào)用ReadSnapshotAsync()讀快照。

    • 如果沒有獲得快照,調(diào)用InitState()根據(jù)InitState()中代碼初始化ESGrain,InitState()是虛方法,可以被具體的ESGrain重寫,以自定義初始化。

  • 讀取事件庫,重放事件,獲得最新的State。


小技巧:在實(shí)際開發(fā)中,可以重寫InitState(),在其中根據(jù)關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)自定義state的初始化。


使用

State

ESGrain的數(shù)據(jù)存儲在State中,當(dāng)ESGrain被激活后State數(shù)據(jù)存儲在內(nèi)存中,持久化會存儲為快照。定義ESGrain時(shí),需要定義State,實(shí)現(xiàn)IState接口,序列化默認(rèn)使用protocol buffer,State類要添加protocol buffer特性。IState接口定義的是State的基礎(chǔ)部分,即示例中的base部分,base之外的是當(dāng)前actor需要的要存儲的數(shù)據(jù)。

示例代碼:

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)] public class AccountState : IState<string> { ? ? #region base ? ? public string StateId { get; set; } ? ? public uint Version { get; set; } ? ? public uint DoingVersion { get; set; } ? ? public DateTime VersionTime { get; set; } ? ? #endregion ? ? public decimal Balance { get; set; } }

Event

ESGrain之間通過Event傳遞數(shù)據(jù),Event編寫請參考Event編寫.md

EventHandles

使用ESGrain引發(fā)事件,一般出于兩種考慮:1.傳遞數(shù)據(jù)到Handler;2.修改State中的數(shù)據(jù)。修改ESGrain中的數(shù)據(jù)通過EventHandle中的代碼實(shí)現(xiàn)。

使用:

  • 實(shí)現(xiàn)IEventHandle

  • 在Apply中實(shí)現(xiàn)定義要處理的事件。

    示例代碼:

public class AccountEventHandle : IEventHandle

{

? public void Apply(object state, IEvent evt)

? {

? ? ? if (state is AccountState actorState)

? ? ? {

? ? ? ? ? switch (evt)

? ? ? ? ? {

? ? ? ? ? ? ? case AmountAddEvent value: AmountAddEventHandle(actorState, value); break;

? ? ? ? ? ? ? case AmountTransferEvent value: AmountTransferEventHandle(actorState, value); break;

? ? ? ? ? ? ? default: break;

? ? ? ? ? }

? ? ? }

? }

? private void AmountTransferEventHandle(AccountState state, AmountTransferEvent evt)

? {

? ? ? state.Balance = evt.Balance;

? }

? private void AmountAddEventHandle(AccountState state, AmountAddEvent evt)

? {

? ? ? state.Balance = evt.Balance;

? }

}



  • State中的數(shù)據(jù)存儲在內(nèi)存中,大量的數(shù)據(jù)存在State中,在某種角度可以將State看做內(nèi)存數(shù)據(jù)庫。

  • Ray中,修改State的數(shù)據(jù)要通過EventHandle實(shí)現(xiàn)(只有一種方式)。

ESGrain種類

  • Ray默認(rèn)提供了MongoESGrain和SqlGrain兩類。

    ESGrain<K, S, W>說明:

  • K:StateId的類型。

  • S:ESGrain的State。

  • W:MessageInfo。

完整ESGrain示例

編寫ESGrain時(shí)

  • 明確RabbitPub。

  • 明確MongoStorage。

  • 繼承MongoESGrain或SqlGrain。

  • 實(shí)現(xiàn)ESGrain接口。

  • 如果需要重寫OnActivateAsync。

  • 編寫感興趣的Actor方法

  • 如果需要發(fā)送事件:1.定義事件;2.編寫EventHandler。

[RabbitMQ.RabbitPub("Account", "account")]

[MongoStorage("Test", "Account")]

public sealed class Account : MongoESGrain<String, AccountState, IGrains.MessageInfo>, IAccount

{

? ? protected override string GrainId => this.GetPrimaryKeyString();


? ? static IEventHandle _eventHandle = new AccountEventHandle();

? ? protected override IEventHandle EventHandle => _eventHandle;


? ? public override Task OnActivateAsync()

? ? {

? ? ? ? return base.OnActivateAsync();

? ? }

? ? public Task Transfer(string toAccountId, decimal amount)

? ? {

? ? ? ? var evt = new AmountTransferEvent(toAccountId, amount, this.State.Balance - amount);

? ? ? ? return RaiseEvent(evt).AsTask();

? ? }

? ? public Task AddAmount(decimal amount, string uniqueId = null)

? ? {

? ? ? ? var evt = new AmountAddEvent(amount, this.State.Balance + amount);

? ? ? ? return RaiseEvent(evt, uniqueId: uniqueId).AsTask();

? ? }

? ? [AlwaysInterleave]

? ? public Task<decimal> GetBalance()

? ? {

? ? ? ? return Task.FromResult(this.State.Balance);

? ? }

}

ESRepGrain

ESGrain默認(rèn)是主Actor,當(dāng)單個(gè)Actor壓力過大時(shí),可以實(shí)現(xiàn)該actor的副本actor,副本actor主要用來處理:1.讀的操作;2.其他非寫的異步操作。

主actor與副本actor之間保持同步的機(jī)制:
  • 主actor引發(fā)事件,在CoreHandler里將消息傳遞給副本actor,在副本actor里面重放該事件。

  • 主actor與副本actor持久化的是同一個(gè)快照庫、事件庫。也會從同一個(gè)庫里激活。

  • 生命周期

    與主actor類似。

    使用

    與ESGrain類似,對比如下:

    ESGrainESRepGrain
    明確RabbitPub不需要
    明確MongoStorage明確MongoStorage
    繼承MongoESGrain或SqlGrain繼承MongoESRepGrain或SqlRepGrain
    實(shí)現(xiàn)ESGrain接口自定義的副本Actor接口
    如果需要重寫OnActivateAsync如果需要重寫OnActivateAsync
    編寫感興趣的Actor方法編寫感興趣的Actor方法
    如果需要發(fā)送事件:1.定義事件;2.編寫EventHandler不會引發(fā)事件
    示例

    [MongoStorage("Test", "Account")]

    public sealed class AccountRep : MongoESRepGrain<String, AccountState, MessageInfo>, IAccountRep

    {

    ? ? ?protected override string GrainId => this.GetPrimaryKeyString();


    ? ? ?static IEventHandle _eventHandle = new AccountEventHandle();

    ? ? ?protected override IEventHandle EventHandle => _eventHandle;


    ? ? ?public Task<decimal> GetBalance()

    ? ? ?{

    ? ? ? ? ?return Task.FromResult(this.State.Balance);

    ? ? ?}

    }

    原文地址:http://www.cnblogs.com/CharlesZHENG/p/8438057.html


    .NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

    總結(jié)

    以上是生活随笔為你收集整理的Actor-ES框架:Actor编写-ESGrain与ESRepGrain的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。