Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* 撮合通知异步执行与停用退订(C407,GFX-1105,GitHub #733):`ICapabilityEventBus.Subscribe` 返回幂等 `IDisposable` 退订句柄(void → IDisposable 为二进制破坏性变更——包族消费方需重新编译;源码侧忽略返回值的既有调用不受影响);online-match 模块撮合分配事件回调改为纯入队(移除同步总线回调内 `ResolveAssignmentAsync` / `session.WriteAsync` 两处 `GetAwaiter().GetResult()` 死锁面),新增 `match-assignment-notification-tick` 每轮有限批次(64)异步解析并推送(条目级失败不阻断同批其余条目,异常交调度器既有日志路径);`DeactivateAsync` 停用收口——关闭入队、退订、清空待处理并等待在途批次完成,热更/停机后旧模块零通知。回归 13 例:总线退订契约 5 + 模块生命周期 8(含对旧同步实现确定性红的发布不同步解析 / 停用退订 / 停用清空 / 容错批次)。

* 举报入口频控与未结案去重(C405,GFX-1115):举报提交接入双固定窗口限流(`OnlineSocialOptions.Report.MaximumSubmissionsPerMinute=5` / `MaximumSubmissionsPerDay=50`,键=租户/App/举报人,超限 7001 且不落案件不发事件,分钟窗惰性清扫仅删双窗均过期的桶);`IOnlineReportStore.SaveIfAbsentAsync` 升级为两层原子唯一(案件标识重放 + 未结案组合键「举报人+被举报人+场景」,Submitted/Reviewing 占位、终态释放),重复举报返回原案件原证据且仅首建发 `ReportChanged`;`ReplaceAsync` 身份三要素不可改、终态释放与新占位归属在 CAS 同锁维护;`OnlineSocialDecisionService` 构造新增必填 `OnlineReportOptions`,宿主自定义举报存储必须遵循同一原子唯一性语义
* Wrapper 生成器崩溃止血与不可编译产物清理(C431,GFX-1171,GitHub #917):`[TimeOut]` 实参防御式解析(仅数值字面量可静态求值——常量名/缺参/空参/表达式/下划线开头的常量名输出 Error 诊断并降级为框架默认超时,不再令生成器整体崩溃丢失全部 wrapper);`GetFullName` 重写为向上收集命名空间与嵌套类型段(无命名空间代理返回类型链短名,顺带覆盖 struct/enum 容器形态);`Tools.GetNameSpace` 取真命名空间(首个 `+` 前最后一个 `.`,无命名空间返回空串且不发射空 using),嵌套代理基类改容器限定名 `Outer.Inner`、wrapper 类名携带容器链(同命名空间同名代理不再碰撞);partial 合并键升为完全限定名(跨命名空间同名无关类不再产生幽灵 Wrapper);async 被包装方法统一 `return await`(修复非泛型 `async Task`/`async ValueTask` 生成体不可编译);含 `ref/out/in` 参数与 `[Discard]` 返回类型非 Task/ValueTask(按类型名最后一段比较,全限定名不误报)的方法报 Error 且不进入生成面(校验先行);`[Discard]` 非 ThreadSafe 入队 lambda 改 `async ()=> await` 统一绑定 `EnqueueAsync(Func<Task>)` 重载(ValueTask 一次性消费契约不再被违反)。新增 16 例生成器测试(含独立审查 R1/R2/R3 修复钉住),既有 3 例 Discard lambda 断言随契约更新。

### Added
* 行版本条件写内存管线收口共享助手(C409,GFX-1117):新增 `GameFrameX.DataBase/Abstractions/RowVersionCasWriteHelper` 与 `RowVersionBackfillWriteHelper`——`UpdateIfRowVersionAsync`(CAS)与 `UpdateIfRowVersionIsNullAsync`(回填)两原语在 Mongo/PostgreSQL/SQLite 三 Provider 重复的内存侧样板(Id 一致性校验、版本对齐 + checked 递增、写库前 `ToBytes()` 快照、失败回滚 / 成功精确提交)收敛为单一事实源,Provider 仅保留谓词 / 语句 / 重试外壳等写库差异;语义零变化(失败回滚、异常不回滚、`long.MaxValue` 溢出写库前抛出、SQLite null 守卫现状均冻结),回归依托 `DatabaseConditionalWritePrimitivesTests` 既有套件。
Expand Down
7 changes: 4 additions & 3 deletions GameFrameX.Hotfix.WrapperGenerator/Agent/AgentInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ public class AgentInfo
public string Name { get; set; }

/// <summary>
/// 获取或设置父类(被包装的代理类)名称。
/// 获取或设置父类(被包装的代理类)引用名:剥离命名空间后的容器限定名,嵌套代理为 <c>Outer.Inner</c> 形态。
/// </summary>
/// <remarks>
/// Gets or sets the parent (wrapped agent) class name.
/// Gets or sets the parent (wrapped agent) class reference: the container-qualified name with the
/// namespace stripped; nested agents use the <c>Outer.Inner</c> form. Top-level agents equal the simple name.
/// </remarks>
/// <value>父类名称 / Parent class name</value>
/// <value>父类引用名 / Parent class reference name</value>
public string Super { get; set; }

/// <summary>
Expand Down
5 changes: 3 additions & 2 deletions GameFrameX.Hotfix.WrapperGenerator/Agent/AgentTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
else
{
TemplateStringBuilder.AppendLine("\t\t\tlong callChainId = GameFrameX.Core.Actors.Impl.WorkerActor.NextChainId();");
TemplateStringBuilder.AppendLine($"\t\t\t_ = base.Actor.WorkerActor.EnqueueAsync(()=>base.{infoMethod.Name}{infoMethod.Typeparams}({infoMethod.ParamString}), callChainId, true{BuildTimeoutArgument(infoMethod)});");
TemplateStringBuilder.AppendLine($"\t\t\t_ = base.Actor.WorkerActor.EnqueueAsync(async ()=> await base.{infoMethod.Name}{infoMethod.Typeparams}({infoMethod.ParamString}), callChainId, true{BuildTimeoutArgument(infoMethod)});");
}

TemplateStringBuilder.AppendLine($"\t\t\treturn {infoMethod.ReturnType}.CompletedTask;");
Expand All @@ -146,7 +146,8 @@
/// <param name="infoMethod">方法元数据 / Method metadata</param>
private static void AppendInvocationBody(MethodInfoData infoMethod)
{
var needAwait = infoMethod.IsAsync && infoMethod.ReturnType.Contains("<");
// async 方法转发底层任务必须 await(非泛型 Task/ValueTask 同样如此);是否泛型与该判定无关
var needAwait = infoMethod.IsAsync;
TemplateStringBuilder.AppendLine("\t\t\t(bool needEnqueue, long chainId)= base.Actor.WorkerActor.IsNeedEnqueue();");
TemplateStringBuilder.AppendLine("\t\t\tif (!needEnqueue)");
TemplateStringBuilder.AppendLine("\t\t\t{");
Expand All @@ -161,10 +162,10 @@
/// <remarks>
/// Builds the timeout argument fragment: emits ", <ms>" only when [TimeOut] was explicitly configured;
/// otherwise the argument is omitted so EnqueueAsync's framework default applies.
/// </remarks>

Check warning on line 165 in GameFrameX.Hotfix.WrapperGenerator/Agent/AgentTemplate.cs

View workflow job for this annotation

GitHub Actions / topology-equivalence

XML comment has badly formed XML -- 'End tag 'remarks' does not match the start tag 'ms'.'
/// <param name="infoMethod">方法元数据 / Method metadata</param>
/// <returns>超时实参片段(含前导逗号)或空串 / The timeout argument fragment (with leading comma) or an empty string</returns>
private static string BuildTimeoutArgument(MethodInfoData infoMethod)

Check warning on line 168 in GameFrameX.Hotfix.WrapperGenerator/Agent/AgentTemplate.cs

View workflow job for this annotation

GitHub Actions / topology-equivalence

XML comment has badly formed XML -- 'Expected an end tag for element 'remarks'.'
{
return infoMethod.HasTimeout ? ", " + infoMethod.TimeOut : string.Empty;
}
Expand Down
Loading
Loading