Skip to content

IGNITE-29227 Fix lost continuous query events with an unregistered transformer result class on an ATOMIC cache - #13769

Open
rezataroosheh wants to merge 4 commits into
apache:masterfrom
rezataroosheh:IGNITE-29227
Open

rezataroosheh wants to merge 4 commits into
apache:masterfrom
rezataroosheh:IGNITE-29227

Conversation

@rezataroosheh

@rezataroosheh rezataroosheh commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

JIRA: https://issues.apache.org/jira/browse/IGNITE-29227

What

A ContinuousQueryWithTransformer on an ATOMIC cache now delivers the events of a partition whose primary is another node when the class of the transformer result is not yet registered on that node. Before this fix, the listener got none of these events, and later events of the same partition were held as well.

Why

On the primary node, an ATOMIC update notifies the continuous query while it holds the topology read lock. For a listener on another node, CacheContinuousQueryHandler#transformToEntry converts the transformer result to a cache object. Registering a new class is not allowed under the topology lock, so the conversion throws UnregisteredClassException part-way through the notification. GridDhtAtomicCache then registers the class and retries the update with the next update counter. The event for the first counter is never sent, so CacheContinuousQueryPartitionRecovery on the listener node holds the partition's later events, waiting for it. It was reported on the dev list.

The fix splits the notification for a listener on another node of an ATOMIC cache into two parts:

  • The transformer still runs in the update thread, as before. So a transformer error, for example, a P2P class-loading problem, still fails the update (P2PClassLoadingFailureHandlingTest).
  • Converting the result to a cache object and sending it (the new notifyRemoteListener) runs in the async callback pool, striped by partition, so the events of a partition keep their order. This runs outside the topology lock, so the class can be registered there.

Local listeners, TRANSACTIONAL caches and queries with an @IgniteAsyncCallback filter keep their current behavior.

This is one possible approach. I'm open to another direction if you prefer.

Workaround for current versions: a remote filter annotated with @IgniteAsyncCallback that accepts all events. With it, the test below passes without the fix.

Related: IGNITE-29226 (same reporter, remote transformed events on a keep-binary cache), PR #13770.

Tests

CacheContinuousWithTransformerUnregisteredClassTest#testUnregisteredResultClassOnAtomicCache, with two server nodes and an ATOMIC cache with one backup. The query runs on the first node, and a key whose primary is the second node is put 3 times. The transformer returns PersonId, a class that is not registered yet. The test checks that all 3 events arrive as PersonId. It fails without the fix (Received: []).

P2PClassLoadingFailureHandlingTest passes unchanged.

The Contribution Checklist

  • There is a single JIRA ticket related to the pull request.
  • The web-link to the pull request is attached to the JIRA ticket.
  • The JIRA ticket has the Patch Available state.
  • The pull request body describes changes that have been made.
    The description explains WHAT and WHY was made instead of HOW.
  • The pull request title is treated as the final commit message.
    The following pattern must be used: IGNITE-XXXX Change summary where XXXX - number of JIRA issue.
  • A reviewer has been mentioned through the JIRA comments
    (see the Maintainers list)
  • The pull request has been checked by the Teamcity Bot and
    the green visa attached to the JIRA ticket (see tab PR Check at TC.Bot - Instance 1 or TC.Bot - Instance 2)

Notes

If you need any help, please email dev@ignite.apache.org or ask any advice on https://the-asf.slack.com #ignite channel.

@rezataroosheh rezataroosheh changed the title IGNITE-29227 ContinuousQueryWithTransformer on an ATOMIC cache holds a partition's events if the transformer's result class is not registered IGNITE-29227 Fix lost continuous query events with an unregistered transformer result class on an ATOMIC cache Nov 1, 2026
@rezataroosheh
rezataroosheh marked this pull request as ready for review November 1, 2026 11:46
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

Possible compatibility issues. Please, check rolling upgrade cases

This PR modifies protected classes (with Order annotation).
Changes to these classes can break rolling upgrade compatibility.

Affected files:

  • modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryHandler.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant