unbridled-41 opened a new issue, #4966:
URL: https://github.com/apache/rocketmq-dashboard/issues/4966

   ### Before Creating the Bug Report
   
   - [x] I have searched the [open 
issues](https://github.com/apache/rocketmq-dashboard/issues) of this repository 
and believe that this is not a duplicate. Searched for `heartbeat healthy 
consumer group`, `lastHeartbeat`, `online instance heartbeat`, `心跳`, `protocol 
tag consumer` and `客户端未上报`. The nearest are #4742 (closed: the protocol tags' 
*colour*, because `PROTOCOL_MAP` was keyed by values the API does not send — a 
different symptom, and that mapping is already fixed) and #4763 (open: test 
fixtures that use values the backend never sends).
   - [x] This is a defect in RocketMQ Studio, not a usage question and not a 
defect in another Apache RocketMQ repository.
   - [x] I can reproduce this on the current `master` branch, or I have stated 
the exact version I am running below.
   
   ### Studio Version
   
   branch: `rocketmq-studio`
   git commit id: `1ef5d860` (the revision this was written against; the fix is 
in PR #4951, branched from that commit)
   deployed as: not required for the reproduction — see Runtime Environment.
   
   ### Runtime Environment
   
   Reproduced with the frontend unit tests (`cd web && npx vitest run 
src/pages/instance/__tests__/ConsumerPage.test.tsx`), which need no browser and 
no cluster. The provider behaviour that decides the outcome is asserted by the 
backend test suite on the same commit.
   
   ### Connected RocketMQ Cluster
   
   An Apache RocketMQ instance reached through the standard metadata path, i.e. 
the deployment where `ConsumerConnections.toInstances` builds the online 
instances. No specific cluster version is needed: the fields are absent because 
the broker's `Connection` body has no such values, not because of a broker 
version.
   
   ### Describe the Bug
   
   The consumer group detail modal reports **心跳状态正常** ("the heartbeat is fine") 
from data that never arrives, and the online-instance table renders a protocol 
tag with no text in it.
   
   Every online instance is built by `ConsumerConnections.toInstances` 
(`server/src/main/java/org/apache/rocketmq/studio/provider/apache/ConsumerConnections.java:33-43`),
 which copies a client id and an address:
   
   ```java
   .map(conn -> ConsumerInstanceVO.builder()
           .clientId(conn.getClientId())
           .address(conn.getClientAddr())
           .build())
   ```
   
   `ConsumerInstanceVO` (`:33-40`) declares `protocol` and `lastHeartbeat`, so 
both serialise as absent, and `grep -rn "setLastHeartbeat\|setProtocol(" 
server/src/main/java` finds no writer for this VO (the two `protocol(...)` hits 
are `RocketMQClientProvider.java:331,413`, which build the clients-page VO). 
The broker's `Connection` carries `clientId`/`clientAddr`/`language`/`version` 
— there is no heartbeat timestamp to send.
   
   The page then draws two conclusions from that absence in 
`web/src/pages/instance/consumer.tsx`:
   
   1. **The health card** (`:2008-2013`) has three branches: 客户端连接信息不可用, `${n} 
个心跳过期`, and otherwise 心跳状态正常. The second branch can only be reached from a 
`STALE_HEARTBEAT` issue, and those require a non-null age: 
`consumerGroupDiagnostics.ts:135-138` returns `null` for a missing 
`lastHeartbeat`, `:324` tests `age !== null`, and `:431-432` therefore yields 
`maxHeartbeatAgeSeconds: null` and `staleClientCount: 0`. The third branch is 
the only reachable one, and it asserts a verdict the page cannot know.
   2. **The protocol column** (`:1181-1184`) builds its label from the missing 
value — `PROTOCOL_MAP[protocol] || { labelKey: protocol, … }` gives `labelKey = 
null`, and `t(null)` returns the key itself (`LangContext.tsx:39`, 
`translations[key]?.[lang] ?? key`) — so the cell is a coloured `<Tag>` 
containing nothing.
   
   The client type hid it: `web/src/api/metadata.ts:115-122` declares 
`protocol: string` and `lastHeartbeat: string` as non-optional, so every 
consumer compiled as if the values were always there.
   
   ### Steps to Reproduce
   
   1. `cd web && npx vitest run 
src/pages/instance/__tests__/ConsumerPage.test.tsx -t "does not call a group 
healthy when the API reports no client heartbeat"` on `1ef5d860`.
   2. The test renders the consumer page for a group with two online instances 
that carry exactly what the provider sends — a client id and an address — opens 
详情 and then the 健康诊断 tab.
   3. The run fails on both halves: the 协议 cell has no 不可用, and the card never 
shows 客户端未上报心跳时间.
   
   In a running console: open any Apache instance's consumer group whose detail 
modal lists online instances; the 协议 cells are empty pills, the 最后心跳 column 
shows `-` for every row, and the health tab prints 心跳状态正常.
   
   ### What Did You Expect to See?
   
   A value that was not reported must not be presented as one. The protocol 
cell should show that the protocol is unknown rather than an empty tag, and the 
health card should say that no heartbeat time was reported instead of grading 
the client healthy — matching what the AI tool contract already does for the 
same field, where `rmq.group.detail`'s `protocol` enum includes `UNKNOWN`.
   
   ### What Did You See Instead?
   
   The protocol column renders an empty tag for every instance, and the health 
card asserts 心跳状态正常 for a group whose heartbeat time was never sent.
   
   ### Additional Context
   
   Code at `1ef5d860`: `ConsumerConnections.java:33-43`, 
`ConsumerInstanceVO.java:33-40`, `consumer.tsx:1177,1181-1184,2008-2013`, 
`consumerGroupDiagnostics.ts:135-138,324,431-432`, `constants/theme.ts:66-69`, 
`metadata.ts:115-122`.
   
   The 最后心跳 column is deliberately left as it is: `formatDateTime` renders `-` 
for a missing value, which is this application's marker for "no value" and does 
not assert one.
   
   Corresponding pull request: #4951 (`fix(consumer): stop grading a group 
healthy without a client heartbeat`), which renders the unavailable label in 
the protocol cell, adds the not-reported state to the card, and makes the two 
fields optional in the client type so the next consumer of either has to handle 
their absence.
   
   ### Are You Willing to Submit a Pull Request?
   
   - [x] Yes, I am willing to submit a pull request.
   


-- 
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]

Reply via email to