Skip to content

fix: keep entity verticle requests local when a local instance exists - #793

Merged
ikalachy merged 1 commit into
mainfrom
fix/entity-verticle-local-routing
Aug 12, 2026
Merged

fix: keep entity verticle requests local when a local instance exists#793
ikalachy merged 1 commit into
mainfrom
fix/entity-verticle-local-routing

Conversation

@ikalachy

Copy link
Copy Markdown
Contributor

Problem

Entity verticles register a consumer at the shared FQN address EntityVerticle[<FQN>] which forwards to the co-located DataVerticle[<name>] instance. In a clustered setup where the same entity verticle runs on multiple nodes, both addresses are registered on every node, so a request could be round-robined to a remote instance.

When the remote instance replies with an EntityWrapper for an entity type whose OData model is not buffered on the requesting node, EntityWrapperMessageCodec.encodeToWire fails, the reply is never delivered, and the caller times out after 30s — surfacing as an intermittent HTTP 500.

This was observed in production on the calendar service: TimelineEvents intermittently 500'd because its nested ProductMaping entity request round-robined cross-node and the (unmodeled) EntityWrapper reply could not be serialized back.

Fix

Two changes in AbstractEntityVerticle:

  1. Inner forward is local-only — the FQN consumer forwards to ownAddress with setLocalOnly(true). Its only job is to hand off to the co-located instance; it must never round-robin across the cluster.
  2. FQN address registered as a local consumer — on deployment the EntityVerticle[<FQN>] address is added to NeonBee's local-consumer registry (and removed on stop()), so local-preferred requests resolve to the local instance.

Test

EntityVerticleLocalPreferredClusterTest uses the in-JVM FakeClusterManager (no external infra, CI-safe). Deploys a node-tagging entity verticle on both nodes and asserts requests with a local instance always resolve locally. Verified it fails without the fix (30s reply timeout on DataVerticle[...]) and passes with it.

Entity verticles register a consumer at the shared FQN address
EntityVerticle[<FQN>] which forwards to the co-located DataVerticle[<name>]
instance. In a clustered setup where the same entity verticle runs on
multiple nodes, both addresses exist on every node, so requests could be
round-robined to a remote instance. When that remote instance replies with
an EntityWrapper for an entity type whose model is not buffered on the
requesting node, the reply cannot be deserialized and the caller times out
after 30s (surfacing as HTTP 500).

Two changes in AbstractEntityVerticle:
- The FQN consumer now forwards to ownAddress with setLocalOnly(true), so
  the inner hop always reaches the co-located instance and never
  round-robins across the cluster.
- The FQN address is registered as a NeonBee local consumer on deployment
  (and unregistered on stop), so local-preferred requests resolve to the
  local instance instead of crossing nodes.

Adds EntityVerticleLocalPreferredClusterTest (FakeClusterManager, CI-safe)
which fails without the fix (30s reply timeout) and passes with it.
@ikalachy
ikalachy requested a review from a team as a code owner August 12, 2026 13:20
@ikalachy
ikalachy merged commit b12652b into main Aug 12, 2026
7 checks passed
@ikalachy
ikalachy deleted the fix/entity-verticle-local-routing branch August 12, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants