lizhimins commented on PR #4581:
URL: 
https://github.com/apache/rocketmq-dashboard/pull/4581#issuecomment-5761158708

   Thanks — the underlying problem you identified is real, and the two tests 
you added are both mutation-sensitive.
   
   To restate it so we are clear about what is being decided: `UpdateTopicDTO` 
already carries `writeQueues`/`readQueues` as `Integer` with `@PositiveOrZero` 
and only copies them onto the VO when non-null, but `TopicVO` declares them as 
primitive `int`, so "not submitted" arrives at 
`RocketMQAdminClientImpl.updateTopic` as `0` and the `> 0` test reads it as 
"not provided". An explicit drain-to-zero is therefore dropped.
   
   **We are not taking this approach.** Our position is that the update path 
should use the value the caller passed, as passed. This PR goes the other way: 
it makes the VO nullable and then resolves the count through a three-way 
substitution at every consumer — request value, else the stored `RmqTopic` 
value, else a hardcoded 8. Each of those resolution points is a place where the 
wrong number can be written to the broker, and the PR widens the number of 
consumers that have to get the resolution right rather than removing the 
ambiguity at the boundary. Concretely:
   
   1. **The nullable VO leaks into contracts that were not updated.** Three AI 
output records still take a primitive `int` and are constructed straight from 
the VO: `TopicOutput`, `TopicListItem` and `TopicDetailOutput`. We traced every 
caller and none can pass null today — but this PR is what makes null possible, 
and the guards are caller discipline rather than construction. That is exactly 
the "someone changes the wrong one later" failure mode.
   2. **It changes the public REST response shape, which the description does 
not say.** `AliyunInstanceProvider.createTopic` and `updateTopic` return the 
caller's `TopicVO` verbatim and never populate the queue counts, and 
`TencentInstanceProvider.updateTopic` only writes them back when a queue number 
was requested. So a remark-only `POST /api/topics/update` against a cloud 
instance would start serializing `"writeQueues": null` where trunk returns `0`. 
`web/src/api/metadata.ts` declares `writeQueues: number` as non-nullable and 
`topic.tsx` renders it directly. Note also that the topic form hides the queue 
inputs entirely for cloud instances, so the UI never sends them there.
   3. **The second commit carries an undisclosed behaviour change.** Flipping 
`existing.getWriteQueueNums() > 0` to `>= 0` means a *stored* 0 now survives a 
partial update instead of being reset to 8. That is an independent fix from the 
request-side one, but the description presents it as "existing behaviour".
   
   The drain-to-zero case is also only reachable from non-UI callers: the topic 
edit form declares the counts `required` with `min={1}`, so Studio itself 
cannot submit 0.
   
   **What would make a future attempt welcome.** Keep `TopicVO` non-nullable 
and settle the ambiguity at the API boundary instead, so the value that reaches 
the broker is the value the caller sent: make the counts required on the update 
DTO (they are already `Integer` + `@PositiveOrZero`) and confine the default-8 
substitution to `createTopic`, where it belongs. If you would rather keep 
partial updates, then the omitted case needs a representation that does not 
depend on every downstream consumer remembering to null-check.
   
   One mechanical note either way: #4538 has landed, so 
`RocketMQAdminClientImpl.updateTopic` now throws 404 for a missing topic just 
above the queue-count block. This branch needs a rebase onto `rocketmq-studio`, 
and the `existing != null &&` guards become redundant once you do.
   


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