diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml
index d1794a4..5d148cc 100644
--- a/.github/workflows/dotnet-build.yml
+++ b/.github/workflows/dotnet-build.yml
@@ -8,7 +8,16 @@ jobs:
runs-on: windows-latest
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v6
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: |
+ 3.1.x
+ 6.0.x
+ 8.0.x
+ 9.0.x
+ 10.0.x
- name: Build with dotnet
run: dotnet build --configuration Release
diff --git a/.github/workflows/nuget-tag-publish.yml b/.github/workflows/nuget-tag-publish.yml
index 2a0cc6f..a0f6af1 100644
--- a/.github/workflows/nuget-tag-publish.yml
+++ b/.github/workflows/nuget-tag-publish.yml
@@ -11,7 +11,19 @@ jobs:
runs-on: windows-latest
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v6
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v5
+ with:
+ dotnet-version: |
+ 3.1.x
+ 6.0.x
+ 8.0.x
+ 9.0.x
+ 10.0.x
+
+ - name: Add .NET global tools to PATH
+ run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH
- name: Install dotnet tool
run: dotnet tool install -g dotnetCampus.TagToVersion
@@ -24,16 +36,10 @@ jobs:
dotnet build --configuration Release
dotnet pack --configuration Release --no-build
- - name: Install Nuget
- uses: nuget/setup-nuget@v1
- with:
- nuget-version: '5.x'
-
- - name: Add private GitHub registry to NuGet
- run: |
- nuget sources add -name github -Source https://nuget.pkg.github.com/dotnet-campus/index.json -Username dotnet-campus -Password ${{ secrets.GITHUB_TOKEN }}
-
- - name: Push generated package to GitHub registry
+ - name: Publish
run: |
- nuget push .\bin\Release\*.nupkg -Source github -SkipDuplicate
- nuget push .\bin\Release\*.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NugetKey }}
+ dotnet nuget push ".\bin\Release\*.nupkg" --api-key ${{ secrets.NugetKey }} --source https://api.nuget.org/v3/index.json --skip-duplicate
+ dotnet nuget push ".\bin\Release\*.nupkg" \
+ --api-key ${{ secrets.GITHUB_TOKEN }} \
+ --source https://nuget.pkg.github.com/${{ github.repository_owner }} \
+ --skip-duplicate
\ No newline at end of file
diff --git a/src/LightWorkFlowManager.Tests/MessageWorkerManagerTest.cs b/src/LightWorkFlowManager.Tests/MessageWorkerManagerTest.cs
index e2ca92a..b10c1ab 100644
--- a/src/LightWorkFlowManager.Tests/MessageWorkerManagerTest.cs
+++ b/src/LightWorkFlowManager.Tests/MessageWorkerManagerTest.cs
@@ -12,11 +12,17 @@
namespace LightWorkFlowManager.Tests;
+///
+/// `MessageWorkerManager` 相关测试。
+///
[TestClass]
public class MessageWorkerManagerTest
{
private const int UnknownError = 7000;
+ ///
+ /// 验证工作器管理器在失败、重试与异常场景下的行为。
+ ///
[ContractTestCase]
public void RunFail()
{
@@ -120,6 +126,14 @@ await Assert.ThrowsExceptionAsync(async ()
});
}
+ ///
+ /// 创建用于测试的工作器管理器。
+ ///
+ /// 可选的服务提供器。
+ /// 可选的任务标识。
+ /// 可选的任务名称。
+ /// 重试次数。
+ /// 测试用工作器管理器实例。
public static MessageWorkerManager GetTestMessageWorkerManager(IServiceProvider? serviceProvider = null,
string? taskId = null, string? taskName = null, int retryCount = 3)
{
@@ -128,6 +142,10 @@ public static MessageWorkerManager GetTestMessageWorkerManager(IServiceProvider?
return messageWorkerManager;
}
+ ///
+ /// 构建测试用服务提供器。
+ ///
+ /// 测试用服务提供器实例。
public static IServiceProvider BuildServiceProvider()
{
var serviceCollection = new ServiceCollection();
diff --git a/src/LightWorkFlowManager.Tests/MessageWorkerTest.cs b/src/LightWorkFlowManager.Tests/MessageWorkerTest.cs
index 91df4dd..741d04f 100644
--- a/src/LightWorkFlowManager.Tests/MessageWorkerTest.cs
+++ b/src/LightWorkFlowManager.Tests/MessageWorkerTest.cs
@@ -11,9 +11,15 @@
namespace LightWorkFlowManager.Tests;
+///
+/// `MessageWorker` 相关测试。
+///
[TestClass]
public class MessageWorkerTest
{
+ ///
+ /// 验证工作器内部可以继续运行其他工作器。
+ ///
[ContractTestCase]
public void RunWorkerOnWorker()
{
diff --git a/src/LightWorkFlowManager.Tests/ProgressCompositorTest.cs b/src/LightWorkFlowManager.Tests/ProgressCompositorTest.cs
index 04ca90f..aa76072 100644
--- a/src/LightWorkFlowManager.Tests/ProgressCompositorTest.cs
+++ b/src/LightWorkFlowManager.Tests/ProgressCompositorTest.cs
@@ -6,9 +6,15 @@
namespace LightWorkFlowManager.Tests;
+///
+/// `ProgressCompositor` 相关测试。
+///
[TestClass]
public class ProgressCompositorTest
{
+ ///
+ /// 验证子进度合成后的进度计算结果。
+ ///
[ContractTestCase]
public void TestSubProgressReport()
{
diff --git a/src/LightWorkFlowManager/Contexts/IWorkerContext.cs b/src/LightWorkFlowManager/Contexts/IWorkerContext.cs
index 52520c8..f9ca996 100644
--- a/src/LightWorkFlowManager/Contexts/IWorkerContext.cs
+++ b/src/LightWorkFlowManager/Contexts/IWorkerContext.cs
@@ -11,15 +11,15 @@ public interface IWorkerContext
///
/// 获取上下文信息
///
- ///
- /// 如果获取不到,返回空
+ /// 上下文类型。
+ /// 如果获取不到则返回空。
T? GetContext();
///
/// 设置上下文信息
///
- ///
- ///
+ /// 上下文类型。
+ /// 要保存的上下文对象。
void SetContext(T context);
}
@@ -31,9 +31,9 @@ public static class MessageContextExtension
///
/// 获取一定存在的上下文信息
///
- ///
- ///
- ///
+ /// 上下文类型。
+ /// 工作器上下文。
+ /// 已存在的上下文对象。
/// 如果上下文信息不存在,就抛出异常
public static T GetEnsureContext(this IWorkerContext workerContext)
{
diff --git a/src/LightWorkFlowManager/Contexts/WorkFlowErrorCode.cs b/src/LightWorkFlowManager/Contexts/WorkFlowErrorCode.cs
index df0467b..7bd6f55 100644
--- a/src/LightWorkFlowManager/Contexts/WorkFlowErrorCode.cs
+++ b/src/LightWorkFlowManager/Contexts/WorkFlowErrorCode.cs
@@ -12,6 +12,8 @@ namespace DC.LightWorkFlowManager.Contexts;
///
/// 创建错误码
///
+ /// 错误码数值。
+ /// 错误码对应的可读信息。
public WorkFlowErrorCode(int code, string message)
{
Code = code;
@@ -38,8 +40,8 @@ public WorkFlowErrorCode(int code, string message)
///
/// 追加信息
///
- ///
- ///
+ /// 要追加的描述信息。
+ /// 追加描述后的错误码。
public WorkFlowErrorCode AppendMessage(string? appendMessage)
{
if (appendMessage == null)
@@ -55,7 +57,8 @@ public WorkFlowErrorCode AppendMessage(string? appendMessage)
///
/// 隐式转换为 int 类型
///
- ///
+ /// 工作流错误码。
+ /// 错误码数值。
public static implicit operator int(WorkFlowErrorCode code)
{
return code.Code;
@@ -64,7 +67,8 @@ public static implicit operator int(WorkFlowErrorCode code)
///
/// 从 int 类型隐式转换为错误信息
///
- ///
+ /// 错误码数值。
+ /// 对应的工作流错误码。
public static implicit operator WorkFlowErrorCode(int code)
{
if (ErrorCodeDictionary.TryGetValue(code, out var value))
@@ -107,9 +111,9 @@ public override int GetHashCode()
///
/// 判断相等
///
- ///
- ///
- ///
+ /// 左侧错误码。
+ /// 右侧错误码。
+ /// 两个错误码是否相等。
public static bool operator ==(WorkFlowErrorCode left, WorkFlowErrorCode right)
{
return left.Equals(right);
@@ -118,9 +122,9 @@ public override int GetHashCode()
///
/// 判断不相等
///
- ///
- ///
- ///
+ /// 左侧错误码。
+ /// 右侧错误码。
+ /// 两个错误码是否不相等。
public static bool operator !=(WorkFlowErrorCode left, WorkFlowErrorCode right)
{
return !left.Equals(right);
diff --git a/src/LightWorkFlowManager/Contexts/WorkerContext.cs b/src/LightWorkFlowManager/Contexts/WorkerContext.cs
index e1f5a23..84f38bc 100644
--- a/src/LightWorkFlowManager/Contexts/WorkerContext.cs
+++ b/src/LightWorkFlowManager/Contexts/WorkerContext.cs
@@ -3,8 +3,12 @@
namespace DC.LightWorkFlowManager.Contexts;
+///
+/// 提供基于类型索引的工作器上下文实现。
+///
public class WorkerContext : IWorkerContext
{
+ ///
[System.Diagnostics.DebuggerStepThrough]
public T? GetContext()
{
@@ -16,6 +20,7 @@ public class WorkerContext : IWorkerContext
return default;
}
+ ///
public void SetContext(T context)
{
_contextDictionary[typeof(T)] = context;
diff --git a/src/LightWorkFlowManager/Exceptions/MessageWorkerException.cs b/src/LightWorkFlowManager/Exceptions/MessageWorkerException.cs
index 2114fef..ff8de22 100644
--- a/src/LightWorkFlowManager/Exceptions/MessageWorkerException.cs
+++ b/src/LightWorkFlowManager/Exceptions/MessageWorkerException.cs
@@ -11,7 +11,7 @@ public class MessageWorkerException : WorkFlowException
///
/// 工作过程的异常
///
- ///
+ /// 工作流错误码。
/// 默认 false 表示不能重试
public MessageWorkerException(WorkFlowErrorCode errorCode, bool canRetryWorker = false)
{
@@ -22,6 +22,8 @@ public MessageWorkerException(WorkFlowErrorCode errorCode, bool canRetryWorker =
///
/// 工作过程的异常
///
+ /// 工作流错误码。
+ /// 导致当前异常的内部异常。
public MessageWorkerException(WorkFlowErrorCode errorCode, Exception innerException) : base(errorCode.Message, innerException)
{
ErrorCode = errorCode;
@@ -32,7 +34,12 @@ public MessageWorkerException(WorkFlowErrorCode errorCode, Exception innerExcept
/// 是否可以重试
///
public bool CanRetryWorker { get; }
+
+ ///
+ /// 获取当前异常对应的工作流错误码。
+ ///
public WorkFlowErrorCode ErrorCode { get; }
+ ///
public override string Message => ErrorCode.Message;
}
diff --git a/src/LightWorkFlowManager/Exceptions/MessageWorkerInputArgumentException.cs b/src/LightWorkFlowManager/Exceptions/MessageWorkerInputArgumentException.cs
index c694ad6..bf628bb 100644
--- a/src/LightWorkFlowManager/Exceptions/MessageWorkerInputArgumentException.cs
+++ b/src/LightWorkFlowManager/Exceptions/MessageWorkerInputArgumentException.cs
@@ -7,6 +7,10 @@ namespace DC.LightWorkFlowManager.Exceptions;
///
public class MessageWorkerInputArgumentException : MessageWorkerException
{
+ ///
+ /// 使用指定错误码初始化输入参数异常。
+ ///
+ /// 输入参数错误对应的工作流错误码。
public MessageWorkerInputArgumentException(WorkFlowErrorCode errorCode) : base(errorCode,canRetryWorker: false)
{
}
diff --git a/src/LightWorkFlowManager/Exceptions/MessageWorkerInputNotFoundException.cs b/src/LightWorkFlowManager/Exceptions/MessageWorkerInputNotFoundException.cs
index c8deada..f859232 100644
--- a/src/LightWorkFlowManager/Exceptions/MessageWorkerInputNotFoundException.cs
+++ b/src/LightWorkFlowManager/Exceptions/MessageWorkerInputNotFoundException.cs
@@ -7,6 +7,10 @@ namespace DC.LightWorkFlowManager.Exceptions;
///
public class MessageWorkerInputNotFoundException : InvalidOperationException, IWorkFlowException
{
+ ///
+ /// 使用指定错误消息初始化异常。
+ ///
+ /// 异常消息。
public MessageWorkerInputNotFoundException(string? message) : base(message)
{
}
diff --git a/src/LightWorkFlowManager/Exceptions/WorkFlowException.cs b/src/LightWorkFlowManager/Exceptions/WorkFlowException.cs
index a01c6ac..26a04b4 100644
--- a/src/LightWorkFlowManager/Exceptions/WorkFlowException.cs
+++ b/src/LightWorkFlowManager/Exceptions/WorkFlowException.cs
@@ -8,18 +8,35 @@ namespace DC.LightWorkFlowManager.Exceptions;
///
public abstract class WorkFlowException : Exception, IWorkFlowException
{
+ ///
+ /// 初始化工作流异常。
+ ///
protected WorkFlowException()
{
}
+ ///
+ /// 使用序列化信息初始化工作流异常。
+ ///
+ /// 保存序列化对象数据的对象。
+ /// 有关源或目标的上下文信息。
protected WorkFlowException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
+ ///
+ /// 使用指定错误消息初始化工作流异常。
+ ///
+ /// 异常消息。
protected WorkFlowException(string? message) : base(message)
{
}
+ ///
+ /// 使用指定错误消息和内部异常初始化工作流异常。
+ ///
+ /// 异常消息。
+ /// 导致当前异常的内部异常。
protected WorkFlowException(string? message, Exception? innerException) : base(message, innerException)
{
}
diff --git a/src/LightWorkFlowManager/Exceptions/WorkerContextNotFoundException.cs b/src/LightWorkFlowManager/Exceptions/WorkerContextNotFoundException.cs
index c228b9c..c9a2db4 100644
--- a/src/LightWorkFlowManager/Exceptions/WorkerContextNotFoundException.cs
+++ b/src/LightWorkFlowManager/Exceptions/WorkerContextNotFoundException.cs
@@ -1,13 +1,24 @@
namespace DC.LightWorkFlowManager.Exceptions;
+///
+/// 表示无法从工作器上下文中找到指定类型数据的异常。
+///
public class WorkerContextNotFoundException : WorkFlowException
{
+ ///
+ /// 使用缺失的上下文键初始化异常。
+ ///
+ /// 缺失的上下文键。
public WorkerContextNotFoundException(string key)
{
Key = key;
}
+ ///
+ /// 获取缺失的上下文键。
+ ///
public string Key { get; }
+ ///
public override string Message => $"Can not find {Key}";
}
diff --git a/src/LightWorkFlowManager/MessageWorkerManager.cs b/src/LightWorkFlowManager/MessageWorkerManager.cs
index bb21760..5875322 100644
--- a/src/LightWorkFlowManager/MessageWorkerManager.cs
+++ b/src/LightWorkFlowManager/MessageWorkerManager.cs
@@ -22,12 +22,12 @@ public class MessageWorkerManager : IAsyncDisposable
///
/// 创建工作器管理
///
- ///
+ /// 任务标识。
/// 任务名,任务类型,如 PDF 解析或 PPT 解析等
- ///
+ /// 用于解析工作器与依赖项的服务作用域。
/// 每个工作器的失败重试次数,默认三次
/// 参数上下文信息
- ///
+ /// 工作器运行监控器。
public MessageWorkerManager(string taskId, string taskName, IServiceScope serviceScope, int retryCount = 3,
IWorkerContext? context = null, IWorkerRunMonitor? workerRunMonitor = null)
{
@@ -99,9 +99,9 @@ public MessageWorkerManager(string taskId, string taskName, IServiceScope servic
///
/// 设置上下文信息。设计上要求一个类型对应一个参数,不允许相同的类型作为不同的参数
///
- ///
- ///
- ///
+ /// 上下文类型。
+ /// 要保存的上下文对象。
+ /// 当前工作器管理器。
public MessageWorkerManager SetContext(T context)
{
Context.SetContext(context);
@@ -113,9 +113,9 @@ public MessageWorkerManager SetContext(T context)
///
/// 现有的参数类型
/// 转换后的参数类型
- ///
+ /// 参数转换委托。
/// 如果前置步骤失败,即 为 IsFail 时,将不执行委托内容
- ///
+ /// 当前工作器管理器。
public MessageWorkerManager SetContext(Func worker)
{
if (MessageWorkerStatus.IsFail)
@@ -133,8 +133,8 @@ public MessageWorkerManager SetContext(Func wo
///
/// 获取工作器,获取到的工作器将会被注入信息
///
- ///
- ///
+ /// 工作器类型。
+ /// 已注入管理器信息的工作器实例。
public T GetWorker() where T : IMessageWorker
{
var messageWorker = ServiceProvider.GetRequiredService();
@@ -145,12 +145,12 @@ public T GetWorker() where T : IMessageWorker
///
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
- ///
- ///
+ /// 输入参数类型。
+ /// 输出参数类型。
+ /// 同步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Func messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(messageTask, workerName ?? messageTask.Method.DeclaringType?.FullName, canRunWhenFail);
@@ -160,12 +160,12 @@ public ValueTask RunWorker(Func
///
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
- ///
- ///
+ /// 输入参数类型。
+ /// 输出参数类型。
+ /// 异步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Func> messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(messageTask, workerName ?? messageTask.Method.DeclaringType?.FullName, canRunWhenFail);
@@ -175,11 +175,11 @@ public ValueTask RunWorker(Func
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
- ///
+ /// 输入参数类型。
+ /// 异步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Func messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(messageTask, workerName ?? messageTask.Method.DeclaringType?.FullName, canRunWhenFail);
@@ -189,10 +189,10 @@ public ValueTask RunWorker(Func message
///
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
+ /// 异步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Func messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(_ => messageTask(), workerName ?? messageTask.Method.DeclaringType?.FullName, canRunWhenFail);
@@ -202,11 +202,11 @@ public ValueTask RunWorker(Func messageTask, string? wo
///
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
- ///
+ /// 输入参数类型。
+ /// 同步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Action messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(input =>
@@ -220,10 +220,10 @@ public ValueTask RunWorker(Action messageTask, str
///
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
+ /// 同步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Action messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(messageTask, workerName ?? messageTask.Method.DeclaringType?.FullName, canRunWhenFail);
@@ -233,10 +233,10 @@ public ValueTask RunWorker(Action messageTask, str
///
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
+ /// 同步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Action messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(_ => messageTask(), workerName ?? messageTask.Method.DeclaringType?.FullName, canRunWhenFail);
@@ -246,10 +246,10 @@ public ValueTask RunWorker(Action messageTask, string? workerName
///
/// 执行委托工作器,执行的内容为 参数的内容
///
- ///
+ /// 异步执行委托。
/// 此委托代表的工作器名,用于调试和埋点上报
/// 是否在当前 前置步骤已失败时,依然可以执行。默认为 false 表示在前置步骤失败时,不执行
- ///
+ /// 工作器执行结果。
public ValueTask RunWorker(Func messageTask, string? workerName = null, bool canRunWhenFail = false)
{
var worker = new DelegateMessageWorker(messageTask, workerName ?? messageTask.Method.DeclaringType?.FullName, canRunWhenFail);
@@ -259,8 +259,8 @@ public ValueTask RunWorker(Func message
///
/// 执行工作器
///
- ///
- ///
+ /// 工作器类型。
+ /// 工作器执行结果。
public ValueTask RunWorker() where TWorker : IMessageWorker
{
var worker = ServiceProvider.GetRequiredService();
@@ -270,8 +270,8 @@ public ValueTask RunWorker() where TWorker : IMessageWork
///
/// 执行工作器
///
- ///
- ///
+ /// 要执行的工作器。
+ /// 工作器执行结果。
public virtual async ValueTask RunWorker(IMessageWorker worker)
{
SetManager(worker as IMessageWorkerManagerSensitive);
@@ -508,6 +508,10 @@ internal WorkerResult GetFailResult()
canRetry: false);
}
+ ///
+ /// 异步释放当前管理器持有的工作器和服务作用域。
+ ///
+ /// 表示异步释放操作的任务。
public async ValueTask DisposeAsync()
{
while (_workerStack.TryPop(out var worker))
diff --git a/src/LightWorkFlowManager/Monitors/IWorkerRunMonitor.cs b/src/LightWorkFlowManager/Monitors/IWorkerRunMonitor.cs
index 6d2f2b2..79a40d0 100644
--- a/src/LightWorkFlowManager/Monitors/IWorkerRunMonitor.cs
+++ b/src/LightWorkFlowManager/Monitors/IWorkerRunMonitor.cs
@@ -4,9 +4,28 @@
namespace DC.LightWorkFlowManager.Monitors;
+///
+/// 提供工作器执行过程的监控回调。
+///
public interface IWorkerRunMonitor
{
+ ///
+ /// 在工作器开始执行时调用。
+ ///
+ /// 即将执行的工作器。
void OnWorkerStart(IMessageWorker worker);
+
+ ///
+ /// 在工作器执行完成时调用。
+ ///
+ /// 已执行完成的工作器。
+ /// 工作器执行结果。
void OnWorkerFinish(IMessageWorker worker, WorkerResult result);
+
+ ///
+ /// 在工作器执行出现异常时调用。
+ ///
+ /// 发生异常的工作器。
+ /// 执行过程中抛出的异常。
void OnWorkerException(IMessageWorker worker, Exception exception);
}
diff --git a/src/LightWorkFlowManager/Monitors/Progress/ProgressCompositor.cs b/src/LightWorkFlowManager/Monitors/Progress/ProgressCompositor.cs
index bb218ee..beef029 100644
--- a/src/LightWorkFlowManager/Monitors/Progress/ProgressCompositor.cs
+++ b/src/LightWorkFlowManager/Monitors/Progress/ProgressCompositor.cs
@@ -6,7 +6,7 @@ namespace DC.LightWorkFlowManager.Monitors;
///
/// 进度合成器,允许包含多个子进度
///
-///
+/// 随进度一起上报的数据类型。
/// 规则:
/// - 可以注册多个子进度,每个子进度都有自己的权值
/// - 子进度的进度贡献到上级进度时,将叠加上子进度自己的权值。如占比一半权值的子进度,就最多只贡献一半的进度
@@ -16,7 +16,7 @@ public class ProgressCompositor
///
/// 创建进度合成器
///
- ///
+ /// 进度名。
public ProgressCompositor(string name)
{
Name = name;
@@ -88,6 +88,11 @@ public IReadOnlyList> RegisterSubProgressCompositors(IRead
return subProgressList;
}
+ ///
+ /// 注册单个子进度合成器。
+ ///
+ /// 子进度注册信息。
+ /// 创建出的子进度合成器。
public ProgressCompositor RegisterSubProgressCompositor(SubProgressCompositorInfo subProgressCompositor)
{
var progressCompositor = new ProgressCompositor(subProgressCompositor.Name);
@@ -109,8 +114,8 @@ private void SubProgressCompositor_Reported(object? sender, ProgressReportedEven
///
/// 上报进度
///
- ///
- ///
+ /// 当前进度值。
+ /// 随进度上报的数据。
public void Report(ProgressPercentage percentage, T? value = default)
{
_selfProgressPercentage = percentage;
@@ -127,8 +132,8 @@ public void Report(ProgressPercentage percentage, T? value = default)
///
/// 上报增量进度,将叠加上当前的进度
///
- ///
- ///
+ /// 要增加的进度值。
+ /// 随进度上报的数据。
public void ReportIncreased(ProgressPercentage percentage, T? value = default)
{
var currentPercentageValue = _selfProgressPercentage.Value + percentage.Value;
diff --git a/src/LightWorkFlowManager/Monitors/Progress/ProgressPercentage.cs b/src/LightWorkFlowManager/Monitors/Progress/ProgressPercentage.cs
index 343e896..1aa4ff5 100644
--- a/src/LightWorkFlowManager/Monitors/Progress/ProgressPercentage.cs
+++ b/src/LightWorkFlowManager/Monitors/Progress/ProgressPercentage.cs
@@ -10,7 +10,7 @@ public readonly record struct ProgressPercentage
///
/// 进度百分比 0-1 范围
///
- ///
+ /// 进度值,范围在 0 到 1 之间。
public ProgressPercentage(double value)
{
Value = value;
@@ -22,9 +22,18 @@ public ProgressPercentage(double value)
}
}
+ ///
+ /// 获取当前进度值。
+ ///
public double Value { get; init; }
+ ///
+ /// 获取最小进度值。
+ ///
public static ProgressPercentage MinValue => new ProgressPercentage(0);
+ ///
+ /// 获取最大进度值。
+ ///
public static ProgressPercentage MaxValue => new ProgressPercentage(1);
}
\ No newline at end of file
diff --git a/src/LightWorkFlowManager/Monitors/Progress/ProgressReportedEventArgument.cs b/src/LightWorkFlowManager/Monitors/Progress/ProgressReportedEventArgument.cs
index 2864f41..1354d7b 100644
--- a/src/LightWorkFlowManager/Monitors/Progress/ProgressReportedEventArgument.cs
+++ b/src/LightWorkFlowManager/Monitors/Progress/ProgressReportedEventArgument.cs
@@ -1,3 +1,29 @@
namespace DC.LightWorkFlowManager.Monitors;
-public readonly record struct ProgressReportedEventArgument(ProgressPercentage ProgressPercentage, T? Value);
\ No newline at end of file
+///
+/// 表示进度上报事件参数。
+///
+/// 随进度一同上报的数据类型。
+public readonly record struct ProgressReportedEventArgument
+{
+ ///
+ /// 初始化进度上报事件参数。
+ ///
+ /// 当前进度值。
+ /// 随进度上报的数据。
+ public ProgressReportedEventArgument(ProgressPercentage progressPercentage, T? value)
+ {
+ ProgressPercentage = progressPercentage;
+ Value = value;
+ }
+
+ ///
+ /// 获取当前进度值。
+ ///
+ public ProgressPercentage ProgressPercentage { get; init; }
+
+ ///
+ /// 获取随进度上报的数据。
+ ///
+ public T? Value { get; init; }
+}
diff --git a/src/LightWorkFlowManager/Monitors/Progress/SubProgressCompositorInfo.cs b/src/LightWorkFlowManager/Monitors/Progress/SubProgressCompositorInfo.cs
index 03b177c..fd02f7d 100644
--- a/src/LightWorkFlowManager/Monitors/Progress/SubProgressCompositorInfo.cs
+++ b/src/LightWorkFlowManager/Monitors/Progress/SubProgressCompositorInfo.cs
@@ -1,3 +1,28 @@
namespace DC.LightWorkFlowManager.Monitors;
-public readonly record struct SubProgressCompositorInfo(string Name, double Weight);
\ No newline at end of file
+///
+/// 表示子进度合成器的注册信息。
+///
+public readonly record struct SubProgressCompositorInfo
+{
+ ///
+ /// 初始化子进度合成器信息。
+ ///
+ /// 子进度名称。
+ /// 子进度权重。
+ public SubProgressCompositorInfo(string name, double weight)
+ {
+ Name = name;
+ Weight = weight;
+ }
+
+ ///
+ /// 获取子进度名称。
+ ///
+ public string Name { get; init; }
+
+ ///
+ /// 获取子进度权重。
+ ///
+ public double Weight { get; init; }
+}
diff --git a/src/LightWorkFlowManager/Protocols/MessageWorkerStatus.cs b/src/LightWorkFlowManager/Protocols/MessageWorkerStatus.cs
index 9ed4063..550e3ae 100644
--- a/src/LightWorkFlowManager/Protocols/MessageWorkerStatus.cs
+++ b/src/LightWorkFlowManager/Protocols/MessageWorkerStatus.cs
@@ -4,12 +4,24 @@
namespace DC.LightWorkFlowManager.Protocols;
+///
+/// 表示工作流管理器的当前执行状态。
+///
public class MessageWorkerStatus
{
+ ///
+ /// 获取当前状态是否为失败。
+ ///
public bool IsFail => Status != WorkFlowErrorCode.Ok;
+ ///
+ /// 获取当前记录的状态码。
+ ///
public WorkFlowErrorCode Status { get; private set; } = WorkFlowErrorCode.Ok;
+ ///
+ /// 获取或设置最后一次异常。
+ ///
public Exception? LastException { get; set; }
///
@@ -17,8 +29,18 @@ public class MessageWorkerStatus
///
public IMessageWorker? FailWorker { get; private set; }
+ ///
+ /// 设置当前状态码。
+ ///
+ /// 要设置的状态码。
public void SetErrorCode(WorkFlowErrorCode errorCode) => Status = errorCode;
+ ///
+ /// 在当前尚未失败时尝试记录失败状态。
+ ///
+ /// 失败状态码。
+ /// 触发失败的工作器。
+ /// 如果成功记录失败状态则返回 ;否则返回 。
public bool TrySetErrorCode(WorkFlowErrorCode errorCode, IMessageWorker failWorker)
{
if (IsFail)
@@ -32,6 +54,7 @@ public bool TrySetErrorCode(WorkFlowErrorCode errorCode, IMessageWorker failWork
return true;
}
+ ///
public override string ToString()
{
if (IsFail)
diff --git a/src/LightWorkFlowManager/Protocols/WorkerResult.cs b/src/LightWorkFlowManager/Protocols/WorkerResult.cs
index 389f85e..3f292ce 100644
--- a/src/LightWorkFlowManager/Protocols/WorkerResult.cs
+++ b/src/LightWorkFlowManager/Protocols/WorkerResult.cs
@@ -4,8 +4,17 @@
namespace DC.LightWorkFlowManager.Protocols;
+///
+/// 表示工作器执行结果。
+///
public class WorkerResult
{
+ ///
+ /// 创建工作器执行结果。
+ ///
+ /// 是否执行成功。
+ /// 执行失败时的错误码。
+ /// 执行失败后是否允许重试。
public WorkerResult(bool isSuccess, WorkFlowErrorCode errorCode, bool canRetry)
{
IsSuccess = isSuccess;
@@ -18,10 +27,19 @@ public WorkerResult(bool isSuccess, WorkFlowErrorCode errorCode, bool canRetry)
}
}
+ ///
+ /// 获取当前执行是否成功。
+ ///
public virtual bool IsSuccess { get; }
+ ///
+ /// 获取当前执行是否失败。
+ ///
public bool IsFail => !IsSuccess;
+ ///
+ /// 获取执行失败时的错误码。
+ ///
public WorkFlowErrorCode ErrorCode { get; }
///
@@ -29,9 +47,21 @@ public WorkerResult(bool isSuccess, WorkFlowErrorCode errorCode, bool canRetry)
///
public bool CanRetry { get; }
+ ///
+ /// 创建一个成功结果。
+ ///
+ /// 表示成功的执行结果。
public static WorkerResult Success() => new WorkerResult(true, WorkFlowErrorCode.Ok, false);
+
+ ///
+ /// 创建一个失败结果。
+ ///
+ /// 失败时的错误码。
+ /// 失败后是否允许重试。
+ /// 表示失败的执行结果。
public static WorkerResult Fail(WorkFlowErrorCode errorCode, bool canRetry=true) => new WorkerResult(false, errorCode, canRetry);
+ ///
public override string ToString()
{
if (IsSuccess)
@@ -45,29 +75,60 @@ public override string ToString()
}
}
+///
+/// 表示带返回值的工作器执行结果。
+///
+/// 结果值类型。
public class WorkerResult : WorkerResult
{
+ ///
+ /// 创建一个成功的执行结果。
+ ///
+ /// 工作器输出结果。
public WorkerResult(T result) : base(isSuccess: true, WorkFlowErrorCode.Ok, canRetry: false)
{
Result = result;
}
+ ///
+ /// 创建一个失败的执行结果。
+ ///
+ /// 失败时的错误码。
+ /// 失败后是否允许重试。
public WorkerResult(WorkFlowErrorCode errorCode, bool canRetry) : base(isSuccess: false, errorCode, canRetry)
{
Result = default;
}
+ ///
+ /// 获取当前执行是否成功。
+ ///
[MemberNotNullWhen(true, nameof(Result))]
public override bool IsSuccess => Result != null;
+
+ ///
+ /// 获取工作器输出结果。
+ ///
public T? Result { get; }
+ ///
+ /// 将输出结果隐式转换为成功的执行结果。
+ ///
+ /// 输出结果。
+ /// 包装后的执行结果。
public static implicit operator WorkerResult(T workerResult)
{
return new WorkerResult(workerResult);
}
+ ///
+ /// 从执行结果中隐式获取输出结果。
+ ///
+ /// 执行结果。
+ /// 输出结果。
public static implicit operator T?(WorkerResult workerResult) => workerResult.Result;
+ ///
public override string ToString()
{
if (IsSuccess)
diff --git a/src/LightWorkFlowManager/Workers/DelegateMessageWorker.cs b/src/LightWorkFlowManager/Workers/DelegateMessageWorker.cs
index 46e9aab..1bd3f94 100644
--- a/src/LightWorkFlowManager/Workers/DelegateMessageWorker.cs
+++ b/src/LightWorkFlowManager/Workers/DelegateMessageWorker.cs
@@ -5,8 +5,18 @@
namespace DC.LightWorkFlowManager.Workers;
+///
+/// 表示基于委托实现的单输入工作器。
+///
+/// 输入参数类型。
public class DelegateMessageWorker : MessageWorker
{
+ ///
+ /// 使用异步委托初始化工作器。
+ ///
+ /// 实际执行逻辑。
+ /// 工作器名称。
+ /// 当前置步骤失败时是否仍可运行。
public DelegateMessageWorker(Func messageTask, string? workerName = null, bool canRunWhenFail = false)
{
_messageTask = messageTask;
@@ -15,6 +25,7 @@ public DelegateMessageWorker(Func messageTask, string? worker
CanRunWhenFail = canRunWhenFail;
}
+ ///
public override string WorkerName => _workerName ?? base.WorkerName;
private readonly string? _workerName;
@@ -28,8 +39,19 @@ protected override async ValueTask DoAsync(TInput input)
private readonly Func _messageTask;
}
+///
+/// 表示基于委托实现的输入输出工作器。
+///
+/// 输入参数类型。
+/// 输出参数类型。
public class DelegateMessageWorker : MessageWorker
{
+ ///
+ /// 使用同步委托初始化工作器。
+ ///
+ /// 实际执行逻辑。
+ /// 工作器名称。
+ /// 当前置步骤失败时是否仍可运行。
public DelegateMessageWorker(Func messageTask, string? workerName = null, bool canRunWhenFail = false)
{
_workerName = workerName;
@@ -42,6 +64,12 @@ public DelegateMessageWorker(Func messageTask, string? workerNa
CanRunWhenFail = canRunWhenFail;
}
+ ///
+ /// 使用异步委托初始化工作器。
+ ///
+ /// 实际执行逻辑。
+ /// 工作器名称。
+ /// 当前置步骤失败时是否仍可运行。
public DelegateMessageWorker(Func> messageTask, string? workerName = null, bool canRunWhenFail = false)
{
_messageTask = messageTask;
@@ -57,13 +85,23 @@ protected override async ValueTask> DoInnerAsync(TInput in
private readonly Func> _messageTask;
+ ///
public override string WorkerName => _workerName ?? base.WorkerName;
private readonly string? _workerName;
}
+///
+/// 表示基于委托实现的无固定输入工作器。
+///
public class DelegateMessageWorker : MessageWorkerBase
{
+ ///
+ /// 使用同步委托初始化工作器。
+ ///
+ /// 实际执行逻辑。
+ /// 工作器名称。
+ /// 当前置步骤失败时是否仍可运行。
public DelegateMessageWorker(Action messageAction, string? workerName = null, bool canRunWhenFail=false)
{
_messageTask = c =>
@@ -76,6 +114,12 @@ public DelegateMessageWorker(Action messageAction, string? worke
CanRunWhenFail = canRunWhenFail;
}
+ ///
+ /// 使用异步委托初始化工作器。
+ ///
+ /// 实际执行逻辑。
+ /// 工作器名称。
+ /// 当前置步骤失败时是否仍可运行。
public DelegateMessageWorker(Func messageTask, string? workerName = null, bool canRunWhenFail=false)
{
_messageTask = async c =>
@@ -88,6 +132,12 @@ public DelegateMessageWorker(Func messageTask, string
CanRunWhenFail = canRunWhenFail;
}
+ ///
+ /// 使用返回执行结果的异步委托初始化工作器。
+ ///
+ /// 实际执行逻辑。
+ /// 工作器名称。
+ /// 当前置步骤失败时是否仍可运行。
public DelegateMessageWorker(Func> messageTask, string? workerName = null, bool canRunWhenFail = false)
{
_messageTask = messageTask;
@@ -96,12 +146,14 @@ public DelegateMessageWorker(Func> messa
CanRunWhenFail = canRunWhenFail;
}
+ ///
public override string WorkerName => _workerName ?? base.WorkerName;
private readonly string? _workerName;
private readonly Func> _messageTask;
+ ///
public override ValueTask Do(IWorkerContext context)
{
return _messageTask(context);
diff --git a/src/LightWorkFlowManager/Workers/IMessageWorker.cs b/src/LightWorkFlowManager/Workers/IMessageWorker.cs
index ef2755b..f8d7fe5 100644
--- a/src/LightWorkFlowManager/Workers/IMessageWorker.cs
+++ b/src/LightWorkFlowManager/Workers/IMessageWorker.cs
@@ -10,6 +10,9 @@ namespace DC.LightWorkFlowManager.Workers;
///
public interface IMessageWorker
{
+ ///
+ /// 获取或设置当前任务标识。
+ ///
string TaskId { get; set; }
///
@@ -36,10 +39,19 @@ public interface IMessageWorker
///
/// 遇到失败时,是否能执行
///
- ///
bool CanRunWhenFail { get; }
+ ///
+ /// 执行当前工作器。
+ ///
+ /// 工作器上下文。
+ /// 工作器执行结果。
ValueTask Do(IWorkerContext context);
+ ///
+ /// 在工作器被释放时执行清理逻辑。
+ ///
+ /// 工作器上下文。
+ /// 表示异步清理操作的任务。
ValueTask OnDisposeAsync(IWorkerContext context);
}
diff --git a/src/LightWorkFlowManager/Workers/MessageWorker.cs b/src/LightWorkFlowManager/Workers/MessageWorker.cs
index d757911..114eed3 100644
--- a/src/LightWorkFlowManager/Workers/MessageWorker.cs
+++ b/src/LightWorkFlowManager/Workers/MessageWorker.cs
@@ -6,8 +6,13 @@
namespace DC.LightWorkFlowManager.Workers;
+///
+/// 表示需要单个输入参数的工作器基类。
+///
+/// 输入参数类型。
public abstract class MessageWorker : MessageWorkerBase
{
+ ///
public sealed override ValueTask Do(IWorkerContext context)
{
var input = context.GetContext();
@@ -23,6 +28,11 @@ public sealed override ValueTask Do(IWorkerContext context)
protected abstract ValueTask DoAsync(TInput input);
}
+///
+/// 表示带输入与输出参数的工作器基类。
+///
+/// 输入参数类型。
+/// 输出参数类型。
public abstract class MessageWorker : MessageWorker
{
protected sealed override async ValueTask DoAsync(TInput input)
@@ -37,6 +47,12 @@ protected sealed override async ValueTask DoAsync(TInput input)
return output;
}
+ ///
+ /// 使用当前上下文中的参数转换为输入后运行工作器。
+ ///
+ /// 当前上下文中的参数类型。
+ /// 将上下文参数转换为输入参数的委托。
+ /// 带输出结果的工作器执行结果。
public ValueTask> RunAsync(Func converter)
{
var argument = CurrentContext.GetEnsureContext();
@@ -44,6 +60,11 @@ public ValueTask> RunAsync(Func
+ /// 使用指定输入参数运行工作器。
+ ///
+ /// 工作器输入参数。
+ /// 带输出结果的工作器执行结果。
public ValueTask> RunAsync(TInput input)
{
ThrowNotManager();
@@ -52,6 +73,10 @@ public ValueTask> RunAsync(TInput input)
return RunAsync();
}
+ ///
+ /// 使用当前上下文运行工作器并返回输出结果。
+ ///
+ /// 带输出结果的工作器执行结果。
public new async ValueTask> RunAsync()
{
ThrowNotManager();
diff --git a/src/LightWorkFlowManager/Workers/MessageWorkerBase.cs b/src/LightWorkFlowManager/Workers/MessageWorkerBase.cs
index 1223f8c..ec7b318 100644
--- a/src/LightWorkFlowManager/Workers/MessageWorkerBase.cs
+++ b/src/LightWorkFlowManager/Workers/MessageWorkerBase.cs
@@ -12,7 +12,12 @@ namespace DC.LightWorkFlowManager.Workers;
///
public abstract class MessageWorkerBase : IMessageWorker, IMessageWorkerManagerSensitive
{
+ ///
public string TaskId { get; set; } = null!;
+
+ ///
+ /// 获取当前工作器名称。
+ ///
public virtual string WorkerName => GetType().Name;
///
@@ -20,6 +25,9 @@ public abstract class MessageWorkerBase : IMessageWorker, IMessageWorkerManagerS
///
public virtual bool CanRetry { protected set; get; } = true;
+ ///
+ /// 获取重试前的等待时间。
+ ///
public virtual TimeSpan RetryDelayTime => TimeSpan.FromSeconds(1);
///
@@ -29,11 +37,16 @@ public abstract class MessageWorkerBase : IMessageWorker, IMessageWorkerManagerS
// 默认遇到错误不能运行
= false;
+ ///
public abstract ValueTask Do(IWorkerContext context);
protected MessageWorkerStatus Status => GetEnsureContext();
protected IWorkerContext CurrentContext => Manager.Context;
protected IServiceProvider ServiceProvider => Manager.ServiceProvider;
+
+ ///
+ /// 获取当前工作器使用的日志器。
+ ///
public ILogger Logger { get; private set; }
// 框架注入
= null!;
@@ -62,6 +75,10 @@ protected T GetScopeWithContext() where T:notnull
protected T? GetContext() => CurrentContext.GetContext();
protected void SetContext(T context) => CurrentContext.SetContext(context);
+ ///
+ /// 通过当前管理器执行当前工作器。
+ ///
+ /// 工作器执行结果。
public async ValueTask RunAsync()
{
ThrowNotManager();
@@ -70,6 +87,7 @@ public async ValueTask RunAsync()
return result;
}
+ ///
public async ValueTask OnDisposeAsync(IWorkerContext context)
{
if (_onDispose != null)