Skip to content

[Bug] EventHub action name mismatch silently drops cache invalidation events in legacy path #3012

@imbajin

Description

@imbajin

Summary

While working on #3011, @dpol1 spotted a potential silent-drop bug in the legacy EventHub cache-notification path. This issue tracks the investigation and fix.

Root Cause

Cache.java defines four string constants:

// present-tense — "command" semantics
String ACTION_INVALID   = "invalid";
String ACTION_CLEAR     = "clear";

// past-tense — "event happened" semantics
String ACTION_INVALIDED = "invalided";
String ACTION_CLEARED   = "cleared";

Producers emit past-tense events:

File Lines Emitted action
CachedGraphTransaction.java 400, 414, 428 ACTION_INVALIDED, ACTION_CLEARED
CachedSchemaTransaction.java 182, 224, 233, 286 ACTION_INVALIDED, ACTION_CLEARED

Local listeners only match present-tense events:

File Lines Listened action
CachedGraphTransaction.java 147, 179 ACTION_INVALID, ACTION_CLEAR
CachedSchemaTransaction.java 120, 127 ACTION_INVALID, ACTION_CLEAR
CachedSchemaTransactionV2.java 117, 137 ACTION_INVALID, ACTION_CLEAR

How the Current Bridge Works

StandardHugeGraph.AbstractCacheNotifier (StandardHugeGraph.java:1397) listens for "invalided"/"cleared" and converts them into RPC calls to remote nodes. Remote nodes then call AbstractCacheNotifier.invalid/clear(), which emits "invalid"/"clear" on their local hubs — which local listeners do catch.

Local transaction commits
  → notifyChanges("invalided") on local schemaEventHub
  → AbstractCacheNotifier.listener catches "invalided"
  → proxy.invalid(type, id)  ← RPC call to remote nodes only
  → Remote node: AbstractCacheNotifier.invalid() emits "invalid" on remote hub
  → Remote CachedSchemaTransaction.listener catches "invalid" ✓

Where Events Are Silently Dropped

The bridge only routes to remote nodes via RPC. The local node never re-emits "invalid" after "invalided" is published, which means:

  1. Single-node / no-RPC deployments: proxy is a no-op; "invalided" events from CachedSchemaTransaction/CachedGraphTransaction are consumed by AbstractCacheNotifier and go nowhere. Local consistency is currently maintained by direct updateCache() calls inside each transaction, but any secondary consumer that relies solely on the EventHub would miss these events.

  2. If the RPC proxy is misconfigured or unavailable: The "invalided" event is silently swallowed — no error, no fallback.

  3. Concurrent local transactions: Due to the containsListener guard (only one listener per hub/event), if a second transaction instance needs to be notified via EventHub it will not be — a latent hazard in scenarios where multiple transactions share the same EventHub.

Suggested Fix

Align the action constants: either

  • Have producers emit present-tense (ACTION_INVALID / ACTION_CLEAR) and remove the past-tense constants, or
  • Have AbstractCacheNotifier also re-publish "invalid"/"clear" locally after forwarding the RPC, so local listeners are always notified.

The safer approach is option 1: unify on present-tense ACTION_INVALID / ACTION_CLEAR throughout, since RaftContext (RaftContext.java:287,313) already uses the present-tense constants correctly.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions