Skip to content

Proposal 10 — DataPort: No lifecycle hook for connection rebinding after socket steal #12

@scottf

Description

@scottf

Problem

DataPort.connect(NatsConnection conn, NatsUri nuri, long timeoutNanos) permanently binds the conn reference at connect time. Any DataPort implementation that stores conn for lifecycle management (e.g. a write-timeout watchdog that calls conn.forceReconnect()) remains wired to the connection that originally established the socket.

After the AP socket steal, the stolen DataPort is now owned by the active ApConnection, but its stored conn still points to oldPassive. Any lifecycle event on that DataPort — write-timeout watchdog, periodic probe, etc. — will call oldPassive.forceReconnect() instead of the active connection's forceReconnect(). This means:

  • Write timeouts on the active connection are escalated to the wrong connection object
  • oldPassive.forceReconnect() triggers base reconnectImplConnect() → "Connection refused" loop
  • Active's own timeout handler is never invoked

Proposed fix

Add a reattach lifecycle method to the DataPort interface in jnats:

// In DataPort interface (io.nats.client.impl.DataPort)
/**
 * Called after a socket-steal transfers this DataPort to a new NatsConnection.
 * Implementations should rebind any stored connection reference and restart any
 * per-connection lifecycle tasks (e.g. write-timeout watchdogs) on the new owner.
 *
 * @param newConnection the NatsConnection that now owns this DataPort
 */
default void reattach(NatsConnection newConnection) {
    // default no-op for implementations without lifecycle state
}

ApConnection.reconnectImplConnect() would call stolenDataPort.reattach(this) after the steal.

Current workaround

We added a reattachToConnection(NatsConnection) method to our own DataPort subclass and call it from within the split-package ApConnection after the steal. This is not a portable solution for third-party DataPort implementations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    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