[
https://issues.apache.org/jira/browse/IGNITE-28618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Alex Abashev updated IGNITE-28618:
----------------------------------
Description:
h2. Summary
Receive-side mirror of IGNITE-28520. Same motivation, same mechanism — but for
the {{finishUnmarshal}} direction.
The post-deserialisation pass already runs on the user-listener-dispatch
thread: {{GridCacheIoManager.unmarshall}} calls
{{cacheMsg.finishUnmarshal(cctx, ldr)}} on the dispatch thread before handing
the message to {{processMessage}}. Just like on the send side, every
{{GridCacheMessage}} subclass with {{CacheObject}} fields has a hand-written
{{finishUnmarshal(GridCacheSharedContext, ClassLoader)}} override that walks
those fields and calls {{co.finishUnmarshal(ctx, ldr)}}. Same maintenance
hazard: a missed override silently shifts the {{Marshaller.unmarshal}} call
onto the NIO reader (when something later asks for {{val}} via
{{valueBytes(ctx)}}).
This ticket adds the symmetric generated method and auto-invoke so coverage is
structural.
h2. What changes
* {{MessageSerializer}} gets {{default void finishUnmarshalCacheObjects(M msg,
CacheObjectValueContext ctx, ClassLoader ldr)}} (no-op default).
* {{MessageSerializerGenerator}} emits {{finishUnmarshalCacheObjects}} on every
concrete serializer with at least one traversable {{@Order}} field, with
recursion into nested {{Message}} types via
{{*_SER.finishUnmarshalCacheObjects(...)}}; map traversal walks both keys and
values.
* {{GridCacheIoManager.unmarshall}} adds
{{finishUnmarshalGeneratedCacheObjects(cacheMsg, ldr)}} *before* the existing
{{cacheMsg.finishUnmarshal(cctx, ldr)}} (legacy code may rely on {{val}} being
already populated for tx-key hashing / validation, so auto-invoke runs first).
Helper gated the same way as the send-side: {{instanceof GridCacheIdMessage}},
context from the outer message's {{cacheId}}.
* Hand-written {{finishUnmarshal(GridCacheSharedContext, ClassLoader)}}
overrides are removed where the body was a pure {{@Order}}-CO traversal — same
set as the send-side cleanup:
** {{GridCacheTtlUpdateRequest}}, {{GridDhtForceKeysRequest}},
{{GridNearUnlockRequest}}, {{GridDhtUnlockRequest}},
{{GridDistributedLockRequest}}, {{GridDistributedLockResponse}},
{{GridDhtAtomicUpdateResponse}}, {{GridDhtAtomicNearResponse}},
{{GridNearGetRequest}}.
** Also dropped: {{ret.finishUnmarshal(cctx, ldr)}} call inside
{{GridNearAtomicUpdateResponse.finishUnmarshal}} (covered by nested-message
recursion).
* {{GridCacheReturn.finishUnmarshal}} delegates the {{CacheObject}} traversal
to the generated {{GridCacheReturnSerializer.finishUnmarshalCacheObjects}}
(mirror of the existing {{prepareMarshal}} bridge); the post-traversal
binary-unwrapping ({{unwrapBinaryIfNeeded}} of {{cacheObj}} and
{{invokeResCol}}, building the {{CacheInvokeResult}} map into {{v}}) stays
inline — it is not part of the serializer contract.
h2. Out of scope
* Send-side migration is IGNITE-28520; this ticket only mirrors it.
* Extending auto-invoke beyond {{GridCacheIdMessage}} for either direction —
IGNITE-ZZZZZ.
h2. Acceptance criteria
* {{GridCacheIoManager.unmarshall}} invokes
{{finishUnmarshalGeneratedCacheObjects(cacheMsg, ldr)}} for every
{{GridCacheIdMessage}} subclass with a non-{{null}} {{cacheObjectContext}},
before the legacy {{finishUnmarshal}} hook.
* {{MessageProcessorTest}} green with regenerated fixtures (each fixture now
has both {{prepareMarshalCacheObjects}} and {{finishUnmarshalCacheObjects}}).
* Same targeted-suite gating as IGNITE-28520; in addition:
{{IgniteCacheQueryMultiThreadedSelfTest}},
{{GridCacheReturnValueTransferSelfTest}} cover both directions on the same flow.
* TC-bot possible-blockers — no real regressions on read paths.
was:
h2. Summary
Receive-side mirror of IGNITE-28520. Move the generic post-deserialisation
{{CacheObject.finishUnmarshal}} traversal off the NIO worker by adding
{{finishUnmarshalCacheObjects}} to {{MessageSerializer}} and auto-invoking it
from {{GridCacheIoManager.unmarshall}} on the user-listener-dispatch thread,
before the message is handed to {{processMessage}}.
After this lands the receive path looks like:
# {{ser.finishUnmarshalCacheObjects(msg, cacheObjCtx, ldr)}} — new auto-invoked
traversal of {{@Order}}-annotated {{CacheObject}} / nested {{Message}} fields;
# {{cacheMsg.finishUnmarshal(cctx, ldr)}} — existing hand-written hook
(legacy), runs after.
The same ordering rationale as send-side: legacy may rely on {{val}} being
already populated (for tx-key hashing, validation, etc.), so auto-invoke must
run first.
h2. Scope
* Add {{default void finishUnmarshalCacheObjects(M msg, CacheObjectValueContext
ctx, ClassLoader ldr)}} to {{MessageSerializer}} (no-op default).
* {{MessageSerializerGenerator}}: emit symmetric
{{finishUnmarshalCacheObjects}} method (with {{@Override}}) on every serializer
with traversable {{@Order}} fields; recurse via per-class
{{*_SER.finishUnmarshalCacheObjects(...)}}; map traversal walks both sides (key
+ value).
* {{GridCacheIoManager.unmarshall}}: add
{{finishUnmarshalGeneratedCacheObjects(cacheMsg, ldr)}} call before
{{cacheMsg.finishUnmarshal(cctx, ldr)}}; helper gated on {{instanceof
GridCacheIdMessage}} mirror of the prepare-side.
* Phase 2 cleanup: where a {{GridCacheMessage}} subclass
{{finishUnmarshal(GridCacheSharedContext, ClassLoader)}} override is a pure
{{@Order}}-CO traversal, drop it. Mirror list from IGNITE-28520:
** {{GridCacheTtlUpdateRequest}}, {{GridDhtForceKeysRequest}},
{{GridNearUnlockRequest}}, {{GridDhtUnlockRequest}},
{{GridDistributedLockRequest}}, {{GridDistributedLockResponse}},
{{GridDhtAtomicUpdateResponse}}, {{GridDhtAtomicNearResponse}},
{{GridNearGetRequest}}, {{GridNearAtomicUpdateResponse.finishUnmarshal}} — line
{{ret.finishUnmarshal(cctx, ldr)}}.
* Update {{GridCacheReturn.finishUnmarshal}} to delegate the {{CacheObject}}
traversal to the generated
{{GridCacheReturnSerializer.finishUnmarshalCacheObjects}} (mirror of current
{{prepareMarshal}} bridge); the post-traversal binary-unwrapping
({{unwrapBinaryIfNeeded}} of {{cacheObj}} and {{invokeResCol}}, building the
{{CacheInvokeResult}} map into {{v}}) stays inline — it is not part of the
serializer contract.
h2. Out of scope
* The send-side migration is IGNITE-28520; this ticket only mirrors it for the
receive side.
* Extending auto-invoke beyond {{GridCacheIdMessage}} for either direction —
IGNITE-ZZZZZ.
h2. Acceptance criteria
* {{GridCacheIoManager.unmarshall}} invokes the new helper for
{{GridCacheIdMessage}} subclasses, before the legacy {{finishUnmarshal}} call.
* {{MessageProcessorTest}} green with regenerated fixtures (each fixture now
has both {{prepareMarshalCacheObjects}} and {{finishUnmarshalCacheObjects}}).
* Same targeted-suite gating as IGNITE-28520; in addition:
{{IgniteCacheQueryMultiThreadedSelfTest}},
{{GridCacheReturnValueTransferSelfTest}} cover both directions.
> Move finishUnmarshal out of NIO communication thread
> ----------------------------------------------------
>
> Key: IGNITE-28618
> URL: https://issues.apache.org/jira/browse/IGNITE-28618
> Project: Ignite
> Issue Type: Sub-task
> Reporter: Alex Abashev
> Priority: Major
>
> h2. Summary
> Receive-side mirror of IGNITE-28520. Same motivation, same mechanism — but
> for the {{finishUnmarshal}} direction.
> The post-deserialisation pass already runs on the user-listener-dispatch
> thread: {{GridCacheIoManager.unmarshall}} calls
> {{cacheMsg.finishUnmarshal(cctx, ldr)}} on the dispatch thread before handing
> the message to {{processMessage}}. Just like on the send side, every
> {{GridCacheMessage}} subclass with {{CacheObject}} fields has a hand-written
> {{finishUnmarshal(GridCacheSharedContext, ClassLoader)}} override that walks
> those fields and calls {{co.finishUnmarshal(ctx, ldr)}}. Same maintenance
> hazard: a missed override silently shifts the {{Marshaller.unmarshal}} call
> onto the NIO reader (when something later asks for {{val}} via
> {{valueBytes(ctx)}}).
> This ticket adds the symmetric generated method and auto-invoke so coverage
> is structural.
> h2. What changes
> * {{MessageSerializer}} gets {{default void finishUnmarshalCacheObjects(M
> msg, CacheObjectValueContext ctx, ClassLoader ldr)}} (no-op default).
> * {{MessageSerializerGenerator}} emits {{finishUnmarshalCacheObjects}} on
> every concrete serializer with at least one traversable {{@Order}} field,
> with recursion into nested {{Message}} types via
> {{*_SER.finishUnmarshalCacheObjects(...)}}; map traversal walks both keys and
> values.
> * {{GridCacheIoManager.unmarshall}} adds
> {{finishUnmarshalGeneratedCacheObjects(cacheMsg, ldr)}} *before* the existing
> {{cacheMsg.finishUnmarshal(cctx, ldr)}} (legacy code may rely on {{val}}
> being already populated for tx-key hashing / validation, so auto-invoke runs
> first). Helper gated the same way as the send-side: {{instanceof
> GridCacheIdMessage}}, context from the outer message's {{cacheId}}.
> * Hand-written {{finishUnmarshal(GridCacheSharedContext, ClassLoader)}}
> overrides are removed where the body was a pure {{@Order}}-CO traversal —
> same set as the send-side cleanup:
> ** {{GridCacheTtlUpdateRequest}}, {{GridDhtForceKeysRequest}},
> {{GridNearUnlockRequest}}, {{GridDhtUnlockRequest}},
> {{GridDistributedLockRequest}}, {{GridDistributedLockResponse}},
> {{GridDhtAtomicUpdateResponse}}, {{GridDhtAtomicNearResponse}},
> {{GridNearGetRequest}}.
> ** Also dropped: {{ret.finishUnmarshal(cctx, ldr)}} call inside
> {{GridNearAtomicUpdateResponse.finishUnmarshal}} (covered by nested-message
> recursion).
> * {{GridCacheReturn.finishUnmarshal}} delegates the {{CacheObject}} traversal
> to the generated {{GridCacheReturnSerializer.finishUnmarshalCacheObjects}}
> (mirror of the existing {{prepareMarshal}} bridge); the post-traversal
> binary-unwrapping ({{unwrapBinaryIfNeeded}} of {{cacheObj}} and
> {{invokeResCol}}, building the {{CacheInvokeResult}} map into {{v}}) stays
> inline — it is not part of the serializer contract.
> h2. Out of scope
> * Send-side migration is IGNITE-28520; this ticket only mirrors it.
> * Extending auto-invoke beyond {{GridCacheIdMessage}} for either direction —
> IGNITE-ZZZZZ.
> h2. Acceptance criteria
> * {{GridCacheIoManager.unmarshall}} invokes
> {{finishUnmarshalGeneratedCacheObjects(cacheMsg, ldr)}} for every
> {{GridCacheIdMessage}} subclass with a non-{{null}} {{cacheObjectContext}},
> before the legacy {{finishUnmarshal}} hook.
> * {{MessageProcessorTest}} green with regenerated fixtures (each fixture now
> has both {{prepareMarshalCacheObjects}} and {{finishUnmarshalCacheObjects}}).
> * Same targeted-suite gating as IGNITE-28520; in addition:
> {{IgniteCacheQueryMultiThreadedSelfTest}},
> {{GridCacheReturnValueTransferSelfTest}} cover both directions on the same
> flow.
> * TC-bot possible-blockers — no real regressions on read paths.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)