Skip to content

Commit 3b1fb95

Browse files
ReubenBondCopilot
andcommitted
fix(codegen): adapt invokable pooling to current generators
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 37bc971 commit 3b1fb95

11 files changed

Lines changed: 115 additions & 46 deletions

File tree

src/Orleans.CodeGenerator/ActivatorGenerator.cs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Orleans.CodeGenerator
99
{
1010
internal class ActivatorGenerator
1111
{
12-
private readonly CodeGenerator _codeGenerator;
12+
private readonly IGeneratorServices _generatorServices;
1313

1414
private struct ConstructorArgument
1515
{
@@ -19,16 +19,16 @@ private struct ConstructorArgument
1919
public bool IsPool { get; set; }
2020
}
2121

22-
public ActivatorGenerator(CodeGenerator codeGenerator)
22+
public ActivatorGenerator(IGeneratorServices generatorServices)
2323
{
24-
_codeGenerator = codeGenerator;
24+
_generatorServices = generatorServices;
2525
}
2626

2727
public ClassDeclarationSyntax GenerateActivator(ISerializableTypeDescription type)
2828
{
2929
var simpleClassName = GetSimpleClassName(type);
3030

31-
var baseInterface = _codeGenerator.LibraryTypes.IActivator_1.ToTypeSyntax(type.TypeSyntax);
31+
var baseInterface = _generatorServices.LibraryTypes.IActivator_1.ToTypeSyntax(type.TypeSyntax);
3232

3333
var orderedFields = new List<ConstructorArgument>();
3434
var index = 0;
@@ -37,7 +37,9 @@ public ClassDeclarationSyntax GenerateActivator(ISerializableTypeDescription typ
3737
foreach (var arg in parameters)
3838
{
3939
// Detect if this is an InvokablePool<T> parameter
40-
var isPool = arg is GenericNameSyntax gns && gns.Identifier.Text == "InvokablePool";
40+
var isPool = arg.DescendantNodesAndSelf()
41+
.OfType<GenericNameSyntax>()
42+
.Any(gns => gns.Identifier.Text == "InvokablePool");
4143
orderedFields.Add(new ConstructorArgument { Type = arg, FieldName = $"_arg{index}", ParameterName = $"arg{index}", IsPool = isPool });
4244
index++;
4345
}
@@ -61,7 +63,7 @@ public ClassDeclarationSyntax GenerateActivator(ISerializableTypeDescription typ
6163
var classDeclaration = ClassDeclaration(simpleClassName)
6264
.AddBaseListTypes(SimpleBaseType(baseInterface))
6365
.AddModifiers(Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.SealedKeyword))
64-
.AddAttributeLists(CodeGenerator.GetGeneratedCodeAttributes())
66+
.AddAttributeLists(GeneratedCodeUtilities.GetGeneratedCodeAttributes())
6567
.AddMembers(members.ToArray());
6668

6769
if (type.IsGenericType)
@@ -72,7 +74,20 @@ public ClassDeclarationSyntax GenerateActivator(ISerializableTypeDescription typ
7274
return classDeclaration;
7375
}
7476

75-
public static string GetSimpleClassName(ISerializableTypeDescription serializableType) => $"Activator_{serializableType.Name}";
77+
public static string GetSimpleClassName(ISerializableTypeDescription serializableType) => GetSimpleClassName(serializableType.Name);
78+
79+
public static string GetSimpleClassName(string name) => $"Activator_{name}";
80+
81+
internal static bool ShouldGenerateActivator(ISerializableTypeDescription type)
82+
{
83+
return !type.IsAbstractType
84+
&& !type.IsEnumType
85+
&& (!type.IsValueType
86+
&& type.IsEmptyConstructable
87+
&& !type.UseActivator
88+
&& type is not GeneratedInvokableDescription
89+
|| type.HasActivatorConstructor);
90+
}
7691

7792
private ConstructorDeclarationSyntax GenerateConstructor(
7893
string simpleClassName,

src/Orleans.CodeGenerator/InvokableGenerator.cs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ namespace Orleans.CodeGenerator
1717
/// </summary>
1818
internal class InvokableGenerator
1919
{
20-
private readonly CodeGenerator _codeGenerator;
20+
private readonly ProxyGenerationContext _generationContext;
2121

22-
public InvokableGenerator(CodeGenerator codeGenerator)
22+
public InvokableGenerator(ProxyGenerationContext generationContext)
2323
{
24-
_codeGenerator = codeGenerator;
24+
_generationContext = generationContext;
2525
}
2626

27-
private LibraryTypes LibraryTypes => _codeGenerator.LibraryTypes;
27+
private LibraryTypes LibraryTypes => _generationContext.LibraryTypes;
2828

2929
public GeneratedInvokableDescription Generate(InvokableMethodDescription invokableMethodInfo)
3030
{
@@ -86,7 +86,7 @@ public GeneratedInvokableDescription Generate(InvokableMethodDescription invokab
8686
invokableMethodInfo,
8787
accessibility,
8888
generatedClassName,
89-
CodeGenerator.GetGeneratedNamespaceName(invokableMethodInfo.ContainingInterface),
89+
GeneratedCodeUtilities.GetGeneratedNamespaceName(invokableMethodInfo.ContainingInterface),
9090
fieldDescriptions.OfType<IMemberDescription>().ToList(),
9191
serializationHooks,
9292
baseClassType,
@@ -128,7 +128,7 @@ private ClassDeclarationSyntax GetClassDeclarationSyntax(
128128
var classDeclaration = ClassDeclaration(generatedClassName)
129129
.AddBaseListTypes(SimpleBaseType(baseClassType.ToTypeSyntax(method.TypeParameterSubstitutions)))
130130
.AddModifiers(Token(accessibilityKind), Token(SyntaxKind.SealedKeyword))
131-
.AddAttributeLists(CodeGenerator.GetGeneratedCodeAttributes())
131+
.AddAttributeLists(GeneratedCodeUtilities.GetGeneratedCodeAttributes())
132132
.AddMembers(fields);
133133

134134
foreach (var alias in compoundTypeAliases)
@@ -774,9 +774,7 @@ MemberDeclarationSyntax GetFieldDeclaration(InvokerFieldDescription description)
774774
else if (description is PoolFieldDescription)
775775
{
776776
// Pool field: InvokablePool<ThisInvokableType>
777-
var poolType = GenericName(
778-
Identifier("InvokablePool"),
779-
TypeArgumentList(SingletonSeparatedList(invokableTypeSyntax)));
777+
var poolType = LibraryTypes.InvokablePool_1.ToTypeSyntax(invokableTypeSyntax);
780778
field = FieldDeclaration(
781779
VariableDeclaration(
782780
poolType,
@@ -828,9 +826,7 @@ private ExpressionSyntax GetTypesArray(InvokableMethodDescription method, IEnume
828826
var poolField = fieldDescriptions.OfType<PoolFieldDescription>().FirstOrDefault();
829827
if (poolField != null)
830828
{
831-
var poolType = GenericName(
832-
Identifier("InvokablePool"),
833-
TypeArgumentList(SingletonSeparatedList(invokableTypeSyntax)));
829+
var poolType = LibraryTypes.InvokablePool_1.ToTypeSyntax(invokableTypeSyntax);
834830
constructorArgumentTypes.Add(poolType);
835831
parameters.Add(Parameter(Identifier("pool")).WithType(poolType));
836832
body.Add(ExpressionStatement(
@@ -893,7 +889,7 @@ private List<InvokerFieldDescription> GetFieldDescriptions(InvokableMethodDescri
893889
foreach (var parameter in method.Method.Parameters)
894890
{
895891
var isSerializable = !SymbolEqualityComparer.Default.Equals(LibraryTypes.CancellationToken, parameter.Type);
896-
fields.Add(new MethodParameterFieldDescription(method.CodeGenerator, parameter, $"arg{fieldId}", fieldId, method.TypeParameterSubstitutions, isSerializable));
892+
fields.Add(new MethodParameterFieldDescription(method.GenerationContext.LibraryTypes, parameter, $"arg{fieldId}", fieldId, method.TypeParameterSubstitutions, isSerializable));
897893
fieldId++;
898894
}
899895

@@ -951,7 +947,7 @@ internal sealed class CancellationTokenFieldDescription(LibraryTypes libraryType
951947
internal class MethodParameterFieldDescription : InvokerFieldDescription, IMemberDescription
952948
{
953949
public MethodParameterFieldDescription(
954-
CodeGenerator codeGenerator,
950+
LibraryTypes libraryTypes,
955951
IParameterSymbol parameter,
956952
string fieldName,
957953
uint fieldId,
@@ -961,7 +957,7 @@ public MethodParameterFieldDescription(
961957
{
962958
TypeParameterSubstitutions = typeParameterSubstitutions;
963959
FieldId = fieldId;
964-
CodeGenerator = codeGenerator;
960+
LibraryTypes = libraryTypes;
965961
Parameter = parameter;
966962
if (parameter.Type.TypeKind == TypeKind.Dynamic)
967963
{
@@ -978,8 +974,8 @@ public MethodParameterFieldDescription(
978974
IsSerializable = isSerializable;
979975
}
980976

981-
public CodeGenerator CodeGenerator { get; }
982977
public ISymbol Symbol { get; }
978+
public LibraryTypes LibraryTypes { get; }
983979
public Dictionary<ITypeParameterSymbol, string> TypeParameterSubstitutions { get; }
984980
public int ParameterOrdinal => Parameter.Ordinal;
985981
public uint FieldId { get; }

src/Orleans.CodeGenerator/LibraryTypes.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ private LibraryTypes(Compilation compilation, CodeGeneratorOptions options)
5454
RegisterActivatorAttribute = Type("Orleans.RegisterActivatorAttribute");
5555
RegisterConverterAttribute = Type("Orleans.RegisterConverterAttribute");
5656
RegisterCopierAttribute = Type("Orleans.RegisterCopierAttribute");
57+
RegisterProviderAttribute = Type("Orleans.RegisterProviderAttribute");
5758
UseActivatorAttribute = Type("Orleans.UseActivatorAttribute");
5859
SuppressReferenceTrackingAttribute = Type("Orleans.SuppressReferenceTrackingAttribute");
5960
OmitDefaultMemberValuesAttribute = Type("Orleans.OmitDefaultMemberValuesAttribute");
@@ -252,6 +253,7 @@ INamedTypeSymbol Type(string metadataName)
252253
public WellKnownCopierDescription[] StaticCopiers { get; private set; }
253254
public WellKnownCopierDescription[] WellKnownCopiers { get; private set; }
254255
public INamedTypeSymbol RegisterCopierAttribute { get; private set; }
256+
public INamedTypeSymbol RegisterProviderAttribute { get; private set; }
255257
public INamedTypeSymbol RegisterSerializerAttribute { get; private set; }
256258
public INamedTypeSymbol ResponseTimeoutAttribute { get; private set; }
257259
public INamedTypeSymbol RegisterConverterAttribute { get; private set; }

src/Orleans.CodeGenerator/ProxyGenerator.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ internal class ProxyGenerator
2222
private const string CopyContextPoolMemberName = "CopyContextPool";
2323
private const string CodecProviderMemberName = "CodecProvider";
2424
private const string SharedMemberName = "Shared";
25-
private readonly CodeGenerator _codeGenerator;
25+
private readonly IGeneratorServices _generatorServices;
26+
private readonly CopierGenerator _copierGenerator;
2627

27-
public ProxyGenerator(CodeGenerator codeGenerator)
28+
public ProxyGenerator(IGeneratorServices generatorServices, CopierGenerator copierGenerator)
2829
{
29-
_codeGenerator = codeGenerator;
30+
_generatorServices = generatorServices;
31+
_copierGenerator = copierGenerator;
3032
}
3133

32-
private LibraryTypes LibraryTypes => _codeGenerator.LibraryTypes;
34+
private LibraryTypes LibraryTypes => _generatorServices.LibraryTypes;
3335

3436
public (ClassDeclarationSyntax, GeneratedProxyDescription) Generate(ProxyInterfaceDescription interfaceDescription)
3537
{
@@ -61,7 +63,7 @@ public ProxyGenerator(CodeGenerator codeGenerator)
6163
SimpleBaseType(interfaceDescription.ProxyBaseType.ToTypeSyntax()),
6264
SimpleBaseType(interfaceDescription.InterfaceType.ToTypeSyntax()))
6365
.AddModifiers(Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.SealedKeyword))
64-
.AddAttributeLists(CodeGenerator.GetGeneratedCodeAttributes())
66+
.AddAttributeLists(GeneratedCodeUtilities.GetGeneratedCodeAttributes())
6567
.AddMembers(fieldDeclarations)
6668
.AddMembers(activatorMembers)
6769
.AddMembers(ctors)
@@ -77,7 +79,10 @@ public ProxyGenerator(CodeGenerator codeGenerator)
7779
}
7880

7981
public static string GetSimpleClassName(ProxyInterfaceDescription interfaceDescription)
80-
=> $"Proxy_{SyntaxGeneration.Identifier.SanitizeIdentifierName(interfaceDescription.Name)}";
82+
=> GetSimpleClassName(interfaceDescription.Name);
83+
84+
public static string GetSimpleClassName(string name)
85+
=> $"Proxy_{SyntaxGeneration.Identifier.SanitizeIdentifierName(name)}";
8186

8287
private List<GeneratedFieldDescription> GetFieldDescriptions(
8388
ProxyInterfaceDescription interfaceDescription)
@@ -88,7 +93,7 @@ private List<GeneratedFieldDescription> GetFieldDescriptions(
8893
var paramCopiers = interfaceDescription.Methods
8994
.Where(method => method.MethodTypeParameters.Count == 0)
9095
.SelectMany(method => method.GeneratedInvokable.Members);
91-
_codeGenerator.CopierGenerator.GetCopierFieldDescriptions(paramCopiers, fields);
96+
_copierGenerator.GetCopierFieldDescriptions(paramCopiers, fields);
9297
return fields;
9398
}
9499

@@ -237,7 +242,7 @@ MethodDeclarationSyntax CreateProxyMethod(ProxyMethodDescription methodDescripti
237242
EqualsValueClause(createRequestExpr))))));
238243

239244
var codecs = fieldDescriptions.OfType<ICopierDescription>()
240-
.Concat(_codeGenerator.LibraryTypes.StaticCopiers)
245+
.Concat(_generatorServices.LibraryTypes.StaticCopiers)
241246
.ToList();
242247

243248
// Set request object fields from method parameters.
@@ -264,7 +269,7 @@ MethodDeclarationSyntax CreateProxyMethod(ProxyMethodDescription methodDescripti
264269
hasCopyContext = true;
265270
}
266271

267-
var valueExpression = _codeGenerator.CopierGenerator.GenerateMemberCopy(
272+
var valueExpression = _copierGenerator.GenerateMemberCopy(
268273
fieldDescriptions,
269274
IdentifierName($"arg{parameterIndex}"),
270275
copyContextVariable,

src/Orleans.Core/Messaging/MessageFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public Message CreateMessage(object? body, InvokeMethodOptions options)
4949
return message;
5050
}
5151

52-
public object CopyBodyObject(object body) => _deepCopier.Copy(body);
52+
public object CopyBodyObject(object body) => _deepCopier.Copy(body)!;
5353

5454
private CorrelationId GetNextCorrelationId()
5555
{

src/Orleans.Core/Runtime/CallbackData.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ private long GetResponseTimeoutStopwatchTicks()
8383

8484
private TimeSpan GetResponseTimeout() => (Message.BodyObject as IInvokable)?.GetDefaultResponseTimeout() ?? shared.ResponseTimeout;
8585

86+
private string GetTargetGrainType()
87+
{
88+
var type = Message.TargetGrain.Type;
89+
return type.IsDefault ? "unknown" : type.ToString()!;
90+
}
91+
8692
private void OnCancellation()
8793
{
8894
// If waiting for acknowledgement is enabled, simply signal to the remote grain that cancellation
@@ -104,7 +110,7 @@ private void OnCancellation()
104110
SignalCancellation();
105111
shared.Unregister(Message);
106112
_applicationRequestInstruments.OnAppRequestsEnd((long)stopwatch.Elapsed.TotalMilliseconds);
107-
_applicationRequestInstruments.OnAppRequestsTimedOut();
113+
_applicationRequestInstruments.OnAppRequestsTimedOut(GetTargetGrainType());
108114
OrleansCallBackDataEvent.Instance.OnCanceled(Message);
109115
context.Complete(Response.FromException(new OperationCanceledException(_cancellationTokenRegistration.Token)));
110116
_cancellationTokenRegistration.Dispose();
@@ -126,7 +132,7 @@ public void OnTimeout()
126132
this.shared.Unregister(this.Message);
127133
_cancellationTokenRegistration.Dispose();
128134
_applicationRequestInstruments.OnAppRequestsEnd((long)this.stopwatch.Elapsed.TotalMilliseconds);
129-
_applicationRequestInstruments.OnAppRequestsTimedOut();
135+
_applicationRequestInstruments.OnAppRequestsTimedOut(GetTargetGrainType());
130136

131137
OrleansCallBackDataEvent.Instance.OnTimeout(this.Message);
132138

@@ -160,6 +166,23 @@ public void OnTargetSiloFail()
160166
this.context.Complete(Response.FromException(exception));
161167
}
162168

169+
public void OnHostShutdown()
170+
{
171+
if (Interlocked.CompareExchange(ref completed, 1, 0) != 0)
172+
{
173+
return;
174+
}
175+
176+
stopwatch.Stop();
177+
shared.Unregister(Message);
178+
_cancellationTokenRegistration.Dispose();
179+
_applicationRequestInstruments.OnAppRequestsEnd((long)stopwatch.Elapsed.TotalMilliseconds);
180+
181+
var message = Message;
182+
var exception = new SiloUnavailableException($"The local Orleans host is shutting down and can no longer process the request: {message}.");
183+
context.Complete(Response.FromException(exception));
184+
}
185+
163186
public void DoCallback(Message response)
164187
{
165188
if (Interlocked.CompareExchange(ref this.completed, 1, 0) != 0)

src/Orleans.Core/Runtime/GrainReferenceRuntime.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private async ValueTask InvokeMethodWithFiltersAsync(GrainReference reference, I
106106
}
107107
}
108108

109-
private ValueTask<TResult> InvokeMethodAsyncCore<TResult>(GrainReference reference, IInvokable request, InvokeMethodOptions options)
109+
private ValueTask<TResult?> InvokeMethodAsyncCore<TResult>(GrainReference reference, IInvokable request, InvokeMethodOptions options)
110110
{
111111
ResponseCompletionSource<TResult> responseCompletionSource;
112112
try
@@ -123,7 +123,7 @@ private ValueTask<TResult> InvokeMethodAsyncCore<TResult>(GrainReference referen
123123
}
124124
}
125125

126-
private static async ValueTask<TResult> CompleteInvokeAsync<TResult>(ResponseCompletionSource<TResult> responseCompletionSource, IInvokable request, InvokeMethodOptions options)
126+
private static async ValueTask<TResult?> CompleteInvokeAsync<TResult>(ResponseCompletionSource<TResult> responseCompletionSource, IInvokable request, InvokeMethodOptions options)
127127
{
128128
try
129129
{

src/Orleans.Runtime/Core/InsideRuntimeClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ public async Task Invoke(IGrainContext target, Message message)
386386
{
387387
if (disposeRequest)
388388
{
389-
request.Dispose();
389+
request!.Dispose();
390390
if (ReferenceEquals(message.BodyObject, request))
391391
{
392392
message.BodyObject = null;

0 commit comments

Comments
 (0)