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)