Skip to content

Commit be77866

Browse files
committed
fixed issue w/ using Finally() middleware to expose variables created by middleware. Closes GH-772
1 parent 2d0267e commit be77866

File tree

3 files changed

+129
-1
lines changed

3 files changed

+129
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using System.Diagnostics;
2+
using Alba;
3+
using IntegrationTests;
4+
using Marten;
5+
using Microsoft.AspNetCore.Builder;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using Wolverine.Marten;
9+
using Wolverine.Postgresql;
10+
using Wolverine.Runtime;
11+
using Wolverine.Tracking;
12+
13+
namespace Wolverine.Http.Tests.Bugs;
14+
15+
public class Bug_772_Saga_codegen
16+
{
17+
[Fact]
18+
public async Task can_compile_without_issue()
19+
{
20+
var builder = WebApplication.CreateBuilder(Array.Empty<string>());
21+
22+
builder.Services
23+
.AddMarten(options =>
24+
{
25+
options.Connection(Servers.PostgresConnectionString);
26+
})
27+
.UseLightweightSessions()
28+
.IntegrateWithWolverine();
29+
30+
builder.Host.UseWolverine(options =>
31+
{
32+
options.Discovery.IncludeAssembly(GetType().Assembly);
33+
34+
options.Policies.AutoApplyTransactions();
35+
options.Policies.UseDurableLocalQueues();
36+
options.Policies.UseDurableOutboxOnAllSendingEndpoints();
37+
38+
Debug.WriteLine(options.DescribeHandlerMatch(typeof(LongProcessSaga)));
39+
});
40+
41+
builder.Services.AddScoped<IDataService, DataService>();
42+
43+
await using var host = await AlbaHost.For(builder, app =>
44+
{
45+
app.MapWolverineEndpoints();
46+
});
47+
48+
await host.InvokeMessageAndWaitAsync(new BeginProcess(Guid.NewGuid()));
49+
}
50+
}
51+
52+
public interface IDataService
53+
{
54+
Task<RecordData> GetData(Guid messageDataId);
55+
}
56+
57+
public class DataService : IDataService
58+
{
59+
public Task<RecordData> GetData(Guid messageDataId)
60+
{
61+
var answer = new RecordData { MessageDataId = messageDataId, Data = Guid.NewGuid().ToString()};
62+
return Task.FromResult(answer);
63+
}
64+
}
65+
66+
public class RecordData
67+
{
68+
public Guid MessageDataId { get; set; }
69+
public string Data { get; set; }
70+
}
71+
72+
public record BeginProcess(Guid DataId);
73+
74+
public record ContinueProcess(Guid SagaId, Guid DataId, string Data);
75+
76+
public static class BeginProcessMiddleware
77+
{
78+
public static async Task<RecordData> LoadAsync(BeginProcess message, IDataService dataService)
79+
{
80+
return await dataService.GetData(message.DataId);
81+
}
82+
83+
public static void Finally()
84+
{
85+
// ...
86+
}
87+
}
88+
89+
public class LongProcessSaga : Saga
90+
{
91+
public Guid Id { get; init; }
92+
93+
[Wolverine.Attributes.Middleware(typeof(BeginProcessMiddleware))]
94+
public static (LongProcessSaga, OutgoingMessages) Start(BeginProcess message, RecordData? sourceData = null)
95+
{
96+
var outgoingMessages = new OutgoingMessages();
97+
98+
var saga = new LongProcessSaga
99+
{
100+
Id = Guid.NewGuid(),
101+
};
102+
103+
if (sourceData is not null)
104+
{
105+
outgoingMessages.Add(new ContinueProcess(saga.Id, message.DataId, sourceData.Data));
106+
}
107+
108+
return (
109+
saga,
110+
outgoingMessages
111+
);
112+
}
113+
}

src/Wolverine/Middleware/MiddlewarePolicy.cs

+2
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ public TryFinallyWrapperFrame(Frame inner, Frame[] finallys) : base(inner.IsAsyn
286286
{
287287
_inner = inner;
288288
_finallys = finallys;
289+
290+
creates.AddRange(inner.Creates.Select(x => new Variable(x.VariableType, x.Usage)));
289291
}
290292

291293
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer)

src/Wolverine/Runtime/Handlers/HandlerGraph.cs

+14-1
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,23 @@ public void Group()
284284
}
285285
}
286286

287+
private bool isSagaMethod(HandlerCall call)
288+
{
289+
if (call.HandlerType.CanBeCastTo<Saga>())
290+
{
291+
if (!call.Method.IsStatic) return true;
292+
293+
if (call.Method.Name.EqualsIgnoreCase("Start")) return true;
294+
if (call.Method.Name.EqualsIgnoreCase("StartAsync")) return true;
295+
}
296+
297+
return false;
298+
}
299+
287300
private HandlerChain buildHandlerChain(IGrouping<Type, HandlerCall> group)
288301
{
289302
// If the SagaChain handler method is a static, then it's valid to be a "Start" method
290-
if (group.Any(x => x.HandlerType.CanBeCastTo<Saga>() && !x.Method.IsStatic))
303+
if (group.Any(isSagaMethod))
291304
{
292305
return new SagaChain(group, this);
293306
}

0 commit comments

Comments
 (0)