)]}'
{
  "log": [
    {
      "commit": "98822d9fae4e1f298c4d723b6f8f54480f19297e",
      "tree": "7b41876792d90dadab67246e866f32f902f7107b",
      "parents": [
        "3c0849e992771986b5690f6a169d4afdcef0b2f7"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Wed Nov 04 11:00:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 04 11:00:26 2026 +0800"
      },
      "message": "fix(rust): align log messages and levels with the Java client (#1472)\n\nThe Rust client logged at INFO on every settings push and every received\nbatch, used its own wording, and refreshed settings on a schedule unrelated\nto Java\u0027s, so its logs were both noisier and harder to correlate with the\nJava client\u0027s (#1471).\n\nAlign the messages, levels and fields (clientId, endpoints, mq,\nconsumerGroup, ...) with the Java client across telemetry, client lifecycle,\nheartbeat, routes, sessions, producer, simple consumer, push consumer,\nprocess queue and lite consumers, and adopt Java\u0027s schedules for the\nsettings sync (1s delay / 5 min period) and the statistics log (1s / 60s).\nThree periodic logs Java keeps at INFO stay at DEBUG here, because at the\ndefault level they would make the Rust client log more than before: a\nsuccessful heartbeat, a route fetch whose route did not change, and the\nstart of a refresh round.\n\nThe 30s timer used to both push settings and rebuild broken streams. Java\nneeds no rebuild because ClientSessionImpl#renewRequestObserver retries every\nsecond without a limit, while the reconnect loop here gives up after 8\nattempts, so the timer is split: the settings sync moves to Java\u0027s schedule,\nand a new SessionManager::recover_broken_streams runs every 30s and only\ntouches sessions whose stream is gone. The route refresh keeps the 10s of\n#1404, which bounds how long a client keeps sending to a stale endpoint\nafter a failover.\n\nAlso fix three defects found while aligning:\n\n- Client::shutdown_ref returned early when the termination notice failed, so\n  the scheduler and the telemetry sessions were never released. It now logs\n  the failure and still releases everything, like ClientImpl#shutDown.\n- Producer, SimpleConsumer and PushConsumer did not shut the client down when\n  a start failed after Client::start, leaving the scheduler and the sessions\n  running after start() had returned an error. A ClientIsNotRunning from the\n  cleanup is tolerated, any other cleanup failure is logged.\n- LiteSimpleConsumer\u0027s telemetry loop caught a closed channel in a debug\n  catch-all arm, so recv() returned None immediately and spun the task.\n\nLeft on purpose: the ack / nack / DLQ logs carry no requestId because the\nRust session does not surface it; Producer::send has no local retry, so a\nfailed send is logged as maxAttempts\u003d1; the queue statistics report no\ncachedMessageCount / cachedMessageBytes because there is no message cache;\nand assignment scanning before the first settings arrive is a DEBUG skip\nwhere Java waits for them during startup. The assignment scan (30s vs Java\u0027s\n5s) and the idle session cleanup (30s vs Java\u0027s 1 min) keep their periods for\nnow and only have their logs aligned.\n\nAdd util::test_log::capture(), a test-only tracing subscriber that records\nevents, so tests can assert on the level and the content of what the client\nlogs."
    },
    {
      "commit": "3c0849e992771986b5690f6a169d4afdcef0b2f7",
      "tree": "2be4a3fd5655a7749c4d42c46b08c2662465792d",
      "parents": [
        "f9cb7f424bdb62b0d2b54d60864e46a08b613636"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Mon Nov 02 17:38:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 02 17:38:58 2026 +0800"
      },
      "message": "fix(go): robust consumer settlement, reception backoff, and shutdown under failures (#1473)\n\n* fix(go): give up dead settlement retries and stop swallowing settlement errors\n\n- move the INVALID_RECEIPT_HANDLE abandon branch of\n  defaultProcessQueue.changeInvisibleDuration before the generic err\n  handling: changeInvisibleDuration0 converts a non-OK status into an\n  error, so the branch was unreachable and an expired receipt handle\n  was renewed once a second forever\n- cap the ack / change invisible duration / forward-to-DLQ retry chains\n  at 3 attempts and stop scheduling retries once the process queue was\n  dropped or the consumer is no longer running; the DLQ chain also\n  forgives INVALID_RECEIPT_HANDLE (it never gave up on any code)\n- restore the Java semantics of the receiving back-off delays: the\n  default is RECEIVING_FAILURE_BACKOFF_DELAY (1s) and only flow control\n  retries after the short RECEIVING_FLOW_CONTROL_BACKOFF_DELAY (20ms)\n- SimpleConsumer.ChangeInvisibleDuration: only adopt the receipt handle\n  from a successful response; a failed request used to wipe the handle\n  to the empty string and make every following call fail permanently\n- SimpleConsumer.Ack: return the server status instead of nil on a\n  non-OK response\n- fix mis-copied \"message acknowledgement\" log text in the renewal and\n  DLQ failure paths and replace %w verbs that zap does not expand\n\n* fix(go): stop receive hammering, throttle reception failure logs, and bound GracefulStop under proxy restart\n\n- Remove the 20ms TOO_MANY_REQUESTS reception backoff: real proxy flow\n  control means the executor queue is saturated, and retrying at ~50\n  polls per second only hammers it harder; every reception failure now\n  waits the full 1s backoff.\n- Throttle reception-failure logging: the first failure logs ERROR, then\n  one WARN per 30 consecutive failures carrying the cumulative count,\n  the rest only DEBUG; the counter resets on success and on\n  MESSAGE_NOT_FOUND, so a sustained outage no longer emits one ERROR per\n  second per queue.\n- GracefulStop now cancels in-flight long polling receive requests via\n  a consumer-scoped receive context, so shutdown no longer waits out\n  requestTimeout + longPollingTimeout for a poll hanging against a\n  restarting proxy.\n- notifyClientTermination runs concurrently across route targets, so the\n  shutdown no longer stretches by a full request timeout per target.\n- Replace remaining Java-style {} placeholders with fmt verbs in\n  process_queue.go and push_consumer.go logs.\n- Add tests: ack settlement retries are capped and complete; GracefulStop\n  cancels an in-flight receive request instead of waiting it out.\n\n* fix(go): keep assignments when the assignment scan fails and fix clientId verb\n\nA failed queryAssignments does not mean the server has no assignments:\nsyncing the nil result dropped every working process queue and stalled\nconsumption for the whole outage. The scan now keeps the current\nassignments until the next successful one, so the reception chain keeps\nrunning (and its failure logging stays throttled) while the proxy or\nbroker is down.\n\nAlso fix clientId\u003d%d printing %!d(string\u003d...) in the empty-assignments\nwarning, found during the local cluster test."
    },
    {
      "commit": "f9cb7f424bdb62b0d2b54d60864e46a08b613636",
      "tree": "eb465a5c697b6cdd0f834d4288ed3aa90c66c916",
      "parents": [
        "e90ece7a320142c125242c2fdfed305c68cf4c12"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Tue Oct 27 14:02:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 14:02:35 2026 +0800"
      },
      "message": "fix(rust): relax dependency upper-bound pins so downstream can use newer versions (#1468)\n\nExact and upper-bound pins in [dependencies] propagate to every downstream\nproject and make rocketmq unusable alongside newer tokio, tokio-util, time,\nindexmap or hyper-util. Keep only lower bounds and enforce the MSRV through\nthe MSRV-aware resolver (resolver.incompatible-rust-versions \u003d fallback) when\nCI generates Cargo.lock, which does not affect downstream resolution."
    },
    {
      "commit": "e90ece7a320142c125242c2fdfed305c68cf4c12",
      "tree": "35230464823465f5abed4eb2e77c4abfdd210ec5",
      "parents": [
        "50a5df5a3f8779cebcc1d13672ca68455bde36c2"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Sun Oct 25 11:31:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 25 11:31:16 2026 +0800"
      },
      "message": "fix(ci): repair the Rust Coverage workflow startup failure (#1444)\n\nThe Rust Coverage workflow has not started a single run since 2026-03-31.\nThe 188 runs since the last success all end in conclusion\u003dstartup_failure\nwith zero jobs created; that last success was run 23637248643 on\n2026-03-27T08:13:19Z.\n\nThe workflow file is not the cause. Its blob is 3a0c3e13 both at the last\nsuccessful run (e97a2cdb) and on master today, unchanged byte for byte.\n\nTwo of the three actions it references are provably healthy on the very\ncommits where Rust Coverage failed:\n\n  actions/checkout@v2        used by build-result in build.yml,\n                             success on 50a5df5a\n  codecov/codecov-action@v4  used by the Java, Golang and C++ coverage\n                             workflows, all three success on 50a5df5a\n\nThat leaves dtolnay/rust-toolchain@stable, which nothing else in this\nrepository references and which is the only third-party action here pinned to\na mutable branch rather than a tag. The action looks healthy from the\noutside: the repository is not archived, refs/heads/stable resolves, and\naction.yml is intact. The one commit that landed on stable between the last\nsuccess and the first failure (3c5f7ea2, 2026-03-27T15:55:47Z) touched only\nscripts/update-revs.sh. The org Actions policy cannot be read without admin\n(GET /repos/apache/rocketmq-clients/actions/permissions returns 403), so the\nprecise trigger is not confirmable from here and this attribution is by\nelimination.\n\nReplace it with the rustup invocation that all four jobs in rust_build.yml\nalready use and that is green on master. Behaviour is unchanged: neither path\nships llvm-tools-preview, and cargo-llvm-cov installs that component on demand\neither way.\n\nThis change cannot validate itself on the PR. The workflow triggers only on\npaths under rust/**, which .github/workflows/rust_coverage.yaml does not\nmatch, so Rust Coverage does not run here; it runs on the push to master after\nmerge.\n\nWhat was verified locally instead, on 3549cb57 with rustc 1.99.1, running the\nexact commands from the workflow:\n\n    rustup component add llvm-tools-preview    ok\n    cargo llvm-cov --all-features --workspace\n        --ignore-filename-regex pb/ --codecov\n        --output-path codecov.json             exit 0, 162 passed, 0 failed\n    codecov.json                               113676 bytes, valid payload\n\nThis matters because the workflow last ran before seven months of changes to\nrust/, including #1404, #1381 and the whole #1412 batch, so a run that merely\nmanages to start would not by itself imply a green job."
    },
    {
      "commit": "50a5df5a3f8779cebcc1d13672ca68455bde36c2",
      "tree": "62cd3249674e9e8ff94df02273f254af3d0efb61",
      "parents": [
        "3549cb5736ad674f307ccf6fb12046971f6b8d76"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Sat Oct 24 19:14:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 19:14:22 2026 +0800"
      },
      "message": "[ISSUE #1412] [CI] Restore rust-build as a gating check for build-result (#1443)\n\nReverts #1442, whose restore condition is now met. `master` carries the\ndependency pins from #1404 (`tokio \u003c 1.47`, `hyper-util \u003c 0.1.16`,\n`powerfmt \u003c 0.2.1`) and the `for_kv_map` fix, so the Rust baseline that\nmade #1442 necessary is green again: `rust-build / MSRV 1.74.0 check`,\n`rust-build / Clippy` and the Ubuntu/macOS/Windows matrix all pass.\n\nVerified locally on 3549cb57 with rustc 1.99.1:\n\n    cargo test --all-features                    164 passed, 0 failed\n    cargo clippy --all-features -- -D warnings   exit 0, no errors\n    cargo fmt --check                            clean\n\nByte-exact revert: build.yml returns to blob 1dacbf97, its content before\n#1442, so `rust-build` is back in `needs` and in the aggregation script\nand nothing else changes.\n\nWhile #1442 was in effect a Rust change could merge with its compilation\nand unit tests failing, because `build` declares `needs: [fmt, msrv]` and\nan msrv failure skipped the whole matrix. Restoring the gate closes that\nwindow."
    },
    {
      "commit": "3549cb5736ad674f307ccf6fb12046971f6b8d76",
      "tree": "7f09d0e99a7d9a102ab294e35b0e89ef3a8a9305",
      "parents": [
        "086c38a3e1fd27777f48333f8a397bbd5c5d3247"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 18:55:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 18:55:39 2026 +0800"
      },
      "message": "[ISSUE #1440] [Rust] Select readable master queues for SimpleConsumer and start at a random index (#1441)"
    },
    {
      "commit": "086c38a3e1fd27777f48333f8a397bbd5c5d3247",
      "tree": "2b63644337adf1f9ffbd95f5232cdb4aa2df18fd",
      "parents": [
        "c25b9a2f7688777fc4fc1a7844437138a14ef63a"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 18:54:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 18:54:38 2026 +0800"
      },
      "message": "[ISSUE #1438] [Rust] Return an empty receipt handle instead of panicking when a MessageView has none (#1439)"
    },
    {
      "commit": "c25b9a2f7688777fc4fc1a7844437138a14ef63a",
      "tree": "9d7774e7d43b9e2603ad5880bfc2b6d384dbf4c9",
      "parents": [
        "2f4ae8c873417911d94a37fcd3693cd182b4c650"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 18:49:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 18:49:28 2026 +0800"
      },
      "message": "[ISSUE #1432] [Rust] Roll back a failed start and check state in SimpleConsumer operations (#1433)"
    },
    {
      "commit": "2f4ae8c873417911d94a37fcd3693cd182b4c650",
      "tree": "de1b626dda0aa64a6d3b7071068473a58ace2e18",
      "parents": [
        "222e078469323cdf0bd3434f353b1c91263c883c"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 18:38:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 18:38:38 2026 +0800"
      },
      "message": "[ISSUE #1430] [Rust] Refresh MessageView receipt handle after change_invisible_duration (#1431)"
    },
    {
      "commit": "222e078469323cdf0bd3434f353b1c91263c883c",
      "tree": "5b556c9bbe681fcea0198607ce952539029544d1",
      "parents": [
        "f9869e83fa361cfcf05d6b99ba449b27aee248b9"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 14:38:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 14:38:32 2026 +0800"
      },
      "message": "[ISSUE #1426] [Rust] Validate SimpleConsumer receive arguments instead of panicking (#1427)\n\nReject a non-positive batch size before any RPC, as Java SimpleConsumerImpl#receive0 does,\nand return an error instead of panicking when the invisible duration can not be converted\nto protobuf in receive_with and change_invisible_duration."
    },
    {
      "commit": "f9869e83fa361cfcf05d6b99ba449b27aee248b9",
      "tree": "f1ac87576520e0b072bdc0e56d13781504732afb",
      "parents": [
        "9e74b6bd8eddd9d4cca3b19783bcdbf968da02d5"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 14:37:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 14:37:33 2026 +0800"
      },
      "message": "[ISSUE #1434] [Rust] Set suspend when LiteSimpleConsumer changes the invisible duration of a lite message (#1435)"
    },
    {
      "commit": "9e74b6bd8eddd9d4cca3b19783bcdbf968da02d5",
      "tree": "09ceeab81e1df83180b0e989ac0f5b242d079f86",
      "parents": [
        "e0cd6e05bf93a9c1ff16685dde0df5b00637ffee"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 14:36:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 14:36:34 2026 +0800"
      },
      "message": "[ISSUE #1408] [Rust] Apply server lite settings in LitePushConsumer (#1409)\n\nPushConsumer::start_with_telemetry ignored the channel passed by\nLitePushConsumer, so Settings and NotifyUnsubscribeLiteCommand never\nreached the LiteSubscriptionManager and the lite subscription quota stayed\nat 0, which was treated as unlimited.\n\nAlign with the Java client:\n- forward every telemetry command to the caller\u0027s channel after the push\n  consumer handled it (LitePushConsumerImpl#onSettingsCommand calls\n  super.onSettingsCommand before liteSubscriptionManager.sync)\n- wait in LitePushConsumer::start for the first Settings, bounded by\n  SETTINGS_INITIALIZATION_TIMEOUT (3s) + request timeout, and fail the\n  startup on timeout (ClientImpl#startUp / ClientSessionImpl#settingsInitFuture)\n- start the LiteSubscriptionManager only after that\n  (LitePushConsumerImpl#startUp)\n- drop the \"quota 0 means unlimited\" special case\n  (LiteSubscriptionManager#checkLiteSubscriptionQuota)\n\nAlso compile lite_subscription_manager in unit tests so its tests run."
    },
    {
      "commit": "e0cd6e05bf93a9c1ff16685dde0df5b00637ffee",
      "tree": "1a45f86c3e0c7fc823861beb0d0942544263b99b",
      "parents": [
        "abd0b90490e4154c57a8d48fddae32fd854ccd88"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 06:57:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 06:57:16 2026 +0800"
      },
      "message": "[ISSUE #1422] [Rust] Stop receiving once shutdown starts and shut queue actors down concurrently (#1423)\n\nWorkers checked the shutdown token and the 1 ms ticker in an unbiased select!, so a worker often issued another long polling request after shutdown started. Check the token first, like ProcessQueueImpl checks consumer.isRunning() before receiving.\n\nQueue actors were shut down one by one, each waiting for its in-flight long polling request, so the waits added up across queues. Shut them down concurrently, so shutdown takes about one long polling timeout in total, like PushConsumerImpl#waitingReceiveRequestFinished.\n\nDepends on #1404 and #1381."
    },
    {
      "commit": "abd0b90490e4154c57a8d48fddae32fd854ccd88",
      "tree": "bd159ffa432fff97033f7cbd85fe219c971bd10d",
      "parents": [
        "d7408c74946aefbb890144f15005613126cc7de7"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Sat Oct 24 06:56:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 06:56:18 2026 +0800"
      },
      "message": "[ISSUE #1424] [Rust] Apply server long polling timeout to the receive deadline in PushConsumer (#1425)\n\nPushConsumer::apply_settings wrote the server-pushed long_polling_timeout into PushConsumerOption, which the request carries, but not into the client shared value that Session::receive_deadline is based on. The request then asked the server to hold it for the server value while the client waited for the configured one, so a request the server did not answer in time ran until the configured deadline.\n\nWrite the shared value too, as SimpleConsumer does, so the deadline is server long_polling_timeout + timeout like ConsumerImpl#receiveMessage of the Java client.\n\nDepends on #1404."
    },
    {
      "commit": "d7408c74946aefbb890144f15005613126cc7de7",
      "tree": "56f9bf43b9323143e562ed8553cc0844091d4a6f",
      "parents": [
        "d0f3cd13a1b815a7da6b1cfd02ad6bb4701c6af7"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Sat Oct 24 06:05:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 06:05:28 2026 +0800"
      },
      "message": "[rust] Add LiteSimpleConsumer with tests and example (#1381)\n\n* [rust] Add LiteSimpleConsumer with tests and example\n\nImplement the lite-topic variant of SimpleConsumer for the Rust client,\nmirroring the Java reference implementation.\n\nImplementation\n- LiteSimpleConsumer: a consumer bound to a single parent (bind) topic that\n  dynamically (un)subscribes lite topics through SyncLiteSubscription and pulls\n  messages explicitly with receive()/ack()/change_invisible_duration(). It\n  wraps a SimpleConsumer plus a lightweight cloned client shared with\n  LiteSubscriptionManager, and forwards NotifyUnsubscribeLiteCommand / Settings\n  telemetry commands to the manager.\n- ClientType: add LiteSimpleConsumer (\u003d6) and a clone_for_lite_simple_consumer()\n  variant of the lite client clone.\n- build_lite_simple_consumer_settings(): simple consumer settings carrying\n  client type LITE_SIMPLE_CONSUMER and the bind topic with a SUB_ALL filter.\n- prune_lite_route(): keep only the first readable master queue of a route, as\n  LiteSimpleConsumerImpl#updateSubscriptionLoadBalancer does in Java.\n- SimpleConsumer: add new_with_client(), start_with_telemetry(),\n  check_started(), shutdown_ref() and receive_lite() so the lite consumer can\n  reuse the simple consumer plumbing.\n\nDefect fix: missing liteTopic in ack\n- AckMessageEntry now exposes lite_topic() and the ack / change invisible\n  duration requests carry it. Without it the proxy cannot resolve the LMQ\n  receipt handle and answers 50001 INTERNAL_SERVER_ERROR.\n\nDefect fix: unsubscribeLite always failed\n- LiteSubscriptionManager::unsubscribe_lite() validated the running state on the\n  lightweight client clone, whose shutdown_tx is intentionally None, so it\n  always answered \"client is not started\". The state check now belongs to the\n  public API of the owning consumer, like subscribeLite already did.\n\nTests\n- tests/lite_simple_consumer_test.rs: 4 offline tests (builder validation,\n  accessors, life cycle checks).\n- src/util.rs: unit tests for the lite settings, the route pruning and the\n  liteTopic carried in the ack entry.\n- tests/lite_simple_consumer_integration_test.rs: 2 real-cluster tests guarded\n  by ROCKETMQ_RUST_LITE_ENDPOINTS. Verified against a local RocketMQ 5.5.1\n  cluster (broker enableLmq/enableMultiDispatch, proxy in CLUSTER mode,\n  message.type\u003dLITE parent topic, group with +lite.bind.topic): 2/2 passed.\n- Offline suites: cargo test --lib 93 passed, lite_simple_consumer_test 4\n  passed; cargo fmt --check and cargo clippy --all-features -- -D warnings\n  clean.\n\nExample\n- examples/lite_simple_consumer.rs plus a \"Lite Topic\" section in README.md.\n  The example was also run against the local cluster end to end: subscribe,\n  receive 3 lite messages, ack, unsubscribe, shutdown.\n\n* fix(rust): harden LiteSimpleConsumer lifecycle and settings handling\n\n- Stop the LiteSubscriptionManager periodic-sync scheduler and await its\n  join handle before closing client sessions. The scheduler retained an\n  Arc\u003cClient\u003e and could recreate a telemetry session and re-send the\n  CompleteAdd command after shutdown. A unit test keeps the runtime alive\n  for more than one sync interval after stopping and asserts no further\n  RPCs are issued.\n- Check the running state before ack() and change_invisible_duration().\n  Both previously panicked at unwrap() inside get_session_with_endpoints()\n  when called after shutdown(\u0026mut self); they now return\n  ErrorKind::ClientIsNotRunning. Covered by integration tests.\n- Wait for the server\u0027s initial Settings (bounded, 3s) before start()\n  returns, so an immediate first subscribe() validates against the\n  server-provided max_lite_topic_size instead of the local default 64.\n  Falls back to local defaults with a warning on timeout. Covered by an\n  integration test that subscribes immediately after start."
    },
    {
      "commit": "d0f3cd13a1b815a7da6b1cfd02ad6bb4701c6af7",
      "tree": "bbe8e5b91e65d64304d6206363e6bea24373b10e",
      "parents": [
        "9f77cf18a8c049698d97f3a1268626debdf3f549"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Sat Oct 24 04:18:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 04:18:35 2026 +0800"
      },
      "message": "Fix/rust telemetry session defects (#1404)\n\n* fix(rust): stop rebuilding telemetry streams on shadow sessions and keep the session map bounded\n\nThe telemetry stream was rebuilt on throw-away shadow sessions during the periodic\nsettings sync. Because a shadow session is dropped as soon as the sync cycle ends, the\nrebuilt stream was dropped with it: the registered session kept its dead handle, so every\ncycle produced a fresh one-off stream (a few milliseconds each) instead of restoring the\nlong-lived connection. Combined with a `session_map` that only ever grew, dead endpoints\naccumulated and failed on every settings report cycle, which showed up as recurring\nerrors and gaps in message consumption.\n\nChanges, following the Java client as the reference:\n\n* Sync settings on the registered sessions (`SessionManager::sync_settings`) so a rebuilt\n  stream actually sticks, mirroring `ClientImpl#syncSettings` which reuses one\n  `ClientSession` instance. Sessions whose stream cannot be restored are evicted, mirroring\n  `ClientImpl#removeClientSession`.\n* Evict a session when its heartbeat RPC fails outright (`evict_session`), so the next\n  access rebuilds it against a fresh connection.\n* Reap dead and idle sessions periodically (`clear_dead_and_idle_sessions`), mirroring\n  `ClientManagerImpl#clearIdleRpcClients`; activity is recorded on every request and\n  shared with shadow sessions through an atomic counter.\n* Enable HTTP/2 keep-alive on the channel (300s interval, 30s timeout, ping while idle),\n  matching `RpcClientImpl`. Without it a rolling deployment left a half-open connection\n  that was never detected.\n* Fix the receive deadline, which was set to exactly `long_polling_timeout` while the\n  server is allowed to hold the response for that long. It now adds the request timeout on\n  top, as documented on `ClientOption::set_long_polling_timeout` and as the Java client\n  does (`awaitDuration.plus(tolerance)`). This is why every poll failed once\n  `long_polling_timeout` was set below a few seconds.\n* Apply the settings pushed by the server (`PushConsumer::apply_settings`), which were\n  previously discarded: long polling timeout, receive batch size and fifo now follow the\n  server, mirroring `PushSubscriptionSettings#sync`.\n\nTests: six new unit tests cover session eviction, idle/dead session reaping, settings sync\nacting on the registered session, eviction of unrecoverable sessions, and the receive\ndeadline contract. `cargo test` (95 lib + 3 integration + doc tests) and\n`cargo clippy --all-features -- -D warnings` are green.\n\n* fix(rust): propagate session errors instead of panicking when the server is unreachable\n\n`send_message`, `recall_message`, `receive_message`, `ack_message` and\n`change_invisible_duration` acquired their session with\n`get_session_with_endpoints(...).await.unwrap()`. Whenever the session could not be\nobtained, the client panicked instead of reporting a failure.\n\nThat is reachable whenever the session is not cached yet and the peer is down, which is\nexactly what happens around a rolling deployment: the first call after the server went\naway took the whole process down, and the caller never got a chance to retry. It also\namplified the consumption gaps seen with the telemetry defects, since a dead endpoint\nturned a transient outage into a crash.\n\nThe session error is now returned to the caller with `?`, so callers can retry or fall\nback. Verified against a local RocketMQ 5.5.1 cluster: with the proxy killed mid-run, the\nproducer now reports the connection failure and recovers on its own once the proxy is back,\ninstead of panicking.\n\n* fix(rust): recover the telemetry stream proactively instead of waiting for periodic syncs\n\nA rolling deployment or failover of the server used to interrupt\nconsumption for 42-70 seconds, because the client only noticed the dead\ntelemetry stream at the next 30s settings sync, kept pushing settings\ninto the fire-and-forget channel of the dying stream, and never\nre-registered when the new server instance answered unary RPCs with\n`cannot find client` / `settings is null`.\n\nMirroring the Java client (`ClientSessionImpl#renewRequestObserver`,\n`ClientImpl#recoverTransport`), this introduces an error-driven\nrecovery path:\n\n* the telemetry stream task notifies the client layer through a\n  stream-closed channel the moment the server closes the stream;\n* the client schedules a reconnect that retries on the registered\n  session every second (deliberately not exponential: a growing\n  back-off keeps missing the moment the new instance becomes ready);\n* `SessionManager#reconnect_session` re-establishes the stream on the\n  registered session, keeping it in the map on failure so that an idle\n  client keeps a driver for recovery; rebuilding the stream also\n  re-registers the client with the new instance;\n* a heartbeat business error now triggers the same reconnect (the\n  heartbeat interval drops from 30s to 10s, aligned with\n  `HEART_BEAT_PERIOD`), and a session is only evicted after 2\n  consecutive transport failures (`HEART_BEAT_FAILURE_THRESHOLD`);\n* the long-polling timeout moved behind a shared handle: settings\n  pushed by the server now take effect on the receive deadline and on\n  the request body of the simple consumer too, instead of being\n  discarded (`SimpleSubscriptionSettings#sync`).\n\nVerified against a live cluster: after `kill -9` of the proxy and a\nrestart, the telemetry stream is re-established within one retry cycle\nof the new instance becoming ready; the remaining ~20s of the measured\ninterruption window is the restarted proxy rebuilding its topic routes\nfrom broker heartbeats, which no client can skip.\n\n* test(rust): tolerate the client recovering faster than the readiness probe\n\nThe client can re-establish its stream before the external driver has\ndetected that the proxy is up and written the marker file, so poll for\nthe marker briefly instead of failing outright.\n\n* fix(rust): bound the reconnect loop, rebuild evicted sessions, fix MSRV pins and keep-alive interval\n\nFollow-up on the proactive reconnect, addressing real-cluster findings:\n\n* A session that was evicted or reaped meanwhile made `reconnect_session`\n  return `Ok(())`, which the reconnect retry loop treated as \"stream\n  re-established\" and exited without any stream. A missing session is now\n  rebuilt from the access endpoints instead (`Ok(bool)` tells the loop\n  whether the stream was really restored). The lock is released before that\n  rebuild: `get_or_create_session` takes the same map lock, and holding it\n  across the rebuild dead-locked the tokio mutex.\n* The retry loop is bounded: the delay doubles from 1s up to a 30s cap and\n  the loop gives up after 8 attempts (~2 minutes), leaving a permanently\n  offline endpoint to the periodic settings sync, the heartbeat and the next\n  business traffic instead of hammering it once a second forever. Every\n  attempt is logged with its index and next delay.\n* The periodic topic-route sync drops from 30s to 10s: when a broker\n  endpoint drifts, the stale-route window (measured 13-29s) is decided by\n  that timer, not by the telemetry reconnect.\n* The HTTP/2 keep-alive interval drops from 300s to 60s: the proxy permits\n  client pings every 30s by default (`ProxyConfig#\n  grpcServerPermitKeepAliveTimeMillis \u003d 30000`, overriding the bare grpc-java\n  5-minute default), so a dead peer is now detected within ~90s instead of\n  ~330s. The Java client does not configure keep-alive at all, so the\n  previous \"aligned with Java\" comment was wrong.\n* MSRV 1.74 broke on fresh dependency resolution (as the CI build does every\n  run): pin `hyper-util \u003c0.1.16` (edition 2024), `powerfmt \u003c0.2.1`\n  (rustc 1.79) and `tokio \u003c1.47` (rustc 1.85).\n\nVerified on a live cluster: after `kill -9` of the proxy the reconnect loop\nlogged attempts 1/8 (1s), 2/8 (2s), 3/8 (4s) ... and re-established the\nstream on attempt 5; the first successful receive happened 79ms after the\nnew instance became ready.\n\n* fix(rust): iterate the session map through values() to satisfy clippy 1.99\n\nThe current stable clippy promotes `for_kv_map` to a style error, so\n`cargo clippy --all-features -- -D warnings` fails on the two session-map\nloops that destructure an unused key. Iterating with `values()` /\n`values_mut()` expresses the same intent without the discarded binding.\n\n* fix(rust): reconnect the requested peer instead of the access endpoint\n\n`reconnect_session` rebuilt a missing session from `option.access_url()` while\nreporting `Ok(true)` for the peer that was asked for. When the two differ\n(broker endpoint drift), the reconnect retry loop logged \"telemetry stream for\npeer ... re-established\" and exited although that peer had no stream at all.\nSession-map keys always come from `Endpoints::endpoint_url`, so the peer url\nround-trips back into a valid endpoint and the rebuild can target it directly.\n\nThe new test took no part in the `MTX` serialization that the other\n`MockSession::new_context()` tests use, so mockall\u0027s process-wide context was\nswapped under concurrently running tests and the suite failed at random\n(`MockSession::new: No matching expectation found`). `client_get_session` had\nthe same gap. Both now take the lock."
    },
    {
      "commit": "9f77cf18a8c049698d97f3a1268626debdf3f549",
      "tree": "d800b50db5484ce2a0fcf565cbaddc82a2822d74",
      "parents": [
        "62850895dab3742abc0675c9a73366c6eff82518"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Fri Oct 23 22:20:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 22:20:19 2026 +0800"
      },
      "message": "[ISSUE #1428] [Rust] Decompress received message body and verify its digest (#1429)"
    },
    {
      "commit": "62850895dab3742abc0675c9a73366c6eff82518",
      "tree": "9f1784400fec5478e95982ca6eb852bebfbf654d",
      "parents": [
        "d8637d26bc7dc6a02eb9714b775050b11e4abdfa"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Fri Oct 23 18:40:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 18:40:10 2026 +0800"
      },
      "message": "[ISSUE #1413] [Rust] Increase delivery attempt on FIFO local retry (#1414)\n\nFifoConsumerWorker kept the attempt in a local counter, so the listener saw\nthe server-provided delivery attempt on every local retry, the first retry\nused the delay of attempt 2, and the DLQ request reported max attempts + 1.\n\nAlign with the Java client (ProcessQueueImpl#eraseFifoMessage): while the\ndelivery attempt is below the max attempts, take the delay of the current\nattempt, increase the attempt on the MessageView\n(MessageViewImpl#incrementAndGetDeliveryAttempt) and consume again;\notherwise forward the message to the DLQ with its current delivery\nattempt. The listener now sees 1, 2, ..., max attempts. The standard\n(non-FIFO) path is unchanged."
    },
    {
      "commit": "d8637d26bc7dc6a02eb9714b775050b11e4abdfa",
      "tree": "fce93305c2a6f8c817b8a4196d4c9ba455305fef",
      "parents": [
        "c4c063f83254dc59785ba16fd740762425d8e97d"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Fri Oct 23 13:54:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 13:54:54 2026 +0800"
      },
      "message": "[ISSUE #1410] [Rust] Treat a panic in the PushConsumer listener as consume failure (#1411)\n\nThe message listener was called directly by the consumer workers, so a\npanic unwound through the worker task and stopped it for good, and the\nmessage being consumed was neither acked nor nacked.\n\nAlign with the Java client (ConsumeTask#call catches any Throwable raised\nby the listener and marks the consumption as FAILURE): invoke the listener\nthrough catch_unwind in both the standard and the FIFO worker, log the\npanic and continue with ConsumeResult::FAILURE, so the message goes\nthrough the normal redelivery / local retry / DLQ path.\n\nAlso take the static-mock lock in client::tests::client_get_session; it\nset MockSession::new expectations without it and could race with\ntest_get_session_for_lite_consumer."
    },
    {
      "commit": "c4c063f83254dc59785ba16fd740762425d8e97d",
      "tree": "1046df9ce8872b33b8ed9f0ba1741719a7d6c380",
      "parents": [
        "8a686b5baf02ac784a8cd2f0a59981f01d087c7c"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Fri Oct 23 09:01:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 09:01:59 2026 +0800"
      },
      "message": "[ISSUE #1415] [Rust] Reject lite batch and check send receipt count (#1416)\n\nThe proxy stores a multi-message SendMessageRequest as one batch and\nreturns a single SendResultEntry whose message_id joins all ids. The broker\nonly dispatches a lite message to its lite topic on the single-message\npath, so a batch of lite messages was reported as sent by batch_send but\nnever delivered to lite consumers.\n\n- Reject a batch of more than one message that contains a lite message\n  with InvalidMessage before sending.\n- Align with the Java client (ProducerImpl#send0): fail the send with\n  ErrorKind::Server when the number of receipts differs from the number of\n  sent messages, instead of returning the server entries as is. This also\n  removes the panic of Producer::send when the server returns no entry.\n\nBREAKING CHANGE: since the proxy returns one entry per batch, batch_send\nwith more than one message now fails for normal messages too. Send\nmessages one by one with Producer::send."
    },
    {
      "commit": "8a686b5baf02ac784a8cd2f0a59981f01d087c7c",
      "tree": "e2b20b97c5902dfe48b3c859ac862cced7bcd815",
      "parents": [
        "18468ee6a89956b333f8beaa63e48cd752cbccfb"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Fri Oct 23 09:01:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 09:01:33 2026 +0800"
      },
      "message": "[ISSUE #1419] [Rust] Strip http:// and https:// prefix from access url (#1421)\n\nEndpoints::from_url kept the scheme as part of the host, so an access url\nsuch as \"http://localhost:8080\", used by the official lite examples, failed\nto connect with a DNS error.\n\nAlign with the Java client (Endpoints(String)): strip the http:// or\nhttps:// prefix for a single address. A multi-address url is left as is,\nand the prefix does not enable TLS, like Java."
    },
    {
      "commit": "18468ee6a89956b333f8beaa63e48cd752cbccfb",
      "tree": "c39265b9ef0961001ccde32894a77382530ff161",
      "parents": [
        "3a47e1de95deea3909b6ff64fd26cc0b24d0e611"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Fri Oct 23 09:01:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 09:01:06 2026 +0800"
      },
      "message": "[ISSUE #1418] [Rust] Reject blank lite topic in MessageBuilder (#1420)\n\nAn empty or blank lite topic was accepted by MessageBuilder and only\nrejected by the server, with 40014 (expected LITE but actual NORMAL) for an\nempty string or 40020 for whitespace.\n\nAlign with the Java client (MessageBuilderImpl#setLiteTopic checks\nStringUtils.isNotBlank): build() now fails with InvalidMessage\n\"lite_topic should not be blank.\" for both lite_message_builder and\nset_lite_topic. Surrounding whitespace of a non-blank lite topic is kept\nas is, like Java."
    },
    {
      "commit": "3a47e1de95deea3909b6ff64fd26cc0b24d0e611",
      "tree": "f93c83954465fa791ed0c03c39818ec88d1ea5c4",
      "parents": [
        "7b0e26cf665e120eec9155d3259c0b17e8aa8544"
      ],
      "author": {
        "name": "Lei Zhiyuan",
        "email": "leizhiyuan@gmail.com",
        "time": "Fri Oct 23 09:00:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 09:00:38 2026 +0800"
      },
      "message": "[ISSUE #1406] [Rust] Take PushConsumer filter expression from the subscription (#1407)\n\nThe filter expression used by ReceiveMessage was looked up by the assigned\nmessage queue\u0027s topic name. Servers may return a decorated name such as\n\"\u003cinstance\u003e%\u003ctopic\u003e\", so the lookup failed, no ReceiveMessage was sent and\nthe worker spun on a 1 ms ticker without backoff.\n\nAlign with the Java client:\n- pass the subscription\u0027s FilterExpression from scanAssignments to\n  MessageQueueActor (PushConsumerImpl#syncProcessQueue / ProcessQueueImpl)\n- back off 20 ms on TooManyRequests and 1 s on other receive failures\n  (ProcessQueueImpl#onReceiveMessageException)"
    },
    {
      "commit": "7b0e26cf665e120eec9155d3259c0b17e8aa8544",
      "tree": "c0a79213e19af21519ac44a88cbc75c6eec76f1f",
      "parents": [
        "f9829e51ad5018fb4526bad084bb3d6ddd45a53e"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Fri Oct 23 05:55:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 23 05:55:55 2026 +0800"
      },
      "message": "[ISSUE #1412] [CI] Stop gating build-result on the Rust build (#1442)\n\n`build-result` is the required status check on master, and it aggregates\n`rust-build`. That gates every Rust PR on a Rust baseline which is\ncurrently red for reasons unrelated to any open change:\n\n- rust/Cargo.lock is gitignored, so each run resolves dependencies from\n  scratch and now pulls hyper-util \u003e\u003d 0.1.16 (edition 2024, needs\n  rustc \u003e\u003d 1.85) and powerfmt \u003e\u003d 0.2.1 (needs rustc \u003e\u003d 1.79). Both break\n  the 1.74 toolchain that the `msrv` and `build` jobs install.\n- Stable clippy fails on two pre-existing `for_kv_map` warnings in\n  rust/src/client.rs (lines 904 and 912), which `-D warnings` turns into\n  errors.\n\nSince `build` declares `needs: [fmt, msrv]`, an msrv failure skips the\nwhole Ubuntu/macOS/Windows matrix, and `build-result` then blocks every\nRust PR whose head does not carry the dependency pins.\n\nDrop `rust-build` from `needs` and from the aggregation script.\n`rust_build.yml` is untouched: every Rust job still runs and still\nreports its true result, so the signal stays visible on the PR -- it just\nno longer gates the merge. Reviewers of Rust changes need to read\n`rust-build / *` directly until this is reverted.\n\nRestore `rust-build` here once the dependency pins (powerfmt \u003c 0.2.1,\nhyper-util \u003c 0.1.16, tokio \u003c 1.47) and the `for_kv_map` fix land on\nmaster. #1404 contains both and is green."
    },
    {
      "commit": "f9829e51ad5018fb4526bad084bb3d6ddd45a53e",
      "tree": "a4a850cdd142325953771fa20de653b3dacb3870",
      "parents": [
        "a3d1de8babcd25f47fd57e04c567ed9dae69103b"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Thu Oct 22 17:47:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 22 17:47:18 2026 +0800"
      },
      "message": "fix(nodejs): create the first-settings promise before any await in startup (#1405)\n\n* fix(nodejs): create the first-settings promise before any await in startup\n\nstartup() waits for the first onSettingsCommand before it completes, but it\nregistered the promise resolvers only after updateRoutes() had finished. The\nroute fetch itself opens telemetry sessions and syncs settings while it is\nstill iterating the topics: after the first topic, the loop awaits the next\nqueryRoute and yields the event loop, so a server-pushed Settings callback\ncan fire while the resolvers are still undefined. The first callback is then\nsilently dropped and startup hangs on the await until the periodic settings\nsync fires five minutes later (or forever, if that sync fails).\n\nCreate the promise (and its resolvers) before any await in #startup, so the\nfirst Settings callback can resolve it no matter when it arrives. The\nonUnknownCommand reject path is covered by the same change.\n\n* fix(nodejs): attach a rejection handler to the first-settings promise at creation\n\nonUnknownCommand() rejects the first-settings promise as soon as a status-only\ntelemetry command arrives. The promise is created before updateRoutes() but only\nawaited after it finishes, so a rejection arriving during another topic\u0027s route\nquery or the retry backoff window had no rejection handler attached; under\nNode.js\u0027s default unhandled-rejection behavior that terminates the process even\nthough the startup() caller would have handled the rejection.\n\nAttach a no-op catch handler immediately after creating the promise; the await\nbelow still observes the error and propagates it to the caller. Also clear the\nstartup resolvers in a finally block so they never dangle across the early-throw\n(route fetch failure) and first-settings rejection paths.\n\nReproduced with a minimal script on Node v22.22.2 (exit code 1 pre-fix); a\nregression test covering a telemetry error before route updates complete is\nincluded."
    },
    {
      "commit": "a3d1de8babcd25f47fd57e04c567ed9dae69103b",
      "tree": "53f51072389c665a1e0bedb2730b7a23a02d97b7",
      "parents": [
        "6b0bcc422ff1ee66198df6b4a48a4a44ad7218fa"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Tue Oct 13 16:51:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 13 16:51:33 2026 +0800"
      },
      "message": "enhancement(nodejs): bump version to 1.1.0 (#1398)"
    },
    {
      "commit": "6b0bcc422ff1ee66198df6b4a48a4a44ad7218fa",
      "tree": "b7a1e2e38f12f655593c5b43421b615b6a0f9c0c",
      "parents": [
        "fa490c2a7a7f81b06ecdd554110b3221d47f6541"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Mon Oct 12 16:13:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 12 16:13:35 2026 +0800"
      },
      "message": "[Node.js] Fix ESLint errors in src and test so the lint gate passes (#1396)\n\n- parenthesize ambiguous conditional arrow bodies and normalize array-bracket-spacing\n- add eslint-disable-next-line for intentionally-unused positional params\n- convert empty mock methods to () \u003d\u003e undefined\n- wrap test-only require() in an eslint-disable no-var-requires block"
    },
    {
      "commit": "fa490c2a7a7f81b06ecdd554110b3221d47f6541",
      "tree": "f15ac0fe5a90ee5ed8942936ab70a79631b6a4d3",
      "parents": [
        "6c96a836affe75f1f2f1fe9fe6856aff161e6322"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Fri Oct 09 11:20:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 11:20:45 2026 +0800"
      },
      "message": "Feat/nodejs message interceptor hooks (#1384)\n\n* feat(nodejs): support NOTIFY_UNSUBSCRIBE_LITE_COMMAND and message interceptor hooks\n\n- BaseClient: add onNotifyUnsubscribeLiteCommand hook (warn by default,\n  overridden by lite push consumers)\n- TelemetrySession: dispatch NOTIFY_UNSUBSCRIBE_LITE_COMMAND (was falling\n  through to the unknown-command branch)\n- LitePushConsumerImpl: override the command handler with the endpoints-aware\n  signature and forward to the lite subscription manager\n- BaseClient: drop the commented-out recover-orphaned-transaction reply\n  (warn only, no reply)\n- New hook package: MessageHookPoints, MessageHookPointsStatus,\n  Attribute/AttributeKey, MessageInterceptor(+Context/Impl),\n  CompositedMessageInterceptor and InflightRequestCountInterceptor; clients\n  expose addMessageInterceptor and doBefore/doAfter, configurable via\n  BaseClientOptions#messageInterceptor\n- Wire hook points: SEND (producer), RECEIVE/ACK/CHANGE_INVISIBLE_DURATION\n  (consumer), CONSUME (consume task); push consumers register the built-in\n  inflight request count interceptor\n- Tests: cover telemetry dispatch and interceptor chain ordering, error\n  isolation, attribute propagation and inflight counting\n\n* feat(nodejs): wire COMMIT_TRANSACTION / ROLLBACK_TRANSACTION / FORWARD_TO_DLQ hook points\n\nComplete the remaining 3 of the 8 MessageHookPoints:\n\n- K-2 Producer#endTransaction fires COMMIT_TRANSACTION / ROLLBACK_TRANSACTION\n  (selected by resolution \u003d\u003d\u003d COMMIT), hook status OK/ERROR taken from the\n  response Code or the thrown error.\n- K-3 Consumer#forwardMessageToDeadLetterQueueViaRpc fires FORWARD_TO_DLQ\n  around every DLQ RPC attempt. ProcessQueue now forwards the MessageView\n  so interceptors observe the real message.\n- Add 4 regression tests (transaction hooks, DLQ hook, error paths);\n  offline suite 119/119, integration 16/16.\n\n* fix(nodejs): align message interceptor hooks with the Java client\n\nReviewer feedback on the hook framework: RECEIVE had to be intercepted\nbefore the RPC so in-flight request counters observe real requests, the\nPushConsumer settlement paths had to fire the same ACK /\nCHANGE_INVISIBLE_DURATION hooks as SimpleConsumer (including retries),\nand the composite interceptor had to keep Java\u0027s cumulative context\nsemantics so chained interceptors see each other\u0027s attributes."
    },
    {
      "commit": "6c96a836affe75f1f2f1fe9fe6856aff161e6322",
      "tree": "383a8e8081216a404d622bfd2e6478bdd6c0d0df",
      "parents": [
        "8fd7226cd3fd64b30c3afa2a7386e8058de7f41b"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Fri Oct 09 10:53:14 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 10:53:14 2026 +0800"
      },
      "message": "feat(nodejs): add consumer-side rate limiting via semaphore backpressure (#1386)\n\nAdd src/util/Semaphore.ts and apply it to ProcessQueue, bounding in-flight\nconsumption by consumeConcurrentlyMax (default 32). The receive loop\npauses while all semaphore permits are taken, providing per-queue\nconsumption backpressure; the setting is parsed from broker-side settings\nwhen present."
    },
    {
      "commit": "8fd7226cd3fd64b30c3afa2a7386e8058de7f41b",
      "tree": "6f9290cc2d1e255f6fb60b2946eb242444f1c999",
      "parents": [
        "4123af49bcef731746fe3fdfc1823ba01f10f80e"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Fri Oct 09 10:45:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 10:45:00 2026 +0800"
      },
      "message": "Feat/nodejs metrics export (#1387)\n\n* feat(nodejs): support NOTIFY_UNSUBSCRIBE_LITE_COMMAND and message interceptor hooks\n\n- BaseClient: add onNotifyUnsubscribeLiteCommand hook (warn by default,\n  overridden by lite push consumers)\n- TelemetrySession: dispatch NOTIFY_UNSUBSCRIBE_LITE_COMMAND (was falling\n  through to the unknown-command branch)\n- LitePushConsumerImpl: override the command handler with the endpoints-aware\n  signature and forward to the lite subscription manager\n- BaseClient: drop the commented-out recover-orphaned-transaction reply\n  (warn only, no reply)\n- New hook package: MessageHookPoints, MessageHookPointsStatus,\n  Attribute/AttributeKey, MessageInterceptor(+Context/Impl),\n  CompositedMessageInterceptor and InflightRequestCountInterceptor; clients\n  expose addMessageInterceptor and doBefore/doAfter, configurable via\n  BaseClientOptions#messageInterceptor\n- Wire hook points: SEND (producer), RECEIVE/ACK/CHANGE_INVISIBLE_DURATION\n  (consumer), CONSUME (consume task); push consumers register the built-in\n  inflight request count interceptor\n- Tests: cover telemetry dispatch and interceptor chain ordering, error\n  isolation, attribute propagation and inflight counting\n\n* feat(nodejs): wire COMMIT_TRANSACTION / ROLLBACK_TRANSACTION / FORWARD_TO_DLQ hook points\n\nComplete the remaining 3 of the 8 MessageHookPoints:\n\n- K-2 Producer#endTransaction fires COMMIT_TRANSACTION / ROLLBACK_TRANSACTION\n  (selected by resolution \u003d\u003d\u003d COMMIT), hook status OK/ERROR taken from the\n  response Code or the thrown error.\n- K-3 Consumer#forwardMessageToDeadLetterQueueViaRpc fires FORWARD_TO_DLQ\n  around every DLQ RPC attempt. ProcessQueue now forwards the MessageView\n  so interceptors observe the real message.\n- Add 4 regression tests (transaction hooks, DLQ hook, error paths);\n  offline suite 119/119, integration 16/16.\n\n* feat(nodejs): add metrics export pipeline over OpenTelemetry / OTLP gRPC\n\nAdd src/metrics/*:\n- ClientMeterManager rebuilds an OpenTelemetry SdkMeterProvider on every\n  settings command, exporting the four RocketMQ histograms (send cost\n  time, delivery latency, await time, process time) with explicit bucket\n  boundaries, plus consumer cached-message gauges. Every export request is\n  signed through the client\u0027s MQv2-HMAC-SHA1 metadata provider.\n- MessageMeterInterceptor records the histograms at the SEND / RECEIVE /\n  CONSUME hook points via the interceptor chain.\n- PushConsumerGaugeObserver aggregates cached messages/bytes per topic.\n- BaseClient wires the manager (created in the constructor, reset from\n  onSettingsCommand, shut down on client shutdown)."
    },
    {
      "commit": "4123af49bcef731746fe3fdfc1823ba01f10f80e",
      "tree": "479434201944f6c84a82138fb9da018a0d9b8d7c",
      "parents": [
        "13b9299e5a80d53cf5b448e5a0590ff6ebecba1a"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Fri Oct 09 10:15:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 10:15:52 2026 +0800"
      },
      "message": "fix(nodejs): correct message-group routing and consumption lifecycle guards (#1388)\n\n* fix(nodejs): correct message-group routing and consumption lifecycle guards\n\n- PublishingLoadBalancer: interpret SipHash-2-4 as signed int64 and apply\n  floorMod for message-group routing (the previous unsigned modulo routed\n  \u0027negative\u0027 hashes to different queues)\n- PushConsumer: bound the cached-message drain wait by\n  requestTimeout + longPollingTimeout so shutdown cannot hang forever on\n  a stuck consumption chain\n- SimpleConsumer: guard receive/ack/changeInvisibleDuration with\n  isRunning() checks\n- LiteSubscriptionManager: sync lite subscriptions to all route endpoints\n  (not only the client\u0027s configured endpoints); expose\n  LitePushConsumerImpl#getTotalRouteEndpoints()\n\n* chore(nodejs): untrack the local scratch telemetry test\n\nIt was picked up accidentally by a broad `git add` during the master merge\nand has no place in the repository; license-eye rejects it for the missing\nASF header."
    },
    {
      "commit": "13b9299e5a80d53cf5b448e5a0590ff6ebecba1a",
      "tree": "dafbd1fbf30728976670530799506b9fb64d7e0d",
      "parents": [
        "cd738faf51f9396af169229a68507bf076cc2eb9"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Fri Oct 09 10:14:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 10:14:53 2026 +0800"
      },
      "message": "Feat/nodejs ip name resolver (#1385)\n\n* fix(nodejs): transport layer self-healing and logger close deferral\n\n- Endpoints: prefix gRPC target with resolver scheme (ipv4:/ipv6:/dns:),\n  bracket IPv6 hosts for grpc-js\n- RpcClientManager: key rpc clients by endpoints facade string instead of\n  object identity (endpoints are recreated on every route fetch, leaking\n  duplicate channels); add evict()\n- RpcClient: add keepalive (5min/30s + permit_without_calls) and max\n  message size channel options\n- BaseClient: rejoin isolated endpoints after successful heartbeat;\n  rebuild transport (evict rpc client + refresh telemetry session) after\n  consecutive heartbeat failures with a 30s per-endpoints cooldown;\n  respond VerifyMessageResult (not echo command) to verify-message\n  command; return real process diagnostics for print-thread-stack-trace\n- BaseClient: defer logger.close() to the next macrotask so subclass\n  shutdown logs do not throw \u0027log stream had been close\u0027\n\n* feat(nodejs): add custom ip: gRPC name resolver for endpoints targets\n\nRegister an `ip` scheme resolver (src/route/IpNameResolver.ts) so that\nmulti-address proxy endpoints are resolved as a static address group with\nshuffle-based load balancing across proxies, instead of relying on the\ndefault DNS resolution.\n\nEndpoints.getGrpcTarget() now emits `ip:` for both IPv4 and IPv6\naddresses; the resolver brackets bare IPv6 hosts for grpc-js."
    },
    {
      "commit": "cd738faf51f9396af169229a68507bf076cc2eb9",
      "tree": "c25dc8c7c7f53c5b847db810cf392dd6b07db944",
      "parents": [
        "2a554b9c408b27d0b71ed310c06804b8a8280dc6"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Wed Sep 23 11:19:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 11:19:00 2026 +0800"
      },
      "message": "fix(nodejs): transport layer self-healing and logger close deferral (#1375)\n\n- Endpoints: prefix gRPC target with resolver scheme (ipv4:/ipv6:/dns:),\n  bracket IPv6 hosts for grpc-js\n- RpcClientManager: key rpc clients by endpoints facade string instead of\n  object identity (endpoints are recreated on every route fetch, leaking\n  duplicate channels); add evict()\n- RpcClient: add keepalive (5min/30s + permit_without_calls) and max\n  message size channel options\n- BaseClient: rejoin isolated endpoints after successful heartbeat;\n  rebuild transport (evict rpc client + refresh telemetry session) after\n  consecutive heartbeat failures with a 30s per-endpoints cooldown;\n  respond VerifyMessageResult (not echo command) to verify-message\n  command; return real process diagnostics for print-thread-stack-trace\n- BaseClient: defer logger.close() to the next macrotask so subclass\n  shutdown logs do not throw \u0027log stream had been close\u0027"
    },
    {
      "commit": "2a554b9c408b27d0b71ed310c06804b8a8280dc6",
      "tree": "8e2ababf66ebcce4344493616def00753fba9666",
      "parents": [
        "51561a16646bc82522406b13cb4e164df5ffa46f"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Wed Sep 23 10:20:53 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 10:20:53 2026 +0800"
      },
      "message": "fix(nodejs): fail fast on NotFoundException during startup route fetch (#1374)\n\nNon-not-found errors keep the 3-attempt retry with linear backoff, but\nNotFoundException (topic/consumer group does not exist) can never succeed\non retry - surface it immediately so the error message and cause chain\ncarry NotFoundException(40402) instead of a generic \u0027Failed to fetch\ntopic routes after 3 attempts\u0027 wrapper."
    },
    {
      "commit": "51561a16646bc82522406b13cb4e164df5ffa46f",
      "tree": "3d51050406cd8b9859a436e71bc3ebac79b15dea",
      "parents": [
        "3357f9c077bfc15caa506a6271ecdf0e288f85a0"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Tue Sep 22 17:34:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 22 17:34:02 2026 +0800"
      },
      "message": "enhancement(nodejs): isolate gRPC connections between client instances (#1383)\n\n- Pass \u0027grpc.use_local_subchannel_pool\u0027: 1 when constructing MessagingServiceClient\n- Give each RpcClient its own connection instead of grpc-js\u0027s shared global pool\n- Add broker-free regression test for cross-client isolation and intra-client reuse"
    },
    {
      "commit": "3357f9c077bfc15caa506a6271ecdf0e288f85a0",
      "tree": "5c77549ceb797d55a829a66a885e159edec124e2",
      "parents": [
        "cf0893a9259c704ecb6b70a94691735aa977dd0b"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Tue Sep 22 10:50:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 22 10:50:19 2026 +0800"
      },
      "message": "fix(nodejs): align retry units, endpoints parsing (#1373)\n\n* fix(nodejs): correct retry backoff units, endpoints parsing and status mappings\n\n- Retry delays are milliseconds (the protobuf contract\u0027s unit was\n  misimplemented); inherited backoff preserves sub-second precision from\n  the server Duration (seconds * 1000 + nanos / 1e6)\n- Endpoints string parsing rewritten: strip the optional http(s)://\n  prefix, parse bracketed and bare IPv6 addresses, split the port via\n  lastIndexOf(\u0027:\u0027)\n- StatusChecker new mappings: ILLEGAL_LITE_TOPIC -\u003e BadRequestException,\n  MESSAGE_BODY_EMPTY -\u003e PayloadEmptyException,\n  LITE_SUBSCRIPTION_QUOTA_EXCEEDED -\u003e LiteSubscriptionQuotaExceededException\n- TelemetrySession: fix the reconnect timer leak; release() clears the\n  timer and guards reconnection, error/end events dedupe through a\n  single reconnect schedule\n- Add tsconfig.test.json for compiling src and test together\n\nTests: rename regression suite to test/fixes.test.ts (13 offline cases,\nall pass); tsc clean for both the prod and the test config\n\n* fix(nodejs): keep auto-reconnect alive after telemetry session refresh\n\nrefresh() tore down the old stream through release(), which permanently\nset #released and thus made #scheduleRenewStream() a no-op forever. Any\nlater stream error or completion was silently never reconnected.\n\nRefresh now only cancels a pending reconnect timer and closes the stream,\nleaving release() as the sole shutdown path."
    },
    {
      "commit": "cf0893a9259c704ecb6b70a94691735aa977dd0b",
      "tree": "b9d083e82ad7970bc03ca3cc9b2c9c801017b3b6",
      "parents": [
        "981a507eda963c92e06c174250f40f68a5eb1a57"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Thu Sep 17 14:46:21 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 17 14:46:21 2026 +0800"
      },
      "message": "feat(nodejs): implement LiteSimpleConsumer (#1379)\n\n* feat(nodejs): implement LiteSimpleConsumer\n\nPort the lite simple consumer from the reference client implementation:\n\n- Add `LiteSimpleConsumer` (interface + builder options) and\n  `LiteSimpleConsumerImpl` with `subscribeLite` / `unsubscribeLite`,\n  `receive`, `ack`, `changeInvisibleDuration` and startup/shutdown flow\n- Rework `LiteSubscriptionManager` to be host-agnostic and sync lite\n  subscriptions (FULL / PARTIAL_ADD / PARTIAL_REMOVE) to every sync\n  endpoint, with quota handling and notify-unsubscribe support\n- Handle `NOTIFY_UNSUBSCRIBE_LITE_COMMAND` in `BaseClient` /\n  `TelemetrySession` and align the callback signature across consumers\n- Fix lite ack path: include `liteTopic` in ack and\n  change-invisible-duration requests for lite consumers, matching the\n  server-side receipt handle resolution\n- Add offline unit tests (builder validation, subscription sync,\n  route pruning) and real-cluster integration tests (end-to-end\n  send/receive/ack, subscribe-then-send delivery, unsubscribe-stop,\n  blank topic validation)\n\n* docs(nodejs): add LiteSimpleConsumer example\n\nAdd a runnable LiteSimpleConsumer example and document the lite topic\nusage in the Node.js README:\n\n- examples/LiteSimpleConsumerExample.ts: build a lite simple consumer\n  bound to a parent topic, subscribe/unsubscribe lite topics with\n  OffsetOption, receive-ack loop with changeInvisibleDuration fallback\n  on ack failure, and graceful shutdown on SIGINT\n- README: new \"Lite Topic\" section covering the server prerequisites,\n  producer-side liteTopic send, and the LiteSimpleConsumer pull/ack flow\n\n* refactor(nodejs): stop exporting LiteSimpleConsumerImpl from the consumer barrel\n\nThe consumer barrel re-exported LiteSimpleConsumerImpl, so its host-only\nhelpers (getRpcClientManager, getLogger, getRequestTimeout, getSyncEndpoints)\nended up in the published .d.ts and became public API - hard to change once the\npackage is released.\n\nExport the interface + builder only (`export * from \u0027./LiteSimpleConsumer\u0027`).\nUsers still obtain instances through `build()`, which returns the\n`LiteSimpleConsumer` interface. Tests import the impl by file path, so they are\nunaffected. LitePushConsumerImpl is intentionally left exported.\n\nVerified:\n- emitted declarations: the entry chain (index.d.ts -\u003e consumer/index.d.ts) no\n  longer references LiteSimpleConsumerImpl, while\n  `build(): Promise\u003cLiteSimpleConsumer\u003e` is unchanged;\n- tsc -p tsconfig.prod.json and -p tsconfig.test.json: 0 errors;\n- eslint: 0 errors;\n- non-integration suite: 97/97 pass."
    },
    {
      "commit": "981a507eda963c92e06c174250f40f68a5eb1a57",
      "tree": "2415b2be9e05c7168d59cec6d6fe75a6a417bac8",
      "parents": [
        "2bbe25b5682591887bdd9973305774e62792c0d7"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Wed Sep 16 14:08:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 16 14:08:52 2026 +0800"
      },
      "message": "fix(golang): close the receive hook when long polling finds no message (#1378)\n\nA push consumer opens the RECEIVE hook before every long polling request\nand closes it once the request completes, but the branch handling\nMESSAGE_NOT_FOUND only logged, so a queue with no traffic leaked one\ninflight reception per poll. The counter never came back down, and\nwaitingReceiveRequestFinished always burned its full\nrequestTimeout + longPollingTimeout, about 33s by default, before logging\n\"Timeout waiting for all inflight receive requests\" and giving up. Every\npush consumer shutdown paid that.\n\nReport the completed reception instead: OK for an empty poll, ERROR for a\nreal failure, which keeps the current logging. Metrics are unaffected\nbecause the meter interceptor ignores a RECEIVE hook carrying no messages,\nso idle polling still records nothing.\n\nAdds a regression test that drives a queue whose long polling always\nanswers MESSAGE_NOT_FOUND and asserts the inflight count returns to zero\nonce the receptions complete. It fails before this change with one leaked\nreception per poll.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "2bbe25b5682591887bdd9973305774e62792c0d7",
      "tree": "6ab0aa50fae03009f98e2ef1d63f87cc646bca00",
      "parents": [
        "2513a7b1660b08a47acfac617eb9f2d74405d66b"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Wed Sep 16 14:08:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 16 14:08:37 2026 +0800"
      },
      "message": "[csharp] Add LiteSimpleConsumer with tests and example (#1380)\n\nImplement the lite-topic variant of SimpleConsumer for the C# client,\nmirroring the Java/Node.js reference implementation.\n\nImplementation\n- LiteSimpleConsumer: consumer bound to a single parent (bind) topic that\n  dynamically (un)subscribes lite topics via SyncLiteSubscription. Supports\n  SubscribeLite(liteTopic), SubscribeLite(liteTopic, OffsetOption),\n  UnsubscribeLite(liteTopic), GetLiteTopicSet(), GetBindTopic() plus the\n  inherited SimpleConsumer receive/ack/changeInvisibleDuration APIs.\n- LiteSimpleSubscriptionSettings: SimpleSubscriptionSettings with\n  ClientType.LITE_SIMPLE_CONSUMER so the server derives LITE_SELECTIVE mode.\n- ClientType: add LiteSimpleConsumer and map it to the protobuf enum.\n- LiteSubscriptionManager: generalize from PushConsumer to the Consumer base\n  (both lite consumer kinds share it) and add Shutdown() to dispose the\n  periodic sync timer.\n- Consumer: add shared CheckRunning/GetRequestTimeout/Namespace/SyncLiteSubscription\n  and recognize LiteSimpleSubscriptionSettings; PushConsumer now overrides them.\n- MessageView: expose LiteTopic parsed from system properties.\n- SubscriptionLoadBalancer: throw NotFoundException instead of dividing by\n  zero when the route carries no queue.\n\nDefect fix: missing liteTopic in ack\n- WrapAckMessageRequest / WrapChangeInvisibleDuration now set LiteTopic from\n  MessageView.LiteTopic. Without it the proxy cannot resolve the LMQ receipt\n  handle and answers 50001 INTERNAL_SERVER_ERROR.\n\nTests\n- tests/LiteSimpleConsumerTest.cs: 20 offline unit tests (builder validation,\n  settings/heartbeat client type, subscribe/unsubscribe sync actions, dedup,\n  quota, notify-unsubscribe command, liteTopic carried in ack and\n  changeInvisibleDuration, route pruning).\n- tests/LiteSimpleConsumerIntegrationTest.cs: 3 real-cluster tests, guarded by\n  ROCKETMQ_CSHARP_LITE_ENDPOINTS. Verified against a local RocketMQ 5.5.1\n  cluster (broker enableLmq/enableMultiDispatch, proxy in CLUSTER mode,\n  message.type\u003dLITE parent topic, group with +lite.bind.topic): 3/3 passed.\n\nExample\n- examples/LiteSimpleConsumerExample.cs and its QuickStart wiring."
    },
    {
      "commit": "2513a7b1660b08a47acfac617eb9f2d74405d66b",
      "tree": "680bac990d4021017f6e3a8d633e56be8619c0cd",
      "parents": [
        "fc4b90bdb144c62556f35d59ad7a6fbce30c1092"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Wed Sep 16 14:04:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 16 14:04:55 2026 +0800"
      },
      "message": "[Go] Align half-open gRPC recovery with Java (#1377)\n\n* fix(golang): make the RPC transport rebuildable and its close idempotent\n\nRecovering from a half-open connection needs a replacement transport that\nis configured exactly like the one it replaces, so freeze the effective\nconnection options into the RPC client and add an unexported recreate hook\nthat rebuilds from them. The public RpcClient interface is unchanged: the\nnew capabilities are optional interfaces that the manager type-asserts.\n\nAlso make close idempotent, because both the retirement path and the\nrebuild path close a transport; let an in-flight dial be canceled through\nits context so shutdown and endpoint retirement can interrupt it; close a\ncandidate whose dial failed; and stop discarding the cancel func of the\ndial timeout context.\n\n* fix(golang): keep concurrently re-applied settings race-free\n\nSettings are re-applied on the telemetry goroutine while the send and\nconsume paths read them. The race detector reports both of these as soon\nas a stream is renewed under traffic:\n\n- the producer retry policy is replaced as a whole under a lock and cloned\n  into outbound settings instead of being mutated in place, so a snapshot\n  already handed to a caller stays immutable;\n- the meter provider clientMeter pointer became atomic, because Reset\n  swaps the whole meter while isEnabled and record read the field without\n  a lock.\n\nNeither is visible without the race detector: reproduce with\n`go test -race`, CI runs `go test -v`.\n\n* test(golang): cover the producer retry policy snapshot\n\nAdd a producer fixture that uses a per-test mock client manager and cached\nroutes instead of the package-wide RPC client stub, and use it to assert\nthat applying settings replaces the retry policy rather than mutating a\nsnapshot callers already hold, including while sends are in flight.\n\nRun with `go test -race` to reproduce the original failure; CI runs\n`go test -v`.\n\n* fix(golang): recover half-open transports from heartbeat and server signals\n\nA half-open TCP connection keeps reporting READY, so every RPC blocks\nuntil its deadline and the client never recovers. Only two signals may now\nreplace a transport: heartbeat connectivity failures and the server\nReconnectEndpointsCommand. Ordinary unary failures no longer evict a\nconnection, so handleGrpcError and its call sites are gone.\n\nRecovery rebuilds the ClientConn, because gRPC-Go cannot evict a READY\nconnection: Connect and ResetConnectBackoff do not, enterIdle is\nunexported, and the idle timer never fires while a telemetry stream is\nactive. A candidate is dialed outside the cache lock and published only\nafter re-checking that it is still current, wanted and not stopped; a\nrejected candidate is closed, and the transport being replaced is closed\noutside the lock. Two consecutive DEADLINE_EXCEEDED trigger recovery,\nUNAVAILABLE only while the old connection still reports READY, anything\nelse clears the counter, and a 30s per-endpoint cooldown applies unless\nthe server asked for it. In-flight dials are tracked separately from cache\nentries so retiring an endpoint cannot release the guard on its address.\n\nEach telemetry session now gets one supervisor goroutine: it renews the\nstream after a 1s cancellable backoff instead of waiting for the next\npublish, resends Settings on every new stream, cancels the stream context\nbefore CloseSend so a Send stuck on a half-open connection cannot block\nshutdown, and reports the startup result once through a channel. Route\nupdates count the endpoints they are still initializing so a session that\nis starting is not retired, deprecated endpoints drop their recovery\nbookkeeping, and route lookups clone endpoints before the in-place sort in\nEndpointsToString. The ReceiveReconnect flag, written from the telemetry\ngoroutine and read by callers, gets accessors.\n\nTests that asserted the previous session internals through log strings and\nsleeps are removed here because they reference symbols this commit\ndeletes; their replacements follow in the test commits.\n\n* test(golang): cover the recovery state machine and telemetry lifecycle\n\nReplace the tests that drove the old session internals with sleeps and log\nmatching. Recovery is now asserted through channel barriers: the threshold,\nthe Ready-only UNAVAILABLE branch, counter resets, the cooldown and its\nexpiry, a server command bypassing the cooldown but not the in-progress\nguard, retirement keeping the transport while clearing its bookkeeping, a\ncanceled recovery never publishing its candidate, a late heartbeat not\naccounting against its successor, shutdown waiting for an in-flight\ncandidate, and the initial dial staying cancellable without holding the\ncache lock.\n\nThe session supervisor is covered too: settings go out on stream creation,\nan EOF renews the stream and resends them, a reconnect cancels a blocked\nsettings write, release unblocks a stuck send and joins the goroutine,\nstartup succeeds or fails exactly once, route retirement closes sessions,\npending references protect an endpoint that is still initializing, and a\nstopped client rejects route and session work.\n\nTestCMClearIdleRpcClients is dropped: it read the client cache map without\nthe lock, which the race detector reports, and the idle reaper is now\ncovered by TestCMIdleReapClosesOutsideCacheLock. The package-wide RPC\nclient stub stays for now; the tests that still consume it are migrated in\na later commit.\n\n* fix(golang): map gRPC RESOURCE_EXHAUSTED to the SDK throttling code\n\nA throttled RPC surfaces as a transport level RESOURCE_EXHAUSTED status\nthat callers cannot distinguish from any other failure, so the producer\nretried it immediately instead of backing off. Normalize it at the client\nmanager boundary, for unary calls and for the ReceiveMessage stream, into\nthe SDK throttling code 42900 while keeping the original gRPC status\nreachable through errors.Is and errors.As. Every other error object is\nreturned unchanged, and the public ErrRpcStatus keeps its fields: the\nwrapper is private, and AsErrRpcStatus now uses errors.As, which also\nfixes it giving up on an error wrapped more than once.\n\nWith the boundary normalizing throttling, the producer can treat protocol\nand transport throttling alike and back off for both, on a timer the\ncaller\u0027s context can cancel, and it checks the context before spending an\nattempt.\n\nTestCMTelemetry asserted that a nil stream is not an error; Telemetry now\nreports one rather than handing a nil stream to callers that send on it.\n\n* test(golang): cover throttling mapping and finish the local mock migration\n\nAdd the error mapping matrix: RESOURCE_EXHAUSTED becomes the SDK throttling\ncode with the gRPC cause still reachable, while every other code, EOF and\ncancellation come back as the same object. Cover the producer backing off\nfor protocol and transport throttling alike, a backoff the caller can\ncancel, and other errors retrying without one.\n\nAlso finish moving the tests off the package-wide RPC client stub and the\nshared mock singletons, which made it impossible for any test to use a real\nconnection, and assert that the client manager normalizes throttling for\nevery unary call and for the ReceiveMessage stream, passes a telemetry\nstream through untouched, and reports a normalized creation failure.\n\n* test(golang): add a half-open TCP integration test\n\nDrive a real producer against a loopback gRPC server behind a TCP proxy\nthat keeps reading in both directions and discards the bytes, so an\nestablished connection goes black without the FIN or RST that a half-open\nconnection never delivers.\n\nOnce the send path works, the proxy blackholes it and the test asserts that\nafter two heartbeat deadlines a send succeeds within 40s on a newly\naccepted connection, that settings are resynced there, and that nothing\nclosed the old transport before those two deadlines. Recovery takes about\n26s locally, with the producer limited to a single attempt and a 3s request\ntimeout so retries cannot mask the result.\n\n---------\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "fc4b90bdb144c62556f35d59ad7a6fbce30c1092",
      "tree": "21460b9043318cf827f3a9afe6b71cab83dfa013",
      "parents": [
        "fc088d4a536af5e67281fea41b7911f10d1e8262"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Wed Sep 16 14:04:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 16 14:04:37 2026 +0800"
      },
      "message": "[C#] Align half-open gRPC recovery with Java (#1371)\n\n* fix(csharp): recover half-open gRPC connections\n\nAlign heartbeat-driven transport recovery and telemetry renewal with Java\nto avoid repeated timeouts on half-open connections. Guard lifecycle\ntransitions and normalize transport throttling failures.\n\nReference implementation: https://github.com/apache/rocketmq-clients/pull/1310\nJava commit: 9fe1449d19449b41442aa3a97ab168ed6b5bd6b1\n\nValidation: net8.0/net10.0 builds and formatting checks passed;\n226 tests passed in each of three full-suite runs.\n\nBREAKING CHANGE: Custom IClientManager implementations must add\nReconnect(Endpoints); custom IRpcClient implementations must add State\nand ResetTransport().\n\n* fix(csharp): use codespell-compatible recovery test names\n\nRename local telemetry variables to pass CodeSpell 2.1.0 without changing\ntest behavior or weakening spelling checks.\n\n* fix(csharp): make recovery tests deterministic across CI runners\n\nUse fresh metadata for each recovery heartbeat to avoid accumulating\ncaller headers beyond server limits. Hold the first transport reset until\nall contenders finish instead of relying on thread-pool timing.\n\n---------\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "fc088d4a536af5e67281fea41b7911f10d1e8262",
      "tree": "0f986da221cd9b60c24e8b44f33b3cd04b53ac32",
      "parents": [
        "07697f757928bed507dcc7c7ec07e7cc7ded417d"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Tue Sep 15 17:02:24 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 15 17:02:24 2026 +0800"
      },
      "message": "test(nodejs): use a fixed consumer group in the simple consumer integration test (#1376)\n\nSimpleConsumer#should receive success generated a random consumer group on every\nrun (nodejs-unittest-group-${randomUUID()}). RocketMQ 5.5.1\u0027s proxy resolves\nsubscription groups with a plain table lookup\n(LocalMetadataService#getSubscriptionGroupConfig -\u003e getSubscriptionGroupTable().get())\ninstead of the auto-creating findSubscriptionGroupConfig, so an unknown group\nmakes the proxy reject the client telemetry stream with \"group not found\" and\nstartup() never resolves - the test hangs until the runner times out.\n\nUse the shared fixed group already used by the other cases in this file, so the\ngroup can be pre-created on the broker. The random tag is kept, so the assertions\nstill only match the messages produced by this run.\n\nVerified against a live RocketMQ 5.5.1 broker (proxy :8081): integration suite\n12/12 (index, Producer 6, SimpleConsumer 4, ProducerRecall 1), where the random\ngroup previously hung the run."
    },
    {
      "commit": "07697f757928bed507dcc7c7ec07e7cc7ded417d",
      "tree": "670c4707b8b899121dd618cc70bfcd4563c92f4e",
      "parents": [
        "8b3bb96c686c55db30228f9fbeb19200008df4e5"
      ],
      "author": {
        "name": "zhouli11",
        "email": "04081337@163.com",
        "time": "Mon Sep 14 14:24:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 14 14:24:17 2026 +0800"
      },
      "message": "Update version to 5.1.2, Support LiteSimpleConsumer and fix some bugs for RocketMQ python SDK. (#1372)"
    },
    {
      "commit": "8b3bb96c686c55db30228f9fbeb19200008df4e5",
      "tree": "100c4ccb698de44d8900972836a4d79d1fd7500e",
      "parents": [
        "17677fe1aaa168aa49e921fcfdf66b3cb9b9300b"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Mon Sep 07 13:49:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 13:49:39 2026 +0800"
      },
      "message": "enhancement(nodejs): bump version to 1.0.8 (#1364)"
    },
    {
      "commit": "17677fe1aaa168aa49e921fcfdf66b3cb9b9300b",
      "tree": "d6f2d93c8aecddf71b1b4cc0f6ff5883d9735efa",
      "parents": [
        "0ffab3521a85d44fbddb809c906fd3a7d1e3b0fb"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Fri Sep 04 14:30:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 04 14:30:39 2026 +0800"
      },
      "message": "[ISSUE #1362] [C#] Fix typo in csharp/LICENSE: \"(properties)\" -\u003e \"(i)\" (#1363)\n\nRestore the standard Apache License 2.0 wording in the \"control\"\ndefinition (line 18). The corrupted \"(properties)\" was inherited from\nthe apache/rocketmq LICENSE prior to its 2021 fix (#2600)."
    },
    {
      "commit": "0ffab3521a85d44fbddb809c906fd3a7d1e3b0fb",
      "tree": "ac405a7ac1984cf95cb1c33a213afa318bc4ef58",
      "parents": [
        "666dfbceb39a95bf2d6b6f612bb944bf5b499f2e"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Mon Aug 31 09:51:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 09:51:23 2026 +0800"
      },
      "message": "fix(nodejs): drain inflight receives and cached messages on PushConsumer shutdown (#1353)\n\n- Wait for inflight receive requests (bounded by requestTimeout +\n  longPollingTimeout) after dropping process queues\n- Wait until every cached message is consumed and settled before\n  aborting queues and the consume service\n- Keep a 1s buffer for ack/changeInvisibleDuration callbacks"
    },
    {
      "commit": "666dfbceb39a95bf2d6b6f612bb944bf5b499f2e",
      "tree": "42502f1064bb15467f723b27499e8fc1524cc9ea",
      "parents": [
        "6e2185bb638b639663bda240cf119804a595e099"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Fri Aug 28 15:49:51 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 28 15:49:51 2026 +0800"
      },
      "message": "fix(nodejs): floor seconds when constructing protobuf Duration (#1352)\n\n- createDuration(): Math.floor(ms / 1000) for the int64 seconds field\n- log the swallowed exception in ProcessQueue ack/changeInvisibleDuration retries\n- ConsumeResultSuspend.of() rejects non-integer milliseconds\n- add unit tests for createDuration and ConsumeResultSuspend"
    },
    {
      "commit": "6e2185bb638b639663bda240cf119804a595e099",
      "tree": "80b7aaa29d7439b69d07c65e2a1281bb3a957749",
      "parents": [
        "da8271b572b41b627bcbbdfb5b3310c0c5e4736b"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Wed Aug 26 20:02:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 26 20:02:41 2026 +0800"
      },
      "message": "[maven-release-plugin] prepare release java-5.2.2 (#1349)"
    },
    {
      "commit": "da8271b572b41b627bcbbdfb5b3310c0c5e4736b",
      "tree": "c079fe9fdd5ff6b8f4c41e0828e5461a1ad7f9c9",
      "parents": [
        "ccc0d4fcc848eed66636757a8a70565fce6d4eca"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Mon Aug 17 10:39:21 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 17 10:39:21 2026 +0800"
      },
      "message": "[ISSUE #1334] [C++] Fix PushConsumer teardown crash and add explicit shutdown() (#1336)"
    },
    {
      "commit": "ccc0d4fcc848eed66636757a8a70565fce6d4eca",
      "tree": "281e3d9ef3939291dd107118f270a571c9d32a05",
      "parents": [
        "3a8ec615c08a18d93adf564a64de37afd0cdc270"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Mon Aug 17 10:38:57 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 17 10:38:57 2026 +0800"
      },
      "message": "[ISSUE #1335] [C++] Bound the synchronous producer paths with the request timeout (#1337)"
    },
    {
      "commit": "3a8ec615c08a18d93adf564a64de37afd0cdc270",
      "tree": "6f1073d552bcfcd42add5dd6e2ab0b586d8d86e7",
      "parents": [
        "f790a484f8e9124ada52ed20be73bc5c4f2e7758"
      ],
      "author": {
        "name": "Liu Shengzhong",
        "email": "szliu0927@gmail.com",
        "time": "Tue Aug 11 14:21:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 14:21:30 2026 +0800"
      },
      "message": "[Go] Re-check isCacheFull() on backoff expiry to avoid cache overflow (#1328)"
    },
    {
      "commit": "f790a484f8e9124ada52ed20be73bc5c4f2e7758",
      "tree": "194ed2395ecfff4c7eab9fd56aaaaf603da4b8f8",
      "parents": [
        "d463e6400e9819f95a944fa086877336d2e6aad8"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Mon Aug 10 15:07:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 15:07:43 2026 +0800"
      },
      "message": "[Go] Fix round-robin load balancer always selecting the same queue (#1324)\n\n* [Go] Fix round-robin load balancer always selecting the same queue\n\nIn TakeMessageQueues, the index was computed as `next+1` (constant)\ninstead of `next+i` (loop-varying), causing every loop iteration to\nexamine the same message queue. This defeats the round-robin intent\nand prevents proper load distribution across brokers.\n\n* [Go] Fix int32/int type mismatch in load balancer index calculation\n\n---------\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "d463e6400e9819f95a944fa086877336d2e6aad8",
      "tree": "73e54801a6a22b40b7dadc55bd8d2edd2b96f0a4",
      "parents": [
        "9abb7f39ce9f74b41873a4f5253ab82af052d7a7"
      ],
      "author": {
        "name": "qianye",
        "email": "wuxingcan.wxc@alibaba-inc.com",
        "time": "Fri Aug 07 16:17:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 07 16:17:36 2026 +0800"
      },
      "message": "[ISSUE# 1321] [Java] Preserve attempt ID until messages are received (#1322)"
    },
    {
      "commit": "9abb7f39ce9f74b41873a4f5253ab82af052d7a7",
      "tree": "d3ef2a515ed1709445148021bf50bda87f5c8e5f",
      "parents": [
        "9fe1449d19449b41442aa3a97ab168ed6b5bd6b1"
      ],
      "author": {
        "name": "qianye",
        "email": "wuxingcan.wxc@alibaba-inc.com",
        "time": "Thu Aug 06 20:57:28 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 06 20:57:28 2026 +0800"
      },
      "message": "[ISSUE #1318] [Java] Support opt-in virtual threads (#1319)"
    },
    {
      "commit": "9fe1449d19449b41442aa3a97ab168ed6b5bd6b1",
      "tree": "d39045ba9db37f9af064d1061c67b82c9b7699da",
      "parents": [
        "54471119387ad64a19f930164e64d9b30e1acd57"
      ],
      "author": {
        "name": "qianye",
        "email": "wuxingcan.wxc@alibaba-inc.com",
        "time": "Wed Jul 29 14:10:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 29 14:10:37 2026 +0800"
      },
      "message": "[ISSUE #1309] [Java] Improve gRPC transport resilience (#1310)"
    },
    {
      "commit": "54471119387ad64a19f930164e64d9b30e1acd57",
      "tree": "1f565e02a38cc66e001cea79746ca1e74a1718f3",
      "parents": [
        "5939e374500b4b1572acd23979a61a5f6426f876"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Wed Jul 29 11:32:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 29 11:32:10 2026 +0800"
      },
      "message": "feature(golang): support LiteSimpleConsumer (#1314)\n\n- Add LiteSimpleConsumer interface and implementation with SubscribeLite/UnSubscribeLite/GetLiteTopicSet\n- Extract liteSubscriptionManager shared by lite push/simple consumers\n- Carry LiteTopic in Ack and ChangeInvisibleDuration requests for lite simple consumer\n- Filter topic route to a single readable master queue for lite simple consumer\n- Report actual client type in heartbeat instead of hardcoded SIMPLE_CONSUMER"
    },
    {
      "commit": "5939e374500b4b1572acd23979a61a5f6426f876",
      "tree": "98ab24c82bf71dc5ae281bffda052641dc9ef319",
      "parents": [
        "3180b68cf0f908f29cd2162c0ddf645adae6b0a6"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Thu Jul 23 13:45:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 23 13:45:31 2026 +0800"
      },
      "message": "[Go] Fix resource leaks on client close (#1305)\n\n1. ClientManager shutdown: call shutdown() instead of UnRegisterClient()\n   in GracefulStop to stop background goroutines and close RPC connections\n   (regression from #235 which made ClientManager per-client but forgot\n   to add shutdown call).\n\n2. Telemetry session cleanup: release all sessions in GracefulStop before\n   shutting down the client manager to properly close gRPC streams.\n\n3. release() nil check: guard against nil observer when telemetry\n   connection failed during startup.\n\n4. Per-client metrics isolation: use view.NewMeter() to give each client\n   its own Meter, Measures, Views, and Exporter. On client close, the\n   Meter is stopped and views are unregistered, preventing metrics\n   cardinality explosion from accumulated client_id tag values.\n   The client_id tag is preserved in exported metric data.\n\n5. Fix meter lifecycle: call Start() before Register() to avoid deadlock,\n   and register/unregister the exporter with the per-client Meter so\n   metrics are actually exported.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "3180b68cf0f908f29cd2162c0ddf645adae6b0a6",
      "tree": "3c364d3a5d0379188496e9f3763570836715b208",
      "parents": [
        "47c2a64028cd2f83457e00d081461ef13355f60a"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Mon Jul 13 17:29:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 13 17:29:05 2026 +0800"
      },
      "message": "fix: add CODECOV_ACTION_KEY token and upgrade actions in golang coverage workflow (#1302)"
    },
    {
      "commit": "47c2a64028cd2f83457e00d081461ef13355f60a",
      "tree": "249a7544695c10476945d756781b3c7d2ed2b287",
      "parents": [
        "41b65fa4dc8a59d6caa8f36e3ed3edaa1e91b627"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Fri Jul 10 11:47:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 10 11:47:43 2026 +0800"
      },
      "message": "[C++] Fix thread safety bugs and add comprehensive unit tests (#1301)\n\n* [C++] Fix thread safety bugs in TelemetryBidiReactor and ClientManager\n* [C++] Add comprehensive unit tests for base, client, and rocketmq modules"
    },
    {
      "commit": "41b65fa4dc8a59d6caa8f36e3ed3edaa1e91b627",
      "tree": "fdd69153395eddcad6893580b08697886fc8d9c9",
      "parents": [
        "9c9ce3c3467ae6754228aac0bb3fc815dd00c506"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Fri Jul 10 11:01:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 10 11:01:29 2026 +0800"
      },
      "message": "[C++] Update public API and simplify client lifecycle state machine (#1300)"
    },
    {
      "commit": "9c9ce3c3467ae6754228aac0bb3fc815dd00c506",
      "tree": "771c320f77e42527ea8cad9aa1218da3f904d987",
      "parents": [
        "42a965cab34230120112478e4765599a27c17b6e"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Thu Jul 09 20:54:54 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 09 20:54:54 2026 +0800"
      },
      "message": "[C++] Add CMake install/uninstall support and enable tests in CI (#1297)"
    },
    {
      "commit": "42a965cab34230120112478e4765599a27c17b6e",
      "tree": "a7198f3d5f4c7786c932edaceb01dc5fdab27e80",
      "parents": [
        "315f98eb894ba95bdad19ea312bd9088fe2e2f15"
      ],
      "author": {
        "name": "Drizzle",
        "email": "464473306@qq.com",
        "time": "Mon Jul 06 19:45:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 06 19:45:01 2026 +0800"
      },
      "message": "feat(consumer): implement LitePushConsumer with FIFO and standard consume services (#1294)\n\n- Add LitePushConsumerImpl extending PushConsumer for lightweight message consumption\n- Implement LiteFifoConsumeService with liteTopic-based grouping and suspend support\n- Implement LiteStandardConsumeService with local retry via eraseFifoMessage\n- Refactor ConsumeResult from enum to class-based design with ConsumeResultSuspend extension\n- Optimize FifoConsumeService: add parameter validation, improve Map grouping logic\n- Enhance ProcessQueue: add FIFO message discard/erase methods with local retry\n- Align LitePushConsumerBuilder with Java client: implement maxCacheMessageCount,\n  maxCacheMessageSizeInBytes, consumptionThreadCount configurations\n- Add unit tests for LiteFifoConsumeService, ConsumeResult, and LitePushConsumerBuilder\n- Update MessageView to support liteTopic field for lite consumer routing\n\nCo-authored-by: drizzle.zk \u003cdrizzle.zk@alibaba-inc.com\u003e"
    },
    {
      "commit": "315f98eb894ba95bdad19ea312bd9088fe2e2f15",
      "tree": "83835771863d62f2352a9e622418717c3a2cc15c",
      "parents": [
        "d4de689eff6060db9b326d8a94ea43f04c03bdf9"
      ],
      "author": {
        "name": "ymwneu",
        "email": "ymwneu@126.com",
        "time": "Mon Jul 06 10:23:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 06 10:23:37 2026 +0800"
      },
      "message": "[Java] Record consumegroup when consumeMessage (#1290)"
    },
    {
      "commit": "d4de689eff6060db9b326d8a94ea43f04c03bdf9",
      "tree": "ba8e4842b2427f3b7a52983688d638409a27d08e",
      "parents": [
        "f038a53433fa5f96fe2b3a9c584ab76482aa9dba"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Wed Jul 01 13:51:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 01 13:51:37 2026 +0800"
      },
      "message": "[Go] Fix LitePushConsumer.WrapReceiveMessageRequest using wrong AutoRenew value (#1291)\n\n* fix(go): remove redundant WrapReceiveMessageRequest override in LitePushConsumer\n\n- Remove duplicated WrapReceiveMessageRequest from defaultLitePushConsumer,\n  delegate to embedded *defaultPushConsumer which correctly sets AutoRenew\u003dtrue\n  and includes FilterExpression\n- Drop unused imports: uuid, durationpb\n- Fix test assertion: AutoRenew should be true for lite push consumer\n\n* fix(go): remove redundant WrapReceiveMessageRequest tests for LitePushConsumer\n\n- Delete TestLitePushConsumer_WrapReceiveMessageRequest (delegates to\n  parent, already covered by TestDefaultPushConsumer_WrapReceiveMessageRequest)\n- Rename TestDefaultLitePushConsumer_Wraps to\n  TestDefaultLitePushConsumer_WrapHeartbeatRequest, keep only the\n  LitePushConsumer-specific ClientType assertion"
    },
    {
      "commit": "f038a53433fa5f96fe2b3a9c584ab76482aa9dba",
      "tree": "a75708f06a9b33bebb3d609f95dea239f5c0b8d5",
      "parents": [
        "3d8e99f378a6c6e37bf58accd59a1f6e736a1580"
      ],
      "author": {
        "name": "Yim",
        "email": "yiyan.lu@me.com",
        "time": "Wed Jun 24 14:50:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 24 14:50:45 2026 +0800"
      },
      "message": "[Go] Support offset option for lite topic subscriptions (#1285)\n\nAdd OffsetOption helpers and pass optional offset options through SyncLiteSubscriptionRequest when subscribing to lite topics."
    },
    {
      "commit": "3d8e99f378a6c6e37bf58accd59a1f6e736a1580",
      "tree": "4799ed67d6b0b1a185e498d9f1fd920a557e7646",
      "parents": [
        "eb6fe0bd267b2d9a910cab1e6d4dcddfde61a17e"
      ],
      "author": {
        "name": "JYZ",
        "email": "31824316+imjyz@users.noreply.github.com",
        "time": "Tue Jun 23 11:44:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 23 11:44:09 2026 +0800"
      },
      "message": "[Java] Support client properties for observability and management (#1237)"
    },
    {
      "commit": "eb6fe0bd267b2d9a910cab1e6d4dcddfde61a17e",
      "tree": "d1ab2931c6e1584bd4423c0f154dabf2e9963263",
      "parents": [
        "37cbdf6000d608ce215202a15eda3deca08300cb"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Tue Jun 23 11:00:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 23 11:00:06 2026 +0800"
      },
      "message": "[Java] Build rocketmq-proto from submodule instead of depending on Maven Central (#1287)"
    },
    {
      "commit": "37cbdf6000d608ce215202a15eda3deca08300cb",
      "tree": "199bcf9cadf1bfbb19e00443488cdf43d3b5f9f5",
      "parents": [
        "5ef95b88f0119dd644c4d3f6d87c58036c9ecb23"
      ],
      "author": {
        "name": "rongtong",
        "email": "jinrongtong5@163.com",
        "time": "Wed Jun 17 14:09:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 14:09:16 2026 +0800"
      },
      "message": "Prepare C# SDK 5.2.1 release (#1283)"
    },
    {
      "commit": "5ef95b88f0119dd644c4d3f6d87c58036c9ecb23",
      "tree": "25527cf81a5a2e3b92651aedbce9f439c3151963",
      "parents": [
        "471044f0860b90a19f01c4c665c6286455c8f04e"
      ],
      "author": {
        "name": "rongtong",
        "email": "jinrongtong5@163.com",
        "time": "Wed Jun 17 14:09:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 17 14:09:01 2026 +0800"
      },
      "message": "Prepare Go SDK 5.1.4 release (#1282)"
    },
    {
      "commit": "471044f0860b90a19f01c4c665c6286455c8f04e",
      "tree": "d363bf7b552568cc744af24c272329177680a79d",
      "parents": [
        "7448aa1cb7ab6cc3f19a65a2942ac28cb871113b"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Tue Jun 16 20:50:07 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 16 20:50:07 2026 +0800"
      },
      "message": "[maven-release-plugin] prepare release java-5.2.1 (#1278)"
    },
    {
      "commit": "7448aa1cb7ab6cc3f19a65a2942ac28cb871113b",
      "tree": "fca2cfa760638cc4e6b81cf1d7ddaa2cd42662cd",
      "parents": [
        "882c5bed416a4fccad9ab959bc4862ff8ccb0978"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Mon Jun 15 11:02:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 15 11:02:03 2026 +0800"
      },
      "message": "[Go] Fix data race in receiveMessage for push and simple consumers (#1275)\n\nThe err and resps variables were shared between the main goroutine\nand a spawned goroutine without synchronization, causing a data race\ndetectable by Go\u0027s race detector. The goroutine wrote to both\nvariables while the select handler read them concurrently.\n\nMove resps and err into the goroutine as local variables, and pass\nresults back through a typed channel (receiveResult struct) instead.\nThis also fixes push_consumer.go not signaling the done channel on\nnon-EOF errors, which previously caused it to wait for context\ntimeout instead of returning the actual error immediately.\n\nAffected:\n- golang/push_consumer.go: receiveMessage()\n- golang/simple_consumer.go: receiveMessage()\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "882c5bed416a4fccad9ab959bc4862ff8ccb0978",
      "tree": "5dc85466323cc22e34c823834d6db01879d4cda9",
      "parents": [
        "47d0a47cb9ef300e166f27fec9bd892f47efd63c"
      ],
      "author": {
        "name": "ZM",
        "email": "49428979+AllenZMC@users.noreply.github.com",
        "time": "Mon Jun 15 11:01:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 15 11:01:40 2026 +0800"
      },
      "message": "[Golang] fix(process_queue.go): correct log format verbs in receiveMessage error logging (#1253)\n\n* Update process_queue.go\n\n* fix log fmt"
    },
    {
      "commit": "47d0a47cb9ef300e166f27fec9bd892f47efd63c",
      "tree": "1fe9145e9c3f772d129808e795d2315e3aa2461c",
      "parents": [
        "f17e6dff2938b9c4b5a9514e5acfae2dfa88fd16"
      ],
      "author": {
        "name": "Drizzle",
        "email": "464473306@qq.com",
        "time": "Fri Jun 12 15:00:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 15:00:17 2026 +0800"
      },
      "message": "Add lite consumer sub all liteTopic (#1274)\n\nCo-authored-by: drizzle.zk \u003cdrizzle.zk@alibaba-inc.com\u003e"
    },
    {
      "commit": "f17e6dff2938b9c4b5a9514e5acfae2dfa88fd16",
      "tree": "8640a63bb82cfee487324759dc506c77c9a9a0d6",
      "parents": [
        "9713aafb08107804aaf689622557414acfad2875"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Fri Jun 12 10:31:25 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 10:31:25 2026 +0800"
      },
      "message": "[Go] Fix Commit/RollBack always returning nil in transaction (#1271)\n\nThe Commit() and RollBack() methods in transactionImpl silently swallowed\nerrors from endTransaction: errors were only logged inside the Range\ncallback, and the caller always received nil, making it impossible to\ndetect a failed commit or rollback.\n\nWhat changed:\n- Capture the error from the Range closure and return it to the caller.\n- Stop Range iteration on first error (matching Java\u0027s fail-fast behavior).\n- Return an error when messageSendReceiptMap is empty, aligning with the\n  Java client\u0027s IllegalStateException (\"Transactional message has not been\n  sent yet\").\n\nAffected: golang/transaction.go Commit(), RollBack()\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "9713aafb08107804aaf689622557414acfad2875",
      "tree": "aba896fa10995109747b220aa2948a774fa6e8de",
      "parents": [
        "ec29fca80a9a6d2afe5af51c8f789e013221da7d"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Fri Jun 12 10:30:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 10:30:50 2026 +0800"
      },
      "message": "[Go] Fix double execution of telemetry command during recovery (#1270)\n\nWhen recovering from a telemetry stream error, _execute_server_telemetry_command\nwas called both inside the `if cs.recovering` block (on successful heartbeat)\nand again unconditionally after the block, causing the command to be executed\ntwice.\n\nRemove the call inside the recovering block since the response should be\nexecuted unconditionally once successfully received, regardless of recovery\nstate.\n\nAffected: client.go startUp()\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "ec29fca80a9a6d2afe5af51c8f789e013221da7d",
      "tree": "d8b1d01775f88cb8e9b44906adc7b5234494c694",
      "parents": [
        "c46bc3faa381a796b526205fbda0cb79130893f0"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Fri Jun 12 10:23:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 10:23:50 2026 +0800"
      },
      "message": "[Go] Fix inverted hook status in Ack/DLQ methods (#1269)\n\nThe messageHookPointsStatus was incorrectly initialized to ERROR and\nset to OK when the response code was not OK, which is the opposite\nof the intended behavior. This affected three locations:\n- push_consumer.go: Ack()\n- push_consumer.go: ForwardMessageToDeadLetterQueue()\n- simple_consumer.go: Ack()\n\nAlso set status to ERROR before early return on err !\u003d nil, so that\nthe hook always reports the correct status on failure.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "c46bc3faa381a796b526205fbda0cb79130893f0",
      "tree": "37ff2170c4e9561d37482a8289b6dbd8bda2fe96",
      "parents": [
        "061dd5031be452f229cf69612eb5af0b962b5337"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Thu Jun 11 15:40:47 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 11 15:40:47 2026 +0800"
      },
      "message": "[C#] Fix SetBody validation logic to correctly reject null and empty body (#1268)\n\nThe original condition `null !\u003d body || body.Length \u003d\u003d 0` had two bugs:\n- When body is null, it short-circuits to evaluating `body.Length`, causing\n  NullReferenceException instead of a proper ArgumentException.\n- When body is a non-null empty array (byte[0]), `null !\u003d body` is true,\n  so the empty body passes validation silently.\n\nFix to `null !\u003d body \u0026\u0026 body.Length \u003e 0`, consistent with the Java\nimplementation which uses `ArrayUtils.isNotEmpty(body)`.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "061dd5031be452f229cf69612eb5af0b962b5337",
      "tree": "b924768a11da321de16fd999707ada094c2c2225",
      "parents": [
        "e9521d5da81af9d11ef69fb3cda1393fd80c07f8"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Thu Jun 11 15:38:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 11 15:38:30 2026 +0800"
      },
      "message": "[C#] Fix missing return after InvalidReceiptHandle in AckMessage and ChangeInvisibleDuration (#1267)\n\nBoth methods in ProcessQueue.cs had a fall-through bug where the\nInvalidReceiptHandle branch called tcs.SetException() but did not return,\ncausing execution to continue into the subsequent \u0027if (statusCode !\u003d Code.Ok)\u0027\nblock. This resulted in an unnecessary call to AckMessageLater /\nChangeInvisibleDurationLater with an already-faulted TaskCompletionSource,\nwhich would throw an InvalidOperationException at runtime.\n\nAdd the missing \u0027return;\u0027 statements to match the behavior of the Java\nreference implementation, where each non-success branch explicitly returns\nafter resolving the future.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "e9521d5da81af9d11ef69fb3cda1393fd80c07f8",
      "tree": "921b21a48428a5025eea961e6d4433d3090d666a",
      "parents": [
        "bf4462c24b50a1f8f1f5b0180d2256d2b8cadedb"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Thu Jun 11 15:00:56 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 11 15:00:56 2026 +0800"
      },
      "message": "fix(golang): add missing return in SendAsync when producer is off (#1264)\n\nWhen the producer is not running, SendAsync invoked the callback with\nan error but did not return, causing the subsequent goroutine to also\nexecute. This resulted in the callback being called twice and a\ngoroutine leak.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "bf4462c24b50a1f8f1f5b0180d2256d2b8cadedb",
      "tree": "d8efbaba8dc2002b1c7cf5d7f5b6b657fba4a295",
      "parents": [
        "323fe20087f9637ea04b0f229582e0a8e8f30285"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Thu Jun 11 14:53:08 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 11 14:53:08 2026 +0800"
      },
      "message": "[Go] Fix missing return after retry scheduling in process_queue (#1265)\n\nIn ackMessage0, changeInvisibleDuration, and forwardToDeadLetterQueue0,\nwhen the response code is not OK, the *Later() retry function is called\nbut execution falls through to callback(nil), causing the message to be\nprematurely evicted from cache before the operation actually succeeds.\nThis can lead to message loss.\n\nAdd return statements after each *Later() call to prevent fallthrough,\nmatching the Java implementation\u0027s behavior where the future is only\nresolved on terminal states (success or abandoned).\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "323fe20087f9637ea04b0f229582e0a8e8f30285",
      "tree": "dda3b1e6c55a4f04f50c10f0b2118f84161cacef",
      "parents": [
        "913d5de8894231f657a8a4c555cc9704aed26584"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Thu Jun 11 14:47:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 11 14:47:48 2026 +0800"
      },
      "message": "[Go] Fix forwardToDeadLetterQueueLater incorrectly calling ackMessage instead of forwardToDeadLetterQueue (#1266)\n\nforwardToDeadLetterQueueLater was calling ackMessage0 and ackMessageLater\ninstead of forwardToDeadLetterQueue0 and forwardToDeadLetterQueueLater,\nwhich would cause messages destined for the dead letter queue to be\nsilently acknowledged and lost.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "913d5de8894231f657a8a4c555cc9704aed26584",
      "tree": "eb5bd9a046da936797e880f30cb7800795f3d54f",
      "parents": [
        "189d2d563cc315062bfa6858c89b557c111335c0"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Tue Jun 09 11:34:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 11:34:03 2026 +0800"
      },
      "message": "fix(ci): join git diff output to single line for GITHUB_OUTPUT (#1263)"
    },
    {
      "commit": "189d2d563cc315062bfa6858c89b557c111335c0",
      "tree": "fb81c678ce8dbabed0f91cc05f6e883a348f5703",
      "parents": [
        "446f3be20f70044de50b7e197b855395596ec820"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Tue Jun 09 11:13:45 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 11:13:45 2026 +0800"
      },
      "message": "fix(ci): fix paths-filter shallow clone failure and cpp coverage token (#1262)\n\n- Add fetch-depth: 2 to checkout so HEAD~1 is available for push events\n- Add CODECOV_ACTION_KEY token to cpp coverage upload (required for protected branches)\n- Migrate deprecated ::set-output to $GITHUB_OUTPUT"
    },
    {
      "commit": "446f3be20f70044de50b7e197b855395596ec820",
      "tree": "72f8e296733fe041eed63e5c5d9ba1c6bebeb3b6",
      "parents": [
        "039ee8570673e265f27bd91c78fbcf0782707d77"
      ],
      "author": {
        "name": "zynetYu",
        "email": "40459025+zynetYu@users.noreply.github.com",
        "time": "Tue Jun 09 10:53:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 10:53:39 2026 +0800"
      },
      "message": "[C#] Add .NET 10 support and fix build warnings (#1260)\n\nCo-authored-by: 张宇 \u003czhang.yu02@hinacom.com\u003e"
    },
    {
      "commit": "039ee8570673e265f27bd91c78fbcf0782707d77",
      "tree": "dc999ea61ca12f4df089003b28cb631ad254065e",
      "parents": [
        "77fdb6f75317470f2c6920d4c352557494b825bc"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Tue Jun 09 09:59:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 09:59:00 2026 +0800"
      },
      "message": "[C++] Upgrade Bazel 5.2.0 to 6.6.0, add Bazel CI, migrate coverage to CMake (#1261)"
    },
    {
      "commit": "77fdb6f75317470f2c6920d4c352557494b825bc",
      "tree": "96304d2f00a1000a1efd0849337f4ebd56c125e9",
      "parents": [
        "df8759f93c4d05ae3bc0c430a4e58a2e27dfb49a"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Jun 08 20:37:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 08 20:37:29 2026 +0800"
      },
      "message": "Bump protobufjs from 7.5.6 to 7.6.1 in /nodejs (#1254)\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "df8759f93c4d05ae3bc0c430a4e58a2e27dfb49a",
      "tree": "a4991665b874ccb8cde4cc5ca7bf67e9d8bcca83",
      "parents": [
        "f1df051ce390e0bbb2273a1330736eddb0a26c56"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Mon Jun 08 16:48:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 08 16:48:31 2026 +0800"
      },
      "message": "[C++] Fix critical correctness, thread safety, and memory management bugs (#1259)"
    },
    {
      "commit": "f1df051ce390e0bbb2273a1330736eddb0a26c56",
      "tree": "5bfac2152385d4a3d5bd6c8d521fa2ea5a2ae254",
      "parents": [
        "d35c2c2546001931612a75682685c339a98b76d5"
      ],
      "author": {
        "name": "lizhimins",
        "email": "707364882@qq.com",
        "time": "Mon Jun 08 10:27:46 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 08 10:27:46 2026 +0800"
      },
      "message": "[C++] Improve CMake build system, fix warnings, and restore cross-platform CI (#1257)"
    },
    {
      "commit": "d35c2c2546001931612a75682685c339a98b76d5",
      "tree": "ceb4f62088fa81b430b28cbd92b4cac715d03fa5",
      "parents": [
        "e9f2ae7d0e6307f3dd9dccb4afdf87fd5f7fbf4b"
      ],
      "author": {
        "name": "guyinyou",
        "email": "36399867+guyinyou@users.noreply.github.com",
        "time": "Tue Jun 02 22:12:47 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 02 22:12:47 2026 +0800"
      },
      "message": "fix(csharp): correct inverted condition in GetMacAddress to prevent ArgumentOutOfRangeException on macOS arm64 (#1255)\n\nThe ternary condition in Utilities.GetMacAddress() was inverted:\n- When MAC address length \u003c 6, it returned the short array\n- When MAC address length \u003e\u003d 6, it returned random bytes\n\nThis caused MessageIdGenerator to throw ArgumentOutOfRangeException\nwhen calling writer.Write(macAddress, 0, 6) with an array shorter\nthan 6 bytes, which occurs on macOS arm64 where some network\ninterfaces return MAC addresses less than 6 bytes.\n\nFixed by changing \u0027mac.Length \u003c 6\u0027 to \u0027mac.Length \u003e\u003d 6\u0027 so that\nreal MAC addresses are used when valid (\u003e\u003d6 bytes), and random\nbytes are used as fallback when too short.\n\nCo-authored-by: guyinyou \u003cguyinyou.gyy@alibaba-inc.com\u003e"
    },
    {
      "commit": "e9f2ae7d0e6307f3dd9dccb4afdf87fd5f7fbf4b",
      "tree": "6b5405dac02deeb40717f032a8de4be41d30347a",
      "parents": [
        "66b340d9a7568f2351e7a0dda5f041e90f971f65"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Fri May 22 15:21:52 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 22 15:21:52 2026 +0800"
      },
      "message": "feat(LitePushConsumer): support concurrent consumption for LitePushConsumer (#1248)\n\nIntroduce LiteStandardConsumeService to enable concurrent message\nconsumption for LiteConsumer, with local retry on failure via\neraseFifoMessage."
    },
    {
      "commit": "66b340d9a7568f2351e7a0dda5f041e90f971f65",
      "tree": "9299925d85c08eac660ae268a40104865ef19829",
      "parents": [
        "730a1723faf9f6c5619487deac870b5786db4c8c"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Wed May 20 15:36:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 20 15:36:00 2026 +0800"
      },
      "message": "[C++] Support priority message (#1241)"
    },
    {
      "commit": "730a1723faf9f6c5619487deac870b5786db4c8c",
      "tree": "168d1f765fb459e690d87855fd999ae7a08f8fce",
      "parents": [
        "ca77ac914fe98fc82320aa6c0d6a4f581c35421e"
      ],
      "author": {
        "name": "Drizzle",
        "email": "464473306@qq.com",
        "time": "Fri May 15 14:17:25 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 15 14:17:25 2026 +0800"
      },
      "message": "optimize the nodejs client (#1247)\n\n* update code about the nodejs client\n\n* update client version\n\n* update code for codespell\n\n---------\n\nCo-authored-by: drizzle.zk \u003cdrizzle.zk@alibaba-inc.com\u003e"
    },
    {
      "commit": "ca77ac914fe98fc82320aa6c0d6a4f581c35421e",
      "tree": "fa1d41cc3298a15358513a0942d44958cb512cf4",
      "parents": [
        "e5f73f51facde16a2c03a8def85971dd461b3856"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Thu May 14 14:44:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu May 14 14:44:01 2026 +0800"
      },
      "message": "fix(ClientImpl.java): broadcast SyncLiteSubscriptionRequest to all route endpoints (#1245)\n\nLiteSubscriptionManager#syncLiteSubscription previously only sent the\nrequest to the client\u0027s initial endpoint, causing lite subscription\nstate to be inconsistent across brokers in a multi-broker cluster.\nBroadcast the request to all route endpoints and aggregate the results.\nWiden ClientImpl#getTotalRouteEndpoints() visibility to public accordingly."
    },
    {
      "commit": "e5f73f51facde16a2c03a8def85971dd461b3856",
      "tree": "d82e558d5373d5b01d6caf0e2d30cbe313c89a48",
      "parents": [
        "9d026ed53a228ff65a8cef7365dd9be5d0f9adb1"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Thu May 14 10:03:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu May 14 10:03:03 2026 +0800"
      },
      "message": "Rust  support FIFO consume accelerator for push consumer, recalling timed/delay messages for Producer and Priority Message.It also supports the Lite Push Consumer. (#1227)\n\n* Support FIFO consume accelerator for Push consumer, recalling timed/delay messages for Producer and Priority Message\n\n* update format\n\n* update format\n\n* update format\n\n* update version\n\n* update version\n\n* update version\n\n* update version\n\n* fix test\n\n* update proto\n\n* update message type\n\n* add lite consumer\n\n* fix format\n\n* fix format\n\n* fix format\n\n* fix lite push consumer\n\n* fix format\n\n* fix lite consumer type\n\n* fix lite push consumer\n\n* fix format\n\n* fix lite push consumer\n\n* optimize logs\n\n* update lite push consumer\n\n* fix lite push consumer\n\n* fix lite_topic\n\n* fix format"
    },
    {
      "commit": "9d026ed53a228ff65a8cef7365dd9be5d0f9adb1",
      "tree": "fbea35c60bf66226dbf67a0833cc3b93b42bdf6a",
      "parents": [
        "6361fe312161ad32d4f79da48630f30ad7fb2bac"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Fri May 08 19:57:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 08 19:57:19 2026 +0800"
      },
      "message": "fix(client.go): nil pointer exception during close (#1243)\n\nAdd nil checks for `consumerService` and `clientManager` in the close flow to prevent nil pointer panics caused by uninitialized objects."
    },
    {
      "commit": "6361fe312161ad32d4f79da48630f30ad7fb2bac",
      "tree": "7442e2775f43c709b3934021661869a6e66881dd",
      "parents": [
        "a5b541c2bb392756b4b223058b1a8eec5e4179b3"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Thu May 07 14:46:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu May 07 14:46:27 2026 +0800"
      },
      "message": "refactor(log.go): unify log configuration default value management (#1239)\n\nExtract log configuration default values as constants and optimize environment variable reading logic."
    },
    {
      "commit": "a5b541c2bb392756b4b223058b1a8eec5e4179b3",
      "tree": "5a6ea074f97bc352d9bf60bb13e4bd489cb8e888",
      "parents": [
        "2ac0bdde1cbd5c1a83d5cd4153f158a31b2d8f48"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Thu May 07 11:46:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu May 07 11:46:41 2026 +0800"
      },
      "message": "fix(log.go): adjust log file size unit and enable local time (#1238)\n\nChange the default log file max size from bytes (1073741824) to MB (100), and enable local time recording (default is UTC) to improve log configuration readability and usability."
    },
    {
      "commit": "2ac0bdde1cbd5c1a83d5cd4153f158a31b2d8f48",
      "tree": "5c48ec8b3caec7278a03396beb68c4af83deb3c9",
      "parents": [
        "73c415b5d80ef290fed9a2bc194f24f6bd6ce6b0"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Wed May 06 14:52:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 06 14:52:29 2026 +0800"
      },
      "message": "The C# client supports producers in recalling timed and delayed messages, as well as sending priority messages. It also supports the Lite Push Consumer. (#1229)\n\n* C# Client supports Recalling timed/delay messages for Producer and Priority Message.\n\n* Update protos submodule to latest version\n\n* update md\n\n* add lite\n\n* fix LitePushConsumerExample.cs\n\n* fix lite push consumer"
    },
    {
      "commit": "73c415b5d80ef290fed9a2bc194f24f6bd6ce6b0",
      "tree": "33d5cacea61feec3cd39fe7f62c86cd40ccdde59",
      "parents": [
        "9cde19453360302111574dba227945005700105d"
      ],
      "author": {
        "name": "Quan",
        "email": "zsjperiod@foxmail.com",
        "time": "Wed Apr 29 13:50:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 29 13:50:32 2026 +0800"
      },
      "message": "fix(client.go): handle sync settings error during startup (#1235)\n\nWhen the client is not yet initialized and settings synchronization fails,\npropagate the error to startUp() method so it can return immediately instead\nof blocking forever waiting for settings. Also added startUpError field to\nthe client struct to store errors that occur during startup.\n\nChange-Id: I5c28c65922b81083ac20f70aec2d4091248572c2"
    },
    {
      "commit": "9cde19453360302111574dba227945005700105d",
      "tree": "ae16fca4d8e51261ee8e725e8b84dc8065c6360f",
      "parents": [
        "d71c6c53acdd773f695575f75284d9c1cce3fdd9"
      ],
      "author": {
        "name": "zhaohai",
        "email": "33314633+zhaohai666@users.noreply.github.com",
        "time": "Tue Apr 28 10:49:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 28 10:49:55 2026 +0800"
      },
      "message": "Go client supports Producer with recalling timed/delay messages and Priority Message. (#1231)\n\n* Go client supports Producer with recalling timed/delay messages and Priority Message.\n\n* Go client supports Producer with recalling timed/delay messages and Priority Message."
    }
  ],
  "next": "d71c6c53acdd773f695575f75284d9c1cce3fdd9"
}
