orleans icon indicating copy to clipboard operation
orleans copied to clipboard

Use compound type aliases for generated classes

Open ReubenBond opened this issue 1 year ago • 2 comments

Currently, generated classes are identified by name directly. This works for most cases, but it is not version-tolerant. For example, given the following interface definition:

public interface IGrainWithGenericMethods : IMyInvokableBaseType 
{
    Task<T> RoundTrip<T>(T val);
}

The serializer will generate an invokable named OrleansCodeGen.Orleans.Serialization.UnitTests.Invokable_IGrainWithGenericMethods_GrainReference_1_1<>

If the IGrainWithGenericMethods interface was to change name, then this class would change name, but there is no way to associate an alias on the former with the latter today. Similarly, if another method was added to the class, or the method name was changed, that could result in the method no longer having the same identifier, breaking version tolerance.

This PR introduces the concept of compound type aliases into the serializer type system in order to handle these cases. An attribute is placed on the generated class, such as: [CompoundTypeAliasAttribute("inv", typeof(GrainReference), typeof(IGrainWithGenericMethods), "1")]. This can be interpreted as "The invoker for the proxy base type GrainReference for the interface IGrainWtihGenericMethod and method id 1".

These compound type aliases are added to the assembly metadata in the form of a tree which can be queried at runtime to resolve aliases back to the original type.

When the type is serialized, the attribute is found and the name is encoded as a tuple, ("inv", GrainReference, IGrainWithGenericMethods, "1"), with generic type parameters appended as per usual. During encoding, the types in that expression are replaced with their aliases (eg, WellKnownAlias, if one is set). During decoding, the aliases for the individual component types are replaced with their original types and the expression is compared to metadata to resolve the original type.

This allows individual components to have type aliases and allows the type to survive refactoring.

Microsoft Reviewers: Open in CodeFlow

ReubenBond avatar Aug 23 '22 23:08 ReubenBond

@benjaminpetit ptal @pentp please take a look, too, if you get the chance :)

ReubenBond avatar Sep 14 '22 22:09 ReubenBond

It would be nice to have some tests for that, I think it should be doable to add them to the heterogeneous tests

benjaminpetit avatar Sep 20 '22 13:09 benjaminpetit

TODO:

  • [x] hash grain methods to generate method id
  • [x] Add analyzer to annotate methods with their id to enable refactoring
  • [x] Tests for string-based method aliases

ReubenBond avatar Sep 29 '22 16:09 ReubenBond

@benjaminpetit PTAL

ReubenBond avatar Oct 10 '22 23:10 ReubenBond