Anton Vinogradov created IGNITE-28948:
-----------------------------------------

             Summary: Find generated message companions without reflection
                 Key: IGNITE-28948
                 URL: https://issues.apache.org/jira/browse/IGNITE-28948
             Project: Ignite
          Issue Type: Task
          Components: messaging
            Reporter: Anton Vinogradov


Codegen writes a companion class next to every message: 
{{<message>Serializer}}, {{<message>Marshaller}} and, for cache messages, 
{{<message>Deployer}}. At run time the node finds them by rebuilding the name 
and calling {{Class.forName}}:

{code:java}
// codegen, MessageCompanionGenerator
String clsName = type.getSimpleName() + typeSuffix();   // "Serializer" / 
"Marshaller" / "Deployer"

// run time, AbstractMarshallableMessageFactoryProvider
Class.forName(cls.getName() + suffix, true, 
cls.getClassLoader()).getConstructors()[0];
{code}

So the same naming rule is written twice, on both sides, and the link between a 
message and its companion is a string.

Why this is worth changing:
* A wrong or renamed companion is found only when a node starts, not when the 
code is built.
* Every registered message does a reflective class lookup at start. In core 
alone that is 300 registered messages, and codegen currently produces 510 
serializers, 212 marshallers and 31 deployers.
* The same rule is repeated outside the provider: {{IgniteUtils}} and 
{{GridTestUtils}} build companion names by hand as well.
* Extensions and plugins that extend 
{{AbstractMarshallableMessageFactoryProvider}} depend on the naming rule too.

What to do: codegen already knows every message and its companions while it 
compiles, and then throws that away. Let {{MessageProcessor}} generate, in 
{{processingOver()}}, one registry class per module holding direct references 
instead of names:

{code:java}
public final class GeneratedCompanions {
    static {
        put(GridDhtPartitionsFullMessage.class,
            GridDhtPartitionsFullMessageSerializer::new,
            GridDhtPartitionsFullMessageMarshaller::new,
            null);
        ...
    }
}
{code}

The factory provider then asks the registry, and {{Class.forName}}, the name 
suffixes and the lookup cache all go away.

Expected result:
* A missing or misnamed companion becomes a compile error.
* No reflective lookups while a node starts.
* The naming rule stays inside codegen, where the names are made.

To watch out for: {{AbstractMarshallableMessageFactoryProvider}} is a public 
extension point, used by ignite-extensions and by plugins, so its contract 
changes and those users need a migration path. Registries are per module, so 
the module registries have to be joined.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to