nizhikovprivate commented on PR #13410:
URL: https://github.com/apache/ignite/pull/13410#issuecomment-5116931925

   # Review: IGNITE-28929 — Move marshaller info into Messages classes
   
   **State reviewed**: branch at `b8cf88d250f`, against `master`. 321 files, 
~735 insertions.
   
   **Verdict: LGTM with two optional hardening suggestions.** The design is 
sound, the annotation sweep is exhaustively verified correct, and the one 
blocker found during review has been fixed and verified at build and runtime 
level.
   
   ## What the change does
   
   Per the Jira ticket (IEP-132 Communication), marshaller selection moves from 
registration-site arguments into the message classes themselves via two new 
runtime annotations, `@UseJdkMarshaller` and `@UseBinaryMarshaller` 
(`org.apache.ignite.internal`). 
`AbstractMarshallableMessageFactoryProvider.register` resolves the marshaller 
from the annotation (`dfltMarsh` vs `schemaAwareMarsh` slot) and throws 
`IllegalStateException` if a class carries neither. 
`CoreMessagesProvider.withSchema`/`withNoSchema` remain as assertion-backed 
documentation of intent; the Calcite and ZK factories drop their explicit 
marshaller arguments.
   
   ## Verified correct (mechanically, not sampled)
   
   - **All 297 core registrations match**: every `withNoSchema` class carries 
`@UseJdkMarshaller`, every `withSchema` class `@UseBinaryMarshaller` — zero 
mismatches. Wire format is therefore unchanged for all core messages.
   - **All 12 Calcite registrations match** master's explicit arguments 
(`QueryStartRequest`, `GenericValueMessage` → binary; the other ten → JDK). 
**All 6 ZK classes** correctly carry `@UseJdkMarshaller`.
   - **Coverage is exact both directions**: 315 annotated classes = 315 
registrations; no double-annotated class, no annotated-but-unregistered class, 
no leftover caller of removed overloads.
   - **Build**: full `mvn install` of core, zookeeper, and all upstream modules 
passes.
   - **Runtime**: a probe registering `ZkMessageFactory` into a real 
`IgniteMessageFactoryImpl` and calling `create()` for ids 400–405 instantiates 
all six ZK messages cleanly.
   
   ## Blocker — found, fixed, verified
   
   The original commit routed `ZkMessageFactory` through the reflective 
`register(factory, cls, id)` path. Two ZK message classes are package-private, 
which breaks reflection from the provider's package (confirmed empirically):
   
   1. `ZkNoServersMessage` — implicit package-private constructor → 
`NoSuchMethodException` → **node startup failure** with ZK discovery.
   2. `ZkCommunicationErrorResolveFinishMessage` — public ctor in non-public 
class → `IllegalAccessException` on first `create(400)`, a latent crash in the 
communication-error-resolve path.
   
   The fix (in `b8cf88d250f`) restores a `protected register(factory, cls, id, 
supplier)` overload and passes in-package `::new` references from 
`ZkMessageFactory`. It improves on the pre-change design: the supplier overload 
takes no marshaller argument — annotation resolution happens inside it, so the 
annotation stays the single source of truth on both paths. The "use this 
overload for package-private classes" javadoc now sits on the protected 
overload where callers see it. Verified by inspection, module build, and the 
runtime probe above.
   
   ## Remaining suggestions (non-blocking)
   
   1. **Assert-only validation**: the both-annotations-present conflict check 
in `AbstractMarshallableMessageFactoryProvider.register` and the 
annotation-vs-`withSchema`/`withNoSchema` consistency checks in 
`CoreMessagesProvider` are `assert`s, which vanish in production. A future 
mis-annotation would then *silently change the wire format* instead of failing 
fast — with assertions disabled, the `if/else-if` ordering quietly prefers JDK 
on conflict. These run once at startup over ~300 classes, so hard 
`IllegalStateException`s cost nothing.
   2. **Annotation javadoc precision**: 
`@UseJdkMarshaller`/`@UseBinaryMarshaller` hard-name concrete marshallers, but 
they actually select the injected `dfltMarsh`/`schemaAwareMarsh` slots, which 
plugins may override via `init()`. One clarifying sentence would prevent wrong 
assumptions.
   
   ## Notes for the record
   
   - The 3-arg overload's javadoc ("Register a message with a caller-provided 
`id`") doesn't distinguish it from the 4-arg — its actual contract is 
"instantiates reflectively via the public no-arg ctor; class must be public." 
Cosmetic.
   - Removing/privatizing the old `protected static register` overloads breaks 
third-party subclasses compiled against them; acceptable for an `internal` 
package, but worth a quick check that nothing in ignite-extensions extends this 
class before merge.
   - The whitespace-only hunks in `SessionChannelMessage`, 
`DataStreamerResponse`, `TcpInverseConnectionResponseMessage` are harmless 
cleanups; `@Target(value = TYPE)` vs `@Target(TYPE)` and a stray blank import 
line in `UseJdkMarshaller.java` are style trivia.
   - Suggest running the ZK discovery and Calcite suites on TC before merge — 
the blocker showed those paths weren't exercised locally.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to