chstercc commented on issue #6643:
URL: 
https://github.com/apache/rocketmq-dashboard/issues/6643#issuecomment-6250094918

   Thanks for the detailed write-up; the 5.5 broker semantics you verified 
match what the console code assumes. Two corrections to the current-state 
analysis at `c34535db`, then answers to the four questions.
   
   ### Current state
   
   1. **A LITE parent can already be created from the generic Topic dialog.** 
The type picker includes `{ value: 'LITE' }` 
(`web/src/pages/instance/topic.tsx:127`, card at `:141`; hidden only for cloud 
instances at `:1554`), and the Apache create path maps the type to 
`+message.type=LITE` (`RocketMQAdminClientImpl.java:305-317`, `applyTopicType` 
at `:479-486`). What is missing is the TTL: `CreateTopicDTO`/`TopicVO` carry no 
attribute or TTL field (`CreateTopicDTO.java:26-39`, `TopicVO.java:26-40`), so 
a parent created there has no `lite.topic.expiration` until `extendTTL` 
rewrites it (`LiteTopicService.java:62-81`).
   
   2. **The 5.5 client exposes first-class setters for both fields.** 
`TopicConfig#setLiteTopicExpiration(int)` and 
`SubscriptionGroupConfig#setLiteBindTopic(String)` exist in `rocketmq-common` / 
`rocketmq-remoting` 5.5.0. Slice 3 does not need a raw attribute map; it can 
call `setLiteBindTopic(parent)`.
   
   ### Answers
   
   **1. Create scope: parent only; group binding stays a separate operation.**
   
   - Parent and group are separate ownership rows (`Kind.TOPIC` / `Kind.GROUP`, 
`ResourceOwnershipGuard.java:73-87`), reserved independently; there is no 
cross-resource transaction.
   - Deleting a parent cascades child LMQs at the broker but does **not** 
delete a bound consumer group, so a combined create would leave a dangling 
group on delete.
   - Recommended: create the parent in slice 1; add the optional group binding 
as slice 3. If the UI wants a single onboarding dialog, make it two explicit 
steps and report each outcome; do not claim atomicity.
   
   **2. TTL: default 1440 minutes, range 1..43200; use minutes on the new API.**
   
   - `MAX_LITE_TTL_MINUTES` already mirrors the 30-day cap 
(`RocketMQLiteTopicProvider.java:100-101`).
   - The broker attribute is in minutes. Taking `ttlMinutes` for creation 
avoids the current `extendTTL` ms-to-minute rounding 
(`RocketMQLiteTopicProvider.java:381`), which can silently change the requested 
value. Keep `extendTTL` as-is for compatibility; note the unit difference in 
the API docs.
   - Do not expose `<= 0` ("never expire") in the create dialog; an explicitly 
never-expiring parent defeats the lifecycle. If needed, make it a separate 
confirmation.
   
   **3. Generic Topic page: keep `message.type` immutable, do not expose 
attributes; add the TTL field only to create when `LITE` is selected.**
   
   - Type immutability is already enforced 
(`MetadataService.guardImmutableType`, `MetadataService.java:192-202`).
   - TTL changes should stay on the LiteTopic page (`extendTTL`) so there is 
one owner for the policy. The generic update path currently preserves broker 
attributes: it preflights each master, sends an empty attribute delta and 
re-applies only `message.type` (`RocketMQAdminClientImpl.java:400-414`), so a 
queue/perm edit does not wipe `lite.topic.expiration`. A regression test should 
pin this before adding the create-time TTL.
   - Recommendation: generic create accepts `liteTtlMinutes` only when 
`type=LITE`; generic update never edits it.
   
   **4. Per-child deletion: do not propose a core admin RPC now.**
   
   - 5.5 has no per-child create/delete RPC and the sweeper is the intended 
lifecycle. A manual delete would have to define behavior for active consumers, 
offsets and sessions, and there is no current requirement. TTL-only (or parent 
delete, which cascades) is sufficient. Keep it out of scope.
   
   ### Proposed slices
   
   **Slice 1 — create a Lite parent with TTL (one PR, backend + frontend).**
   
   - Reuse the existing topic create path instead of adding a parallel write 
path:
     - `CreateTopicDTO` / `TopicVO`: add optional `liteTtlMinutes`; validate 
1..43200, only with `type=LITE`, and reject `$` in the name 
(`LiteUtil.SEPARATOR`, `LITE_TOPIC_PREFIX = "%LMQ%$"`).
     - `RocketMQAdminClientImpl.createTopic`: when `LITE`, set 
`topicConfig.setTopicMessageType(LITE)` (or reuse `applyTopicType`) and 
`setLiteTopicExpiration(minutes)`.
     - Keep `MetadataService.saveTopic` for 
ownership/reservation/`CREATE_TOPIC` audit and the Apache-only gate 
(`MetadataService.java:161-176`); no new write path.
     - Frontend: show a TTL input in the topic create dialog when `LITE`; add a 
"Create Lite parent" button on the LiteTopic page that opens the same dialog 
with `LITE` preselected.
   - If maintainers prefer `POST /api/liteTopic` for the page, make it a thin 
delegate to `MetadataService.createTopic`; do not duplicate ownership/audit.
   - Tests: DTO bounds, provider config attributes, controller payload, zh/en 
strings, and a test that a non-LITE create rejects `liteTtlMinutes`.
   
   **Slice 2 — delete with blast radius (one PR).**
   
   - Reuse `POST /api/topics/delete` (`MetadataService.deleteTopic`, 
`MetadataService.java:204-214`); the broker cascade already cleans child LMQs. 
A dedicated `POST /api/liteTopic/delete` can delegate if the page wants a 
separate route.
   - The LiteTopic page reads `topicCount` / `consumerCount` from 
`LiteTopicItemVO` (`LiteTopicItemVO.java:30-31`) and shows "N child lite topics 
will be permanently deleted"; also state that bound consumer groups are **not** 
deleted and must be cleaned separately.
   - Tests: confirmation content and count source, delete call; the broker-side 
cascade is covered by the existing topic delete tests.
   
   **Slice 3 — bind a consumer group (one PR).**
   
   - Add optional `liteBindTopic` to `CreateConsumerGroupDTO` / 
`ConsumerGroupVO`, and set it in `RocketMQAdminClientImpl.createConsumerGroup` 
via `SubscriptionGroupConfig#setLiteBindTopic(parent)`.
   - Validate the parent exists, is LITE, and is owned by the same instance.
   - UX: an optional field in the group create dialog, or a second optional 
step in the LiteTopic create flow with explicit partial-failure reporting.
   - Tests: the provider sets the field; a non-LITE/unowned parent is rejected.
   
   ### Cross-cutting
   
   - All writes are Apache-only (`requireSupportedProvider`) and gated by 
`isSupported`, matching `extendTTL`.
   - Reuse the existing audit operations (`CREATE_TOPIC`, `DELETE_TOPIC`, 
`CREATE_GROUP`) to keep the audit dashboards stable; add new operations only if 
the taxonomy requires it.
   - Update `docs/api-spec.md` for `liteTtlMinutes` (5.3) and `liteBindTopic` 
(6.5), and document the LiteTopic page's create/delete flows.
   - Add zh/en strings for every new label and confirmation.
   
   ### Decisions requested
   
   1. `ttlMinutes` on create (recommended) vs `ttlMillis` for consistency with 
`extendTTL`.
   2. Reuse the topic create dialog/endpoint (recommended) vs a dedicated 
LiteTopic write path.
   3. Optional group-binding step in the same dialog (recommended) vs a 
separate group-page flow.
   


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