Skip to content

[Bug] Incorrect queue permissions in gRPC QueryRouteResponse when read/write queue counts differ #10529

Description

@Kris20030907

Before Creating the Bug Report

  • I found a bug, not just asking a question, which should be created in GitHub Discussions.

  • I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.

  • I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.

Runtime platform environment

Not platform-specific.

RocketMQ version

develop

JDK Version

JDK17

Describe the Bug

When the gRPC proxy builds QueryRouteResponse, the permission of each MessageQueue can be incorrect if readQueueNums and writeQueueNums are different.

The problem is in RouteActivity#genMessageQueueFromQueueData.

QueueData uses queue ids as ranges:

  • readable queues: 0 .. readQueueNums - 1
  • writable queues: 0 .. writeQueueNums - 1

So when a topic has both read and write permission, the overlapping queue ids should be marked as READ_WRITE.

However, the current implementation calculates the number of read-only, write-only, and read-write queues first, then appends them in groups while increasing the queue id. This preserves the count of each permission type, but may assign the permission to the wrong queue id.

For example, with:

  • readQueueNums = 4
  • writeQueueNums = 8
  • perm = PERM_READ | PERM_WRITE

The expected result is:

  • queue ids 0..3: READ_WRITE
  • queue ids 4..7: WRITE

But the current implementation returns:

  • queue ids 0..3: WRITE
  • queue ids 4..7: READ_WRITE

So the route response exposes incorrect per-queue permissions to gRPC clients.

Steps to Reproduce

  1. Create a QueueData with:
    • readQueueNums = 4
    • writeQueueNums = 8
    • perm = PERM_READ | PERM_WRITE
  2. Call RouteActivity#genMessageQueueFromQueueData.
  3. Check the generated MessageQueue list in the returned route response.

A similar issue can also be reproduced with:

  • readQueueNums = 8
  • writeQueueNums = 4
  • perm = PERM_READ | PERM_WRITE

What Did You Expect to See?

The permission should be calculated by queue id.

For readQueueNums = 4, writeQueueNums = 8, and PERM_READ | PERM_WRITE:

  • queue id 0: READ_WRITE
  • queue id 1: READ_WRITE
  • queue id 2: READ_WRITE
  • queue id 3: READ_WRITE
  • queue id 4: WRITE
  • queue id 5: WRITE
  • queue id 6: WRITE
  • queue id 7: WRITE

In general:

  • id < readQueueNums means the queue is readable
  • id < writeQueueNums means the queue is writable
  • if both conditions are true, the permission should be READ_WRITE

What Did You See Instead?

The current implementation returns the correct number of queues for each permission type, but assigns those permissions to the wrong queue ids.

For readQueueNums = 4, writeQueueNums = 8, and PERM_READ | PERM_WRITE, it returns:

  • queue id 0: WRITE
  • queue id 1: WRITE
  • queue id 2: WRITE
  • queue id 3: WRITE
  • queue id 4: READ_WRITE
  • queue id 5: READ_WRITE
  • queue id 6: READ_WRITE
  • queue id 7: READ_WRITE

This is inconsistent with how RocketMQ builds readable and writable queues from QueueData.

Additional Context

The issue is not about the total number of queues. The total count is correct.

The problem is that MessageQueue.id is part of the queue identity, so permission needs to match the actual queue id. Grouping permissions first and assigning ids afterwards can produce a route response where clients see a readable/writable status that belongs to a different queue id.

The internal route selection logic also builds read/write queues by iterating queue ids from 0 to readQueueNums - 1 or writeQueueNums - 1, which confirms that the permission should be derived per queue id rather than by grouped counts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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