zhaohai666 opened a new pull request, #1368:
URL: https://github.com/apache/rocketmq-clients/pull/1368
# fix(nodejs): align client behaviors with the Java client (defect fixes)
## Summary
This PR fixes **24 defects** in the Node.js client found by auditing it
against the mature Java client (rocketmq 5.x), covering **two audit rounds**:
- **Round 1 (7 fixes)**: retry backoff unit contract, protobuf Duration
sub-second precision, `CustomizedBackoffRetryPolicy`, Endpoints string parsing
(IPv6 / http(s) prefix), `StatusChecker` mappings, telemetry session timer
leak, fail-fast on startup route fetch.
- **Round 2 (11 fixes in `0a84b7eb`)**: gRPC target resolver scheme, RPC
client keying, channel options, heartbeat-driven rejoin & transport
self-healing, verify-message reply, process diagnostics, FIFO floorMod routing,
shutdown drain timeout, SimpleConsumer state guard, lite subscription
multi-endpoint sync.
Out of scope (intentionally not changed): Resource `resourceNamespace`
population (K-1), lite `SimpleConsumer` missing helpers (E-2).
## Round 2 changes
| # | Area | Fix |
|---|------|-----|
| B-1 | `Endpoints.getGrpcTarget()` | Prefix gRPC target with resolver
scheme — `ipv4:` / `ipv6:` (bracket IPv6 hosts) / `dns:` — otherwise grpc-js
mis-resolves multi-address and bare-IPv6 targets |
| B-2 | `RpcClientManager` | Key rpc clients by `endpoints.facade` string
instead of `Endpoints` object identity (endpoints are recreated on every route
fetch, leaking duplicate channels); add `evict()` |
| B-3 | `RpcClient` | Add channel options: keepalive 5min/30s +
`keepalive_permit_without_calls`, max send/receive message length `2^31-1`
(mirrors Java Netty defaults) |
| F-1 | `BaseClient` heartbeat | Rejoin isolated endpoints after a
successful heartbeat (mirrors Java `ClientImpl#doHeartbeat`) |
| D-2 | `BaseClient` heartbeat | After ≥2 consecutive heartbeat failures,
rebuild the transport layer: evict the stale `RpcClient` + rebuild telemetry
session (re-syncs settings), throttled by a 30s per-endpoints cooldown |
| D-1 | Verify message command | Reply with `VerifyMessageResult` carrying
the nonce (oneof `verify_message_result`), instead of echoing
`VerifyMessageCommand` |
| D-3 | Stack trace command | Return real process diagnostics (pid, node
version, uptime, memoryUsage, active handles) instead of `'mock stack'` |
| C-1 | `PublishingLoadBalancer` | Interpret SipHash-2-4 as signed int64 and
apply floorMod so FIFO message-group routing matches Java `LongMath.mod`
(previously unsigned modulo routed "negative" hashes to different queues) |
| H-1 | `PushConsumer` shutdown | Bound the cached-message drain wait by
`requestTimeout + longPollingTimeout` so shutdown cannot hang forever on a
stuck consumption chain |
| G-1 | `SimpleConsumer` | Guard `receive()` / `ack()` /
`changeInvisibleDuration()` with `isRunning()` checks |
| E-1 | `LiteSubscriptionManager` | Sync lite subscriptions to **all** route
endpoints (not only the client's configured endpoints), matching the Java
client; adds a public `LitePushConsumerImpl#getTotalRouteEndpoints()` wrapper |
## Round 1 changes (`d7a6a3a2`, `f5fbde3b`)
- Retry delays are milliseconds (seconds in the protobuf contract was
misimplemented); `inheritBackoff` keeps sub-second precision from server
`Duration` (`seconds*1000 + nanos/1e6`).
- New `CustomizedBackoffRetryPolicy` wired into `PushSubscriptionSettings`
(out-of-range steps clamp to the last duration).
- `Endpoints` string parsing rewritten: strips `http(s)://`, parses
bracketed and bare IPv6, ports via `lastIndexOf(':')`.
- `StatusChecker` adds mappings: `ILLEGAL_LITE_TOPIC` → BadRequest,
`MESSAGE_BODY_EMPTY` → PayloadEmpty, `LITE_SUBSCRIPTION_QUOTA_EXCEEDED` →
LiteSubscriptionQuotaExceeded.
- `TelemetrySession` no longer leaks reconnect timers: `release()` clears
the timer and guards reconnection; errors/ends dedupe through a single
reconnect schedule.
- Startup route fetch fails fast on `NotFoundException`.
## Test plan
- `tsc --noEmit` against both `tsconfig.prod.json` and `tsconfig.json` —
green.
- Offline unit/regression suite (`node --test`): **110/110 pass**, including
new coverage for grpc-target scheme prefixes and signed-hash floorMod routing
(negative-hash probe).
- Integration tests against a local RocketMQ 5.5.1 cluster (proxy :8081):
**17/17 pass** (Producer send/transaction/recall, SimpleConsumer
receive/ack/invisible-duration, index).
## Commits
- `d7a6a3a2` fix(nodejs): align retry units, endpoints parsing and status
mapping with Java client
- `f5fbde3b` fix(nodejs): fail fast on NotFoundException during startup
route fetch
- `0a84b7eb` fix(nodejs): align client behaviors with Java reference (round
2)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]