From b644c4b83160ca1f446f8f5d2cdf2c3765894e08 Mon Sep 17 00:00:00 2001 From: JusterZhu Date: Tue, 26 May 2026 14:12:22 +0800 Subject: [PATCH] refactor: change PipelineBuilder from LIFO (ImmutableStack) to FIFO (ImmutableQueue) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LIFO stack caused middleware execution order to be the reverse of registration order, which was the root cause of the MacStrategy pipeline bug fixed in #436. With FIFO (ImmutableQueue), registration order now equals execution order for intuitive API semantics. - PipelineBuilder: ImmutableStack → ImmutableQueue, Push → Enqueue - All OS strategies: register Hash → Compress → Patch (executes in same order) - MacStrategy: also changed to UseMiddlewareIf for consistency Co-Authored-By: Claude Opus 4.7 --- .../GeneralUpdate.Core/Pipeline/PipelineBuilder.cs | 12 ++++++------ src/c#/GeneralUpdate.Core/Strategy/LinuxStrategy.cs | 4 ++-- src/c#/GeneralUpdate.Core/Strategy/MacStrategy.cs | 2 +- .../GeneralUpdate.Core/Strategy/WindowsStrategy.cs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/c#/GeneralUpdate.Core/Pipeline/PipelineBuilder.cs b/src/c#/GeneralUpdate.Core/Pipeline/PipelineBuilder.cs index d75ef004..0dce594f 100644 --- a/src/c#/GeneralUpdate.Core/Pipeline/PipelineBuilder.cs +++ b/src/c#/GeneralUpdate.Core/Pipeline/PipelineBuilder.cs @@ -5,19 +5,19 @@ namespace GeneralUpdate.Core.Pipeline { /// - /// Pipeline builder. + /// Pipeline builder — middleware execute in FIFO (registration) order. /// public sealed class PipelineBuilder(PipelineContext context) { /// - /// LIFO£¬Last In First Out. + /// LIFO£¬Last In First Out. /// - private ImmutableStack _middlewareStack = ImmutableStack.Empty; + private ImmutableQueue _middlewareQueue = ImmutableQueue.Empty; public PipelineBuilder UseMiddleware() where TMiddleware : IMiddleware, new() { var middleware = new TMiddleware(); - _middlewareStack = _middlewareStack.Push(middleware); + _middlewareQueue = _middlewareQueue.Enqueue(middleware); return this; } @@ -28,13 +28,13 @@ public PipelineBuilder UseMiddlewareIf(bool? condition) return this; var middleware = new TMiddleware(); - _middlewareStack = _middlewareStack.Push(middleware); + _middlewareQueue = _middlewareQueue.Enqueue(middleware); return this; } public async Task Build() { - foreach (var middleware in _middlewareStack) + foreach (var middleware in _middlewareQueue) { await middleware.InvokeAsync(context); } diff --git a/src/c#/GeneralUpdate.Core/Strategy/LinuxStrategy.cs b/src/c#/GeneralUpdate.Core/Strategy/LinuxStrategy.cs index d1e2eab9..0fd5a75c 100644 --- a/src/c#/GeneralUpdate.Core/Strategy/LinuxStrategy.cs +++ b/src/c#/GeneralUpdate.Core/Strategy/LinuxStrategy.cs @@ -20,9 +20,9 @@ protected override PipelineBuilder BuildPipeline(PipelineContext context) { GeneralTracer.Info($"GeneralUpdate.Core.LinuxStrategy.BuildPipeline: assembling middleware pipeline. PatchEnabled={_configinfo.PatchEnabled}"); var builder = new PipelineBuilder(context) - .UseMiddlewareIf(_configinfo.PatchEnabled) + .UseMiddleware() .UseMiddleware() - .UseMiddleware(); + .UseMiddlewareIf(_configinfo.PatchEnabled); return builder; } diff --git a/src/c#/GeneralUpdate.Core/Strategy/MacStrategy.cs b/src/c#/GeneralUpdate.Core/Strategy/MacStrategy.cs index 11b998bc..7625f8b8 100644 --- a/src/c#/GeneralUpdate.Core/Strategy/MacStrategy.cs +++ b/src/c#/GeneralUpdate.Core/Strategy/MacStrategy.cs @@ -39,7 +39,7 @@ protected override PipelineBuilder BuildPipeline(PipelineContext context) var builder = new PipelineBuilder(context) .UseMiddleware() .UseMiddleware() - .UseMiddleware(); + .UseMiddlewareIf(_configinfo.PatchEnabled); return builder; } } diff --git a/src/c#/GeneralUpdate.Core/Strategy/WindowsStrategy.cs b/src/c#/GeneralUpdate.Core/Strategy/WindowsStrategy.cs index 8612ed3a..bf7e7811 100644 --- a/src/c#/GeneralUpdate.Core/Strategy/WindowsStrategy.cs +++ b/src/c#/GeneralUpdate.Core/Strategy/WindowsStrategy.cs @@ -27,9 +27,9 @@ protected override PipelineBuilder BuildPipeline(PipelineContext context) { GeneralTracer.Info($"GeneralUpdate.Core.WindowsStrategy.BuildPipeline: assembling middleware pipeline. PatchEnabled={_configinfo.PatchEnabled}"); var builder = new PipelineBuilder(context) - .UseMiddlewareIf(_configinfo.PatchEnabled) + .UseMiddleware() .UseMiddleware() - .UseMiddleware(); + .UseMiddlewareIf(_configinfo.PatchEnabled); return builder; }