当前位置: 首页 > news >正文

Orleans Stream SubscriptionId 生成机制详解

概述

在 Orleans 流系统中,subscriptionId 是用于标识流订阅的唯一标识符。它有两种类型:显式订阅隐式订阅,每种类型都有不同的生成机制。

1. 订阅类型分类

显式订阅 (Explicit Subscription)

  • 通过代码显式调用 SubscribeAsync() 方法创建的订阅
  • 使用随机生成的 GUID
  • 在 GUID 的最后字节的高位设置为 0

隐式订阅 (Implicit Subscription)

  • 基于 Grain 类型和流命名空间自动匹配的订阅
  • 使用确定性算法生成 GUID
  • 在 GUID 的最后字节的高位设置为 1

2. 生成流程

2.1 显式订阅 ID 生成

// 在 GrainBasedPubSubRuntime.cs 中
public GuidId CreateSubscriptionId(QualifiedStreamId streamId, GrainId streamConsumer)
{// 1. 生成随机 GUIDGuid subscriptionId = Guid.NewGuid();// 2. 标记为显式订阅(清除最后字节的高位)subscriptionId = SubscriptionMarker.MarkAsExplicitSubscriptionId(subscriptionId);// 3. 包装为 GuidIdreturn GuidId.GetGuidId(subscriptionId);
}

2.2 隐式订阅 ID 生成

// 在 ImplicitStreamSubscriberTable.cs 中
private Guid MakeSubscriptionGuid(GrainType grainType, QualifiedStreamId streamId)
{Span<byte> bytes = stackalloc byte[16];// 1. 使用 Grain 类型的哈希码BinaryPrimitives.WriteUInt32LittleEndian(bytes, grainType.GetUniformHashCode());// 2. 使用 StreamId 的哈希码BinaryPrimitives.WriteUInt32LittleEndian(bytes[4..], streamId.StreamId.GetUniformHashCode());// 3. 使用 StreamId 的键索引BinaryPrimitives.WriteUInt32LittleEndian(bytes[8..], streamId.StreamId.GetKeyIndex());// 4. 使用 Provider 名称的稳定哈希BinaryPrimitives.WriteUInt32LittleEndian(bytes[12..], StableHash.ComputeHash(streamId.ProviderName));// 5. 标记为隐式订阅(设置最后字节的高位)return SubscriptionMarker.MarkAsImplictSubscriptionId(new(bytes));
}

3. 订阅标记机制

3.1 SubscriptionMarker 类

internal static class SubscriptionMarker
{// 标记为显式订阅:清除最后字节的高位 (0x7F)internal static Guid MarkAsExplicitSubscriptionId(Guid subscriptionGuid){return MarkSubscriptionGuid(subscriptionGuid, false);}// 标记为隐式订阅:设置最后字节的高位 (0x80)internal static Guid MarkAsImplictSubscriptionId(Guid subscriptionGuid){return MarkSubscriptionGuid(subscriptionGuid, true);}// 检查是否为隐式订阅internal static bool IsImplicitSubscription(Guid subscriptionGuid){Span<byte> guidBytes = stackalloc byte[16];subscriptionGuid.TryWriteBytes(guidBytes);// 检查最后字节的高位是否设置return (guidBytes[15] & 0x80) != 0;}
}

4. 完整生成流程

4.1 显式订阅流程

  1. 用户调用订阅方法

    await stream.SubscribeAsync(observer);
    
  2. StreamConsumer 创建订阅 ID

    // 在 StreamConsumer.cs 中
    GuidId subscriptionId = pubSub.CreateSubscriptionId(stream.InternalStreamId, myGrainReference.GetGrainId());
    
  3. GrainBasedPubSubRuntime 生成 ID

    Guid subscriptionId = SubscriptionMarker.MarkAsExplicitSubscriptionId(Guid.NewGuid());
    
  4. 设置观察者

    var subscriptionHandle = myExtension.SetObserver(subscriptionId, stream, observer, batchObserver, token, filterData);
    

4.2 隐式订阅流程

  1. 系统检查隐式订阅资格

    // 在 ImplicitStreamPubSub.cs 中
    if (!implicitTable.TryGetImplicitSubscriptionGuid(grainId, streamId, out subscriptionGuid))
    {throw new ArgumentOutOfRangeException(streamId.ToString(), "Only implicit subscriptions are supported.");
    }
    
  2. ImplicitStreamSubscriberTable 生成确定性 ID

    // 基于 Grain 类型、StreamId 和 Provider 名称生成确定性 GUID
    subscriptionId = MakeSubscriptionGuid(grainId.Type, streamId);
    
  3. 标记为隐式订阅

    return SubscriptionMarker.MarkAsImplictSubscriptionId(new(bytes));
    

5. 关键特性

5.1 唯一性保证

  • 显式订阅:使用 Guid.NewGuid() 保证全局唯一性
  • 隐式订阅:使用确定性算法,相同输入产生相同输出

5.2 类型识别

  • 通过 GUID 最后字节的高位区分订阅类型
  • 0x80 = 隐式订阅,0x7F = 显式订阅

5.3 性能优化

  • 隐式订阅使用确定性算法,避免重复计算
  • 使用 Span<byte>stackalloc 减少内存分配

6. 使用场景

6.1 显式订阅

  • 用户主动订阅特定流
  • 需要精确控制订阅行为
  • 支持取消订阅

6.2 隐式订阅

  • 基于命名空间自动匹配
  • 简化开发者的订阅逻辑
  • 适用于广播场景

7. 总结

Orleans 的 subscriptionId 生成机制设计精巧,通过不同的生成策略和标记机制,既保证了唯一性,又支持了显式和隐式两种订阅模式。这种设计在保证性能的同时,提供了灵活的流订阅管理能力。

http://www.dtcms.com/a/499735.html

相关文章:

  • FMIT,一款专业的乐器调音助手
  • 医疗器械招商网站大全建一个信息 类网站
  • 不用域名推广网站开源网站后台管理系统
  • 欧司朗与日亚签署广泛的知识产权协议
  • Kotlin 与 Java 互操作中常用注解
  • 计算机操作系统:程序的装入与链接
  • 怎么建设网站手机网站制作价格在线考试类网站怎么做
  • 3.1 栈
  • 国贸网站建设公司服务专业的网站建站公司
  • 手写观察者模式:原理、实现与应用
  • 商贸有限公司网站案例wordpress模版安装
  • Rclone、rsync、Docker 的 COPY/ADD:路径末尾加不加「/」的含义大不相同!
  • 【复习】计网每日一题1016--可分配
  • 【STM32】hal库 多通道ADC(+DMA)采集 连续模式
  • 网站收录量是什么意思开网站卖茶要怎么做
  • 软著下证又又+1
  • 常见分析方法与对应图表汇总
  • 【图像处理】常见图像插值算法与应用
  • Python爬虫入门:从零到数据采集
  • 免费创建app网站网站推广的基本方法是哪四个
  • 建设网站需要的资金清单建设银行网站会员怎么用
  • 深度学习——YOLO 原理与各版本演化
  • 实验室安全准入考试答案
  • 设计网络网站郑州专业公司网站建设公司
  • 17做网店一样的网站html投票代码
  • 网站建设与维护薪资网页版梦幻西游答题器
  • Form表单._表单元素(本文为个人学习笔记,内容整理自哔哩哔哩UP主【非学者勿扰】的公开课程。 > 所有知识点归属原作者,仅作非商业用途分享)
  • 合肥企业做网站wap游戏中心
  • React 02
  • 营销网站定制深圳设计展2022