зеркало из https://github.com/dotnet/orleans.git
Check IAddressable before DeepCopy (#2383)
* Modified CodeGenerator to check if the item being DeepCopied is an IAddressable before DeepCopying, converting to IGrainReference if so. * Modified Guard on SerializerGenerator when getting References to IAddressable types before DeepCopy to exclude concrete Grain classes * Modified CodeGenerator to check if the item being DeepCopied is an IAddressable (but not a concrete class) before DeepCopying, converting to IGrainReference if so. * Add test for nested Grain->GrainReference conversion * Improve commenting. * Handle SystemTarget & avoid IGrainObserver
This commit is contained in:
Родитель
93034a4dbf
Коммит
8fc5f39ec6
|
@ -705,12 +705,42 @@ namespace Orleans.CodeGenerator
|
|||
return getValueExpression;
|
||||
}
|
||||
|
||||
// Addressable arguments must be converted to references before passing.
|
||||
// IGrainObserver instances cannot be directly converted to references, therefore they are not included.
|
||||
ExpressionSyntax deepCopyValueExpression;
|
||||
if (typeof(IAddressable).IsAssignableFrom(this.FieldInfo.FieldType)
|
||||
&& this.FieldInfo.FieldType.GetTypeInfo().IsInterface
|
||||
&& !typeof(IGrainObserver).IsAssignableFrom(this.FieldInfo.FieldType))
|
||||
{
|
||||
var getAsReference = getValueExpression.Member(
|
||||
(IAddressable grain) => grain.AsReference<IGrain>(),
|
||||
this.FieldInfo.FieldType);
|
||||
|
||||
// If the value is not a GrainReference, convert it to a strongly-typed GrainReference.
|
||||
// C#: !(value is GrainReference) ? value.AsReference<TInterface>() : value;
|
||||
deepCopyValueExpression =
|
||||
SF.ConditionalExpression(
|
||||
SF.PrefixUnaryExpression(
|
||||
SyntaxKind.LogicalNotExpression,
|
||||
SF.ParenthesizedExpression(
|
||||
SF.BinaryExpression(
|
||||
SyntaxKind.IsExpression,
|
||||
getValueExpression,
|
||||
typeof(GrainReference).GetTypeSyntax()))),
|
||||
SF.InvocationExpression(getAsReference),
|
||||
getValueExpression);
|
||||
}
|
||||
else
|
||||
{
|
||||
deepCopyValueExpression = getValueExpression;
|
||||
}
|
||||
|
||||
// Deep-copy the value.
|
||||
Expression<Action> deepCopyInner = () => SerializationManager.DeepCopyInner(default(object));
|
||||
var typeSyntax = this.FieldInfo.FieldType.GetTypeSyntax();
|
||||
return SF.CastExpression(
|
||||
typeSyntax,
|
||||
deepCopyInner.Invoke().AddArgumentListArguments(SF.Argument(getValueExpression)));
|
||||
deepCopyInner.Invoke().AddArgumentListArguments(SF.Argument(deepCopyValueExpression)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -11,8 +11,15 @@ namespace UnitTests.GrainInterfaces
|
|||
//[ReadOnly]
|
||||
Task<int> GetCalculatedValue();
|
||||
Task SetNext(IChainedGrain next);
|
||||
Task SetNextNested(ChainGrainHolder next);
|
||||
//[ReadOnly]
|
||||
Task Validate(bool nextIsSet);
|
||||
Task PassThis(IChainedGrain next);
|
||||
Task PassThisNested(ChainGrainHolder next);
|
||||
}
|
||||
|
||||
public class ChainGrainHolder
|
||||
{
|
||||
public IChainedGrain Next { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,11 @@ namespace UnitTests.Grains
|
|||
return TaskDone.Done;
|
||||
}
|
||||
|
||||
public Task SetNextNested(ChainGrainHolder next)
|
||||
{
|
||||
State.Next = next.Next;
|
||||
return TaskDone.Done;
|
||||
}
|
||||
|
||||
public Task Validate(bool nextIsSet)
|
||||
{
|
||||
|
@ -80,6 +85,11 @@ namespace UnitTests.Grains
|
|||
return next.SetNext(this);
|
||||
}
|
||||
|
||||
public Task PassThisNested(ChainGrainHolder next)
|
||||
{
|
||||
return next.Next.SetNextNested(new ChainGrainHolder { Next = this });
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,15 @@ namespace UnitTests.General
|
|||
g1.PassThis(g2).Wait();
|
||||
}
|
||||
|
||||
[Fact, TestCategory("Functional"), TestCategory("GrainReference")]
|
||||
public void GrainReference_Pass_this_Nested()
|
||||
{
|
||||
IChainedGrain g1 = GrainClient.GrainFactory.GetGrain<IChainedGrain>(GetRandomGrainId());
|
||||
IChainedGrain g2 = GrainClient.GrainFactory.GetGrain<IChainedGrain>(GetRandomGrainId());
|
||||
|
||||
g1.PassThisNested(new ChainGrainHolder { Next = g2 }).Wait();
|
||||
}
|
||||
|
||||
[Fact, TestCategory("Functional"), TestCategory("Serialization"), TestCategory("GrainReference")]
|
||||
public void GrainReference_DotNet_Serialization()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче