)]}'
{
  "log": [
    {
      "commit": "1d08b2b358db42af2232d17bbe7ccc2937a79bbb",
      "tree": "fb5c38513114acbffde5539174e4f123240023b7",
      "parents": [
        "7892883b419afd96455326a2a09888b2f26052c2"
      ],
      "author": {
        "name": "zhou zhuohan",
        "email": "843520313@qq.com",
        "time": "Tue Jul 21 15:50:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jul 21 15:50:55 2026 +0800"
      },
      "message": "[fix][client] Support nack, ackTimeout redelivery and dlq for chunked messages (#604)"
    },
    {
      "commit": "7892883b419afd96455326a2a09888b2f26052c2",
      "tree": "ff77610ca1b25a82d0fdfb3d9a305b904ccdb250",
      "parents": [
        "b4a6c20b8b00529e7972871825a460bdd7516c76"
      ],
      "author": {
        "name": "Matteo Merli",
        "email": "mmerli@apache.org",
        "time": "Mon Jul 20 01:52:33 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 20 16:52:33 2026 +0800"
      },
      "message": "Scalable Topics: producer end-to-end tests + run `pulsar::st` tests in CI (#603)"
    },
    {
      "commit": "b4a6c20b8b00529e7972871825a460bdd7516c76",
      "tree": "8910df096abfffa503f6d5803ecd98a6bbe8c60f",
      "parents": [
        "855c60d5886e4f17b56e72761aedb1795df75ab0"
      ],
      "author": {
        "name": "Matteo Merli",
        "email": "mmerli@apache.org",
        "time": "Thu Jul 16 08:31:14 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 16 08:31:14 2026 -0700"
      },
      "message": "Scalable Topics: `pulsar::st` producer — per-segment fan-out, key routing, MessageId (#601)\n\n* st: teach the classic client the segment:// topic domain\n\nThe per-segment producers of a scalable topic attach to its segment://\nbacking topics through the classic producer machinery, so the classic\nTopicName must understand the domain - while the classic user-facing API\nmust keep rejecting it (only the pulsar::st client may touch segment\ntopics). Ported from the Java client\u0027s TopicName/PulsarClientImpl changes.\n\n- TopicName: new TopicDomain::Segment. segment://\u003ctenant\u003e/\u003cns\u003e/\u003cparent\u003e/\n  \u003cdescriptor\u003e always parses as the new (cluster-less) format - the local\n  name contains a \u0027/\u0027, so the token-count heuristic must not mistake it for\n  a legacy V1 name - and requires the descriptor component. isPersistent()\n  is true for segment topics (they are the persistent backing topics of one\n  segment, matching Java); new isSegment() accessor. Classic\n  persistent/non-persistent parsing is unchanged, and topic:// (the\n  scalable-topic identity scheme) intentionally stays unparseable here -\n  the st client resolves it before this layer.\n\n- ClientImpl: every user-facing entry point (createProducerAsync, the\n  subscribe funnel, createReaderAsyncV2, createTableViewAsyncV2,\n  getPartitionsForTopicAsync) now rejects segment topics with\n  ResultInvalidTopicName and a message pointing at the pulsar::st API,\n  mirroring the Java client\u0027s scalable-domain check. The new\n  createSegmentProducerAsync() bypasses the rejection for lib/st (the\n  Java-parity escape hatch); consumer-side bypasses come with their phases.\n\n- tests/st/StTopicNameTest.cc: segment parse (fields, slashed local name,\n  roundtrip, persistent/segment flags, never partitioned), descriptor\n  requirement, classic-format regression, and broker-free rejection of\n  segment topics through the classic producer/subscribe/reader API.\n\nVerified: 74/74 pulsar-st-tests green; the classic TopicNameTest (16\ntests, broker-free) and pulsar-tests/pulsarShared builds stay green;\nclang-format-11 clean.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: MessageId implementation - segment-qualified ids\n\nThe scalable-topic MessageId, ported field-for-field from the Java client\u0027s\nMessageIdV5 so serialized ids interoperate between the two clients.\n\n- MessageIdImpl wraps the classic per-segment MessageId plus the segment it\n  belongs to (segmentId -1 \u003d the cross-segment sentinels), with the optional\n  sections the consumer side will fill later: a per-segment position vector\n  (cumulative-ack StreamConsumer ids), the parent topic:// identity, and\n  cross-topic vectors (namespace consumers). The producer path fills only\n  v4MessageId + segmentId. MessageIdFactory (the friend the public header\n  already declared) is how lib/st mints ids and reaches their state.\n\n- toByteArray()/fromByteArray() implement the MessageIdV5 wire layout\n  (big-endian: segmentId, classic-id bytes, position vector, parent topic\n  with -1-absent sentinel, multi-topic vector; trailing sections optional on\n  read). Malformed input returns an empty (falsy) id on the non-throwing\n  surface instead of throwing.\n\n- Ordering compares (segmentId, then classic id), matching MessageIdV5;\n  empty ids sort first and equal each other. operator\u003c\u003c renders\n  {segment\u003d..., id\u003d..., positions\u003d...}. std::hash combines the segment and\n  classic-id fields, completing the P6 unordered-container support.\n\n- earliest()/latest() wrap the classic sentinels with the no-segment marker.\n\ntests/st/StMessageIdTest.cc: sentinels, within/across-segment ordering,\nempty-id semantics, unordered_set usage, stream output, producer-path and\nfull-section byte roundtrips, malformed/truncated input, empty\nserialization. 83/83 pulsar-st-tests green; gcc-13 parity; clang-format-11\nclean.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: thread assignedBrokerUrl to per-segment producers (broker pinning)\n\nScalable-topics per-segment producers should connect straight to the\nDAG-provided owner broker instead of doing a fresh topic lookup. The\nconnection machinery already supports this (HandlerBase::grabCnx(url) -\u003e\ngetConnection -\u003e ClientImpl::connect), so this only threads an optional\nassignedBrokerUrl from createSegmentProducerAsync down to the initial\nconnect:\n\n- HandlerBase::start(assignedBrokerUrl) overload; start() delegates to it\n  with nullopt (grabCnx() is already grabCnx(std::nullopt), so existing\n  handlers are unaffected).\n- ProducerImpl stores assignedBrokerUrl_ and passes it to the initial\n  HandlerBase::start(); a defaulted trailing ctor param keeps every other\n  caller unchanged.\n- createSegmentProducerAsync / createProducerAsyncImpl / handleCreateProducer\n  thread the optional through (default nullopt; the public producer path is\n  unchanged).\n\n* st: producer seam — ProducerImplBase + ProducerCore forwarders\n\nDefine the impl side of the already-declared detail::ProducerCore so a real\nproducer can be wired behind it:\n\n- lib/st/ProducerImplBase.h: the abstract pulsar::st::ProducerImplBase the\n  core forwards to (six methods matching ProducerCore; matches the existing\n  forward-decl in detail/ProducerCore.h).\n- lib/st/ProducerCore.cc: out-of-line definitions of the six ProducerCore\n  methods, each a one-line forward to the impl. Required now that a producer\n  will actually construct a core (a PULSAR_PUBLIC class must not leave\n  exported methods undefined — cf. the Transaction/Windows-DLL fix).\n- ProducerCore.h: friend pulsar::st::ClientImpl so createProducerAsync can\n  mint a core from the impl pointer.\n\n* st: StProducerImpl — per-segment producer fan-out (slice 3)\n\nImplement the scalable-topics producer behind detail::ProducerCore, a port of\nthe Java v5 ScalableTopicProducer:\n\n- Owns one DagWatchSession per topic and one SegmentRouter. Per active segment,\n  a classic pulsar::Producer is created via createSegmentProducerAsync, pinned\n  to the DAG-provided owner broker, cached as its creation Future so concurrent\n  cold senders share one attempt.\n- sendAsync routes each OutgoingMessage by key (round-robin when keyless) to a\n  segment, publishes via the classic producer, and mints the returned id with\n  the segment id into a pulsar::st::MessageId. Route failure is terminal; a\n  sealed/terminated segment retries with backoff (\u003c\u003d10, min(100*(n+1),500)ms)\n  and re-routes onto the layout the DAG watch delivers.\n- Layout changes retire producers for departed segments; exclusive access modes\n  eagerly attach (and fail create() up front if the claim is refused), Shared\n  attaches lazily on first send.\n- lastSequenceId maxes ready producers over the configured initial; flush awaits\n  the in-flight send snapshot; close is idempotent (dag watch + all producers).\n\nCorrectness details baked in from the design review: per-segment config is built\nFRESH each time (ProducerConfiguration\u0027s copy ctor shares its impl); the current\nlayout is a never-null default (route yields ResultServiceUnitNotReady, not a\nnull deref); access modes are mapped by NAME (the st and classic enums differ in\nvalue); a transactional send fails with ResultOperationNotSupported (never\nasserts); the in-flight entry is inserted before dispatch (warm sends complete\nsynchronously); the layout listener captures a weak_ptr (no ownership cycle).\n\nNo per-segment dispatch chain is needed — st::Future fires listeners in FIFO\nregistration order, so same-segment sends dispatch in call order for free; a\nFutureTest locks that guarantee in. StClientImpl::createProducerAsync now builds\na real producer (the not-supported stub and its test are gone).\n\n* st: broker-free StProducerImpl unit tests\n\nCover the pure, connection-independent logic through a small friend accessor:\n\n- Per-segment config isolation — the regression guard for the shallow\n  ProducerConfiguration copy: building a second segment\u0027s config must not rename\n  or re-mark the first (fresh config per segment).\n- Access-mode mapping by name — st and classic ProducerAccessMode enums differ\n  in numeric value, so WaitForExclusive / ExclusiveWithFencing must not be cast.\n- Segment-gone classification — TopicTerminated / AlreadyClosed retry;\n  ServiceUnitNotReady and ConnectError do not (no retry-loop on a transient\n  routing miss).\n- Minted MessageId carries the real segment id.\n\n* st: take send-path Promise by const-ref (clang-tidy performance)\n\ndispatchSend/handleSegmentFailure took the user\u0027s Promise by value but only\ncapture-copy it into their continuation lambdas — const-ref silences\nperformance-unnecessary-value-param (the lambdas still capture their own copy).\n\n* st: clang-format the producer changes for clang-format-11\n\nManual edits to lib/ClientImpl.cc (the broker-pin threading) and the include\norder in ProducerCore.cc were not clang-format-11 clean. CI\u0027s Formatting Check\npins clang-format 11, while the local toolchain is 18 and differs on lambda\nwrapping and include ordering. Reformat only the touched regions.\n\n* st: avoid GCC 13 stringop-overflow false positive in MessageId serialization\n\nThe Alpine x86_64 release build (GCC 13.2.1, musl, -Werror) rejects putBytes:\n`out.insert(out.end(), p, p + n)` from a cast const std::byte* range trips\n-Wstringop-overflow\u003d — GCC loses the destination size through the inlined\nvector _M_range_insert / uninitialized_copy chain and reports a size-0 write.\nThe code is correct; this is a known GCC 13 false positive on vector::insert\nfrom a pointer range.\n\nAppend via resize + memcpy instead: resize gives the analyzer a concrete\ndestination size and sidesteps the flagged insert path entirely. The 9\nStMessageIdTest serialization round-trips still pass; the fixed TU compiles\nclean under the Alpine release flags.\n\n* st: address review — TLS broker address and weak retry-timer capture\n\nBoth from @BewareMyPower\u0027s review of the per-segment producer:\n\n- Pin the segment producer to the broker address that matches how this client\n  connects: `useTls() ? brokerUrlTls : brokerUrl`, the same choice the classic\n  BinaryProtoLookupService makes. Previously it always took the plaintext URL,\n  so a TLS client would have been pinned to the wrong address. When the DAG does\n  not advertise the address we need, the pin is left unset and the normal\n  segment:// lookup resolves it.\n\n- Capture a weak_ptr (not shared_from_this) in the send-retry backoff timer.\n  closeAsync() does not cancel these timers, so a strong capture kept the\n  producer alive until the backoff elapsed; now the producer can be destroyed\n  and a retry that outlives it fails the send with ResultAlreadyClosed instead\n  of resurrecting it.\n\n---------\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e"
    },
    {
      "commit": "855c60d5886e4f17b56e72761aedb1795df75ab0",
      "tree": "139335b4861b5e00a4938bcd476c67a00996b007",
      "parents": [
        "9c6a84226751d28589739067cb2307806b438c24"
      ],
      "author": {
        "name": "zhou zhuohan",
        "email": "843520313@qq.com",
        "time": "Mon Jul 13 21:57:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 13 21:57:33 2026 +0800"
      },
      "message": "[improve] Refactor processMessageChunk to handle ack holes and out-of-order chunks (#587)\n\nMaster Issue: https://github.com/apache/pulsar/pull/13627\n\nRelated Issue: apache/pulsar#21070 and apache/pulsar#21101\n\n### Motivation\n\napache/pulsar#21070 and apache/pulsar#21101 fixed two critical issues in the Java client\u0027s chunked message \nhandling:\n\n1. **Unable to reassemble chunked messages after redeliver**: When a chunked message is redelivered \n   (e.g., due to broker unload or reconnect), the consumer receives duplicated chunks. The old \n   code could not handle this correctly:\n   - For duplicated first chunk (chunkId\u003d0): the old context was not properly cleaned up and restarted, \n     causing the message to never be assembled.\n   - For duplicated middle chunks: the chunk would be rejected (since chunkId ≤ lastChunkedMessageId), \n     and the old code would discard the context entirely, making the message unrecoverable.\n\n2. **Ack holes caused by corrupted or orphaned chunks**: When a different producer reuses the same uuid \n   (corrupted chunk scenario), or when chunk context is discarded due to gap/expiration, the stale cached \n   chunks or the incoming corrupted chunks were never acknowledged. This causes the broker subscription \n   cursor to get stuck, leading to message backlog accumulation that never drains — even after all \n   logically valid messages have been consumed and acknowledged.\n\nThese PRs added logic to distinguish between redeliver (same messageId) and corruption (different \nmessageId), allowing the consumer to correctly restart chunk assembly on redeliver while acking stale \nchunks on corruption to prevent ack holes.\n\nThe C++ client had the same issues. This PR ports the equivalent logic to ensure consistent behavior \nacross all client implementations.\n\n**Note**: Currently, after a chunked message is assembled, the ackTimeout and nack logic only tracks/handles \nthe last chunk message (i.e., the final messageId of the assembled message). This means if ackTimeout or \nnack triggers a redeliver, only the last chunk entry is redelivered rather than all chunk entries. This \nlimitation needs to be addressed in a follow-up PR.\n\n### Modifications\n\n**Core logic changes in `ConsumerImpl.cc` (`processMessageChunk`)**:\n\n- **Part 1 (chunkId \u003d\u003d 0)**: When receiving a duplicated first chunk for a uuid that already has an \n  incomplete context, detect whether it\u0027s a redeliver (same messageId in cache) or corruption (different \n  messageId). For redeliver: remove old context and restart assembling. For corruption: ack all cached \n  chunks to avoid ack holes, then restart.\n\n- **Part 3 (duplicated middle chunk)**: When receiving a chunk with chunkId ≤ lastChunkedMessageId, \n  detect whether it\u0027s a redeliver or corruption. For redeliver: simply discard the duplicate and continue \n  waiting for the next expected chunk. For corruption: ack the corrupted chunk to avoid ack holes.\n\n- **Part 3 (gap chunk)**: When receiving a chunk that skips expected sequence numbers, ack the chunk if \n  it has expired to avoid ack holes.\n\n- **Removed `trackMessage` calls for discarded chunks**: The old code called `trackMessage(messageId)` \n  for orphaned/invalid chunks (Part 2 and old Part 3), which would add the single chunk entry to the \n  `UnAckedMessageTracker`. When ackTimeout triggered, it would redeliver only that single chunk entry — \n  but this is pointless because the consumer still cannot assemble a complete chunked message from a \n  single chunk, and the redelivered chunk would just enter the same discard path again in an infinite loop.\n\n- Added `LOG_WARN` and `LOG_INFO` for observability across all scenarios.\n\n- Added detailed comments explaining each part of the chunk processing logic with examples.\n\n**Test changes in `MessageChunkingTest.cc`**:\n\n- Added `testResendChunkMessagesWithoutAckHole`: Verifies that resending the first chunk (chunkId\u003d0) \n  allows correct reassembly without ack holes.\n\n- Added `testResendChunkMessages`: Verifies interleaved chunk resends across multiple uuids assemble \n  correctly.\n\n- Added `testResendChunkWithAckHoleMessages`: Verifies duplicated middle chunks are filtered correctly \n  and chunk gaps cause context cleanup.\n\n- Refactored existing tests to reuse the `sendSingleChunk` helper function for better readability."
    },
    {
      "commit": "9c6a84226751d28589739067cb2307806b438c24",
      "tree": "a2e296db9abcb2d9e51740eddd874b2c0c4d3f3d",
      "parents": [
        "983435aae4c2bf9164d9e775f6a11576ad44561d"
      ],
      "author": {
        "name": "zhou zhuohan",
        "email": "843520313@qq.com",
        "time": "Mon Jul 13 11:23:55 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jul 12 20:23:55 2026 -0700"
      },
      "message": "Fix CI workflow by updating docker/build-push-action to ASF allowlisted version (#602)"
    },
    {
      "commit": "983435aae4c2bf9164d9e775f6a11576ad44561d",
      "tree": "0b0c39e694a80978e959335cb03bd68e1826e4fb",
      "parents": [
        "cff0cf4b21c1c65ffe5bc88d5a8c12cb99d494cf"
      ],
      "author": {
        "name": "Matteo Merli",
        "email": "mmerli@apache.org",
        "time": "Thu Jul 09 00:50:22 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 09 15:50:22 2026 +0800"
      },
      "message": "Scalable Topics: `pulsar::st` implementation — protocol foundation (DAG watch, layout, routing) (#600)"
    },
    {
      "commit": "cff0cf4b21c1c65ffe5bc88d5a8c12cb99d494cf",
      "tree": "48d39bed15b53835e4daa719222a267010881176",
      "parents": [
        "0711b3171a9ead96ad8b564d54f92735dfad856d"
      ],
      "author": {
        "name": "Matteo Merli",
        "email": "mmerli@apache.org",
        "time": "Wed Jul 01 07:23:31 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jul 01 07:23:31 2026 -0700"
      },
      "message": "Scalable Topics: new typed C++ SDK (`pulsar::st`) — API definition (#598)\n\n* Scalable Topics: typed C++ SDK public API (pulsar::st)\n\nHeader-only public API for the scalable-topics SDK under a new pulsar::st\nnamespace (PIP-460/468/483): client, producers, the three consumer modes,\ntransactions, schemas (reflect-cpp JSON/Avro and protobuf), and the\nExpected\u003cT\u003e/Future\u003cT\u003e result types, plus examples under examples/st.\n\nAPI definition only -- no lib/st implementation or C API yet. The new API\nrequires C++20; the rest of the client stays C++17.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* Fix CI: clang-format the st sources; make reflect-cpp optional\n\n- Apply clang-format-11 to the new pulsar::st headers and examples (the\n  Formatting Check uses clang-format 11; local 18 formats differently).\n- examples/CMakeLists.txt: build the four dependency-free st samples\n  unconditionally and add the reflect-cpp JSON sample only when reflectcpp\n  is found (find_package CONFIG QUIET instead of REQUIRED), so configure no\n  longer fails where reflect-cpp is absent (e.g. the CodeQL/Analyze job).\n- vcpkg.json: drop the reflectcpp dependency for now; it returns with the\n  lib/st implementation that actually exercises the JSON/Avro schemas.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* Fix CI: give st config-struct fields default member initializers\n\nGCC\u0027s -Wmissing-field-initializers (-Wextra, and the build is -Werror) fires\non a partial designated-initializer such as\n.deadLetterPolicy({.maxRedeliverCount \u003d 5}) for every omitted member that\nlacks a default member initializer. clang does not warn, so this was missed\nlocally. Give every optional field in the user-facing policy/ack/DLQ structs\nan \u0027\u003d std::nullopt\u0027 NSDMI so designated-init of any subset is warning-clean.\nVerified with gcc:13 -Wextra -Werror against all four st examples.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: decode returns Expected\u003cT\u003e and takes std::span\u003cconst char\u003e\n\nAddresses PR review feedback on the Schema decode signature. The SerDe seam\nnow takes a std::span\u003cconst char\u003e instead of (const char*, size_t), and\nreturns Expected\u003cT\u003e instead of T -- so malformed bytes or an unset schema are\nerror values rather than a non-opt-in throw, consistent with the rest of the\nAPI. Message\u003cT\u003e::value() returns Expected\u003cT\u003e accordingly.\n\n- built-in numeric codecs report a short payload as ResultInvalidMessage;\n- the reflect-cpp JSON/Avro SerDes map a parse failure to an Error instead of\n  letting rfl\u0027s .value() throw;\n- the protobuf SerDe now checks ParseFromArray\u0027s result;\n- a custom SerDe may still return a plain T (infallible) -- it converts\n  implicitly to Expected\u003cT\u003e.\n\nencode keeps throwing on an unset schema (a configuration error). Examples\nupdated to check the decoded value. Verified with clang + gcc:13 (-Wextra\n-Werror) and clang-format-11.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* Revert \"st: decode returns Expected\u003cT\u003e and takes std::span\u003cconst char\u003e\"\n\nThis reverts commit 46d3f6d1fcbd63c031e8ce7ca1eb8ed48719c44c.\n\n* st: byte-buffer SerDe seam + zero-copy BytesView\n\nPer PR review on the Schema encode/decode signatures.\n\nSerDe seam (Schema\u003cT\u003e + JSON/Avro/protobuf factories):\n- encode writes into a caller-provided, reusable std::vector\u003cstd::byte\u003e\u0026 (no\n  per-message allocation) and returns Expected\u003cvoid\u003e;\n- decode takes std::span\u003cconst std::byte\u003e and returns Expected\u003cT\u003e, so malformed\n  input / an unset schema are error values rather than throws;\n- Bytes is now std::vector\u003cstd::byte\u003e.\n\nClient-facing API unchanged: Message\u003cT\u003e::value() still returns T (decode\nfailures are handled inside the SDK), Producer::send(const T\u0026) and the examples\nare as before; a rare encode error is stashed in the builder and surfaces from\nsend()/sendAsync().\n\nZero-copy bytes: new BytesView \u003d std::span\u003cconst std::byte\u003e. Schema\u003cBytesView\u003e\nis the zero-copy counterpart of Schema\u003cBytes\u003e -- Producer\u003cBytesView\u003e publishes\nthe caller\u0027s bytes without copying (the caller keeps them valid until the send\ncompletes) and Message\u003cBytesView\u003e::value() returns a view into the message\nbuffer. OutgoingMessage carries an optional non-owning view.\n\nVerified with clang + gcc:13 (-Wextra -Werror), clang-format-11, and a runtime\ncheck that decode returns a view at the same address.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: return std::string_view from string accessors\n\nPer PR review: the string accessors return views instead of owning\nreferences/copies, so the lib/st impl is not forced to store a std::string\nper field -- it can return a view into whatever it already holds.\n\n- consumer/producer topic() / subscription() / consumerName() / name() and\n  Message::topic() now return std::string_view (Message::topic() previously\n  copied); the detail::*Core declarations they forward to return string_view too.\n- Message::key() / producerName() / replicatedFrom() now return\n  std::optional\u003cstd::string_view\u003e.\n- Error::message() stays const std::string\u0026 (an Error is usually a temporary, so\n  auto-capturing a const ref copies safely whereas a view would dangle).\n\nReturned views are valid while the source object (message / consumer / producer)\nis alive. All within pulsar::st; the old API is untouched. Verified with clang +\ngcc:13 (-Wextra -Werror), static_asserts on the return types, and clang-format-11.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: serialize MessageId/Checkpoint as bytes, not std::string\n\ntoByteArray() returns std::vector\u003cstd::byte\u003e and fromByteArray() takes\nstd::span\u003cconst std::byte\u003e, instead of std::string -- byte-correct and\nconsistent with Bytes/BytesView. The round-trip stays implicit: a\nstd::vector\u003cstd::byte\u003e from toByteArray() converts to the span parameter.\nExample updated. All within pulsar::st.\n\nVerified with clang + gcc:13 (-Wextra -Werror) and clang-format-11.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: make property() a by-value sink (review item K1)\n\nproperty(const std::string\u0026 k, const std::string\u0026 v) becomes\nproperty(std::string k, std::string v) with insert_or_assign(std::move(k),\nstd::move(v)), across MessageBuilder, ProducerBuilder, and the three consumer\nbuilders -- consistent with the other by-value-sink setters (topic /\nsubscriptionName / etc.).\n\nVerified with clang + gcc:13 (-Wextra -Werror) and clang-format-11.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: fix await_suspend coroutine resume race (review B1)\n\nawait_suspend now returns bool and uses SharedState::addListenerOrReady, which\natomically registers the resume continuation or reports the result is already\navailable -- so the coroutine resumes via await_resume instead of being resumed\nfrom inside await_suspend (which could run/destroy the awaiter before it\nreturns). Verified with a co_await runtime test on clang + gcc:13.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: receive() does not surface decode errors -- doc fix (review B2)\n\nA message whose payload cannot be decoded is handled internally by the SDK and\nnever delivered, so decode is not a receive failure. Dropped it from the receive\nfailure lists on all three consumers and added a clarifying note.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: uppercase primitive schema names STRING/DOUBLE (review B4)\n\nMatch the existing client\u0027s canonical primitive names (lib/Schema.cc:\nSTRING/INT32/INT64/FLOAT/DOUBLE/BYTES); StringCodec/DoubleCodec used mixed-case\n\u0027String\u0027/\u0027Double\u0027. The name is sent to the broker.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: reset encodeError_ on a successful encode (review B5)\n\nMessageBuilder::value() now clears encodeError_ on success instead of leaving a\nprior failure sticky, so a later successful value() doesn\u0027t surface a stale\nerror at send()/sendAsync().\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: model event time as std::optional\u003cTimestamp\u003e (review B3)\n\nOutgoingMessage::eventTime and MessageCore::eventTime() are now\nstd::optional\u003cTimestamp\u003e instead of an int64 epoch-ms with a 0\u003dunset sentinel,\nso an event time of exactly the Unix epoch is no longer indistinguishable from\nunset. The int64 epoch-ms is just the wire encoding (converted in lib/st);\nMessageBuilder::eventTime and Message::eventTime() simplify accordingly.\n\nVerified epoch !\u003d unset at runtime on clang + gcc:13.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: add CheckpointConsumer::consumerName() (review G2)\n\nParity with Stream/QueueConsumer -- the consumerName config field and builder\nsetter existed, but the getter did not, so the name could be set but not read.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: [[nodiscard]] on MessageId/Checkpoint serialization + sentinels (review P3)\n\ntoByteArray() / fromByteArray() / earliest() / latest() return values that must\nnot be silently discarded.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: document Message::properties() view lifetime (review P4)\n\nIt returns a reference into the message, like the other view-returning getters.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: model deliverAt as std::optional\u003cTimestamp\u003e too (review B3 follow-on)\n\nOutgoingMessage::deliverAt is now std::optional\u003cTimestamp\u003e (was int64 epoch-ms\nwith 0\u003dimmediate), matching eventTime; deliverAfter/deliverAt set it directly,\nand the now-unused toEpochMs helper is removed. Verified on clang + gcc:13.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: model publishTime as Timestamp, not int64 epoch-ms\n\nMessageCore::publishTime() now returns Timestamp (was int64_t publishTimeMs());\nMessage::publishTime() forwards it directly. Consistent with the eventTime /\ndeliverAt Timestamp modeling; the int64 epoch-ms is just the wire encoding\n(converted in lib/st).\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: producer review items P1, G3, Q1\n\n- P1: rename Producer::name() -\u003e producerName() (+ ProducerCore), consistent\n  with Message::producerName() and the producerName builder setter.\n- G3: add MessageBuilder::replicationClusters() setter for the previously\n  unreachable OutgoingMessage::replicationClusters field.\n- Q1: drop the \u0027ordering key\u0027 framing from the message-key docs -- it is a\n  routing / partition key; ordering is provided by the StreamConsumer.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: add float/int8/int16 primitive codecs (review G4/Q4)\n\nFloatCodec (FLOAT, big-endian IEEE-754), Int8Codec (INT8), Int16Codec (INT16),\nwired into the default Schema\u003cT\u003e ctor; canonical uppercase names match the\nexisting client. Round-trip verified on clang + gcc:13.\n\nbool is NOT added: the existing pulsar::SchemaType enum has no BOOLEAN value\n(Java has it at 5; the C++ port skipped it), and adding it would mean touching\nthe old API. Deferred pending a decision on extending the old enum.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: Message::data() returns BytesView, not const char* + size()\n\nMessageCore::data() / Message\u003cT\u003e::data() now return std::span\u003cconst std::byte\u003e\n(BytesView), carrying pointer and length together; the separate size() accessor\nis removed (use data().size()), and Message\u003cT\u003e::value() simplifies accordingly.\nConsistent with the Bytes/BytesView byte modeling. Verified on clang + gcc:13.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: group loose client settings into policies by scope (review Q3)\n\nPulsarClientBuilder drops the top-level ioThreads / messageListenerThreads /\nmemoryLimit / listenerName setters. Grouped by scope:\n- listenerName -\u003e ConnectionPolicy\n- ioThreads + messageListenerThreads -\u003e new ThreadPolicy\n- memoryLimit -\u003e new MemoryPolicy\nwith threadPolicy() / memoryPolicy() builder setters. Verified on clang + gcc:13.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: MessageCore optional accessors, drop hasX() bools\n\nMessageCore::key() / producerName() / replicatedFrom() now return\nstd::optional\u003cstd::string_view\u003e directly instead of a paired hasX() bool +\nstring_view accessor -- the optional carries the present/absent signal.\nMessage\u003cT\u003e\u0027s wrappers collapse to direct forwards. Verified on clang + gcc:13.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: receive cores take std::chrono::milliseconds, not int64_t timeoutMs\n\ndetail::*Core receiveAsync/receiveMultiAsync now take std::chrono::milliseconds\n(matching the public receive() signatures), so the public methods forward the\ntyped timeout directly instead of calling .count(). \u003ccstdint\u003e swapped for\n\u003cchrono\u003e in the cores (int64_t was only the timeout). Verified on clang + gcc:13.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: OutgoingMessage key -\u003e std::optional\u003cstd::string\u003e\n\nReplace the bool hasKey + std::string key pair on OutgoingMessage with a\nsingle std::optional\u003cstd::string\u003e key, mirroring the read-side\nMessageCore::key() -\u003e std::optional\u003cstd::string_view\u003e. nullopt means no\nrouting key. MessageBuilder::key() now just assigns the optional.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: OutgoingMessage sequenceId -\u003e std::optional\u003cint64_t\u003e\n\nDrop the -1 sentinel on OutgoingMessage::sequenceId in favor of\nstd::optional\u003cint64_t\u003e; unset means auto-assign. Avoids a custom in-band\nencoding of \u0027no explicit sequence id\u0027. MessageBuilder::sequenceId() just\nassigns the optional.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: Producer::lastSequenceId() -\u003e std::optional\u003cint64_t\u003e\n\nDrop the -1 sentinel on the read side too: lastSequenceId() now returns\nstd::nullopt when nothing has been published yet, instead of -1. Updates\ndetail::ProducerCore to match.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P2 - guard rfl encode() against throwing\n\nrfl::{json,avro}::write() can throw, which would escape encode()\u0027s\nExpected\u003cvoid\u003e non-throwing contract. Wrap the body in try/catch and\nreport failures as unexpected(ResultInvalidMessage, ...), mirroring the\nexisting decode() guard. info() (schema derivation) has no error channel\nand stays off the non-throwing path; document that on the factories.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P5 - warn about fire-and-forget + BytesView dangling\n\nA zero-copy Schema\u003cBytesView\u003e send publishes the viewed bytes directly, so\nthey must outlive the send. The returned future is the only completion\nsignal; discarding it (fire-and-forget) leaves no safe point to free the\nbytes. Document this on sendAsync().\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P6 - std::hash\u003cMessageId\u003e + Checkpoint operator\u003c\u003c\n\nMessageId could not be used as a key in unordered_map/unordered_set. Add a\nstd::hash\u003cMessageId\u003e specialization (operator() defined in lib/st, consistent\nwith operator\u003d\u003d: equal ids hash equal); befriend it so it can read the impl.\n\nGive Checkpoint a hidden-friend operator\u003c\u003c mirroring MessageId\u0027s, so both\nopaque position types stream the same way for logging/debugging.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P7 - explicitly default copy/move on handles\n\nPulsarClient, Producer, the three consumers, and Transaction are\nshared-state handles that must stay cheaply copyable and movable. They\nrelied on implicitly-generated special members, which a later user-declared\ndestructor would silently suppress (turning the move into a copy or deleting\nit). Declare copy/move \u003d default explicitly on all six to lock in handle\nvalue semantics and make the intent visible.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P8 - thenApply supports void-returning and move-only mappers\n\nthenApply assumed a non-void, copyable mapper: it called setValue(f(...))\n(ill-formed when f returns void) and moved f straight into the std::function\nlistener (ill-formed when f is move-only, since std::function requires a\ncopyable target).\n\nBranch on the result type with if constexpr - a void mapper runs and then\ncompletes the Future\u003cvoid\u003e via setSuccess() - and hold f in a shared_ptr so\nthe copyable listener can carry a move-only mapper. Verified at runtime\n(normal, void, move-only, and error-propagation paths) on clang and gcc.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P9 - fail the future when a Promise is abandoned\n\nA detail::Promise dropped without being completed left its SharedState\nforever pending, so Future::get() (and listeners / co_await) blocked\nindefinitely. Add a Guard shared by every copy of a Promise: when the last\ncopy is destroyed it completes the state with an error (ResultUnknownError,\n\"promise abandoned before completion\") unless something already fulfilled\nit. complete() is idempotent, so a normally-completed promise is unaffected,\nand destroying one copy among several does not trip it. Verified at runtime\n(single/copied/void abandonment, partial-copy safety, completed no-op) on\nclang and gcc.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P10 - note negativeAckRedeliveryDelay is inert on StreamConsumer\n\nAckPolicy::negativeAckRedeliveryDelay only applies to a QueueConsumer. A\nStreamConsumer acknowledges cumulatively and has no negative-ack path, so\nthe field is silently ignored there. Document that on the StreamConsumer\nconfig field and the ackPolicy() setter.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P11 - document the invalid/rejected default consumer target\n\nThe topic-vs-namespace target is a bool + two strings, so the POD config can\nrepresent invalid combinations the type system does not prevent - including\nthe default-constructed value (single-topic mode with an empty topic).\nDocument that such states (no target, or missing subscriptionName) are\nrejected by create()/createAsync() with an Error, and that fields not\nselected by useNamespace are ignored. (A variant target could make these\nunrepresentable, but that diverges from the POD-config + designated-init\npattern used across the API.)\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P12 - rename ClientCore::createCheckpointAsync -\u003e createCheckpointConsumerAsync\n\nMatch the create\u003cThing\u003eAsync naming of its siblings (createProducerAsync)\nand the CheckpointConsumer type it returns. Internal detail rename; no public\nAPI change.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: P13 - rvalue overloads for Expected monadic ops and value_or\n\nvalue_or, and_then, transform, and or_else were const\u0026-only: they copied the\ncontained value into the continuation, and value_or/and_then/transform would\nnot even compile for a move-only T. Add \u0026\u0026-qualified overloads that move the\ncontained value (and forward the error by move), so a move-only or\nexpensive-to-copy T flows through the chain without a copy. value() and\noperator* already had ref-qualified overloads. Verified at runtime with a\nmove-only payload (unique_ptr) on clang and gcc, plus an lvalue regression\npass.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n* st: review nits N1-N7\n\nN1 Expected operator*/operator-\u003e are not UB on an error: operator* is\n   noexcept + std::get so it terminates; operator-\u003e returns nullptr. Correct\n   the docs to say so.\nN2 Drop redundant unit prose (\"in milliseconds\"/\"in seconds\") from\n   std::chrono fields/params in Policies, Consumer (AckPolicy) and the\n   sendTimeout setter; the type already states the unit. (ProducerConfig\u0027s\n   int64 sendTimeoutMs keeps its \"milliseconds\" note - it is not a chrono type.)\nN3 decodeBigEndian: replace the dead `i \u003c data.size()` guard (all codecs\n   length-check first) with an assert of that precondition.\nN4 ProtobufNativeSchema: guard the size_t-\u003eint narrowing in encode/decode,\n   rejecting messages larger than INT_MAX instead of passing a wrapped size.\nN5 OutgoingMessage: one-line note for the usesView\u003c-\u003epayloadView invariant.\nN7 Wrap the SerDeFor concept in clang-format off/on so clang-format-11 stops\n   mangling the `{ expr } -\u003e Concept;` compound requirements.\nN6 Normalize config-struct field docs to the dominant /** */-before style\n   (OutgoingMessage, CheckpointConsumerConfig, Stream/QueueConsumerConfig);\n   enum-value ///\u003c trailing docs are left as-is.\n\nVerified: clang-format-11 clean; examples compile (clang); N3 runtime test\nand N4 (protobuf stub) pass on clang and gcc.\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e\n\n---------\n\nSigned-off-by: Matteo Merli \u003cmmerli@apache.org\u003e"
    },
    {
      "commit": "0711b3171a9ead96ad8b564d54f92735dfad856d",
      "tree": "f4e905b6a58d620aa2b2800828e3d74722961895",
      "parents": [
        "55e885c854718c89c98aab6cf6f3e52315c5d31e"
      ],
      "author": {
        "name": "Matteo Merli",
        "email": "mmerli@apache.org",
        "time": "Mon Jun 29 03:02:30 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 29 18:02:30 2026 +0800"
      },
      "message": "Use C++20-capable toolchains in the deb/rpm package build images (#599)"
    },
    {
      "commit": "55e885c854718c89c98aab6cf6f3e52315c5d31e",
      "tree": "da94a2971b5fec607d3c7c00df3c2a812cdb9738",
      "parents": [
        "334d1bc0fe997280529b7ff062e30239275f0c7b"
      ],
      "author": {
        "name": "zhou zhuohan",
        "email": "843520313@qq.com",
        "time": "Thu Jun 25 18:22:39 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 18:22:39 2026 +0800"
      },
      "message": "[feat] Add httpLookupAuthAllowRedirect option to forward auth credentials on HTTP lookup redirects (#588)"
    },
    {
      "commit": "334d1bc0fe997280529b7ff062e30239275f0c7b",
      "tree": "76378137d9fad2b55a1698d94dce5209e5b0d87a",
      "parents": [
        "05f8a6d16d10b2f0f76dbd82c944f4e0707a7d0a"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhangzhibiao@bigo.sg",
        "time": "Thu Jun 25 10:21:10 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 10:21:10 2026 +0800"
      },
      "message": "Fix disconnected C result handling (#590)"
    },
    {
      "commit": "05f8a6d16d10b2f0f76dbd82c944f4e0707a7d0a",
      "tree": "609aaa61869c9a4fb82153495a93ad2cf3cb25c6",
      "parents": [
        "0378140ec177ce0829d9d3e92390c5bfe7f35437"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhangzhibiao@bigo.sg",
        "time": "Thu Jun 25 10:20:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jun 25 10:20:50 2026 +0800"
      },
      "message": "Document custom logger lifetime (#593)"
    },
    {
      "commit": "0378140ec177ce0829d9d3e92390c5bfe7f35437",
      "tree": "d07167ac966de9ea931d42d9ea0fe7fc5f024e29",
      "parents": [
        "f2c0fecd388318d7a940cc1aabcd3adead7d5879"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Tue Jun 02 10:33:46 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 02 10:33:46 2026 +0800"
      },
      "message": "Fix release workflows (#586)"
    },
    {
      "commit": "f2c0fecd388318d7a940cc1aabcd3adead7d5879",
      "tree": "6786ac03b2cf27bbfc2245bd4db14e8403dde04b",
      "parents": [
        "0dab2ba7288264b29166a5f54acfed257169fa9c"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Jun 01 18:05:31 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 01 18:05:31 2026 +0800"
      },
      "message": "feat: expose replicated_from proto field to Message (#583)"
    },
    {
      "commit": "0dab2ba7288264b29166a5f54acfed257169fa9c",
      "tree": "5f17ac9d243b4a8a416314e3ca9644a6e4c61d2e",
      "parents": [
        "a169e10ca643ce5669d070f8df6fbed0c09d4f72"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Jun 01 18:05:18 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 01 18:05:18 2026 +0800"
      },
      "message": "chore: remove unnecessary WARN logs for send or receive timeouts (#584)"
    },
    {
      "commit": "a169e10ca643ce5669d070f8df6fbed0c09d4f72",
      "tree": "5e0acbe3f00b1bc64c77e648ba7e4d62c9842b4f",
      "parents": [
        "ce3dfa814fbc1aaddfe4f8c61f3b1d7954c99462"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri May 29 09:50:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 29 09:50:44 2026 +0800"
      },
      "message": "Fix macOS cross-architecture build on arm64 when target arch is x86_64 (#582)"
    },
    {
      "commit": "ce3dfa814fbc1aaddfe4f8c61f3b1d7954c99462",
      "tree": "21dc979761efee64aa10ca364953454ce18e759b",
      "parents": [
        "2ca2eacbb781280316249dc166212de6610d3b87"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu May 28 14:23:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu May 28 14:23:48 2026 +0800"
      },
      "message": "feat: add v2 APIs to create Consumer, Reader or TableView (#581)\n\n* feat: add v2 APIs to create Consumer, Reader or TableView\n\n* improve tests for other v2 methods\n\n* fix lint"
    },
    {
      "commit": "2ca2eacbb781280316249dc166212de6610d3b87",
      "tree": "1757b82f726dee10e4f572fd61cd1dd112a7ccf7",
      "parents": [
        "aedb9255748ceffd4720a56d44f316be30b080fc"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed May 27 12:10:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 27 12:10:37 2026 +0800"
      },
      "message": "feat: introduce a v2 createProducer API to carry error message when fail (#579)"
    },
    {
      "commit": "aedb9255748ceffd4720a56d44f316be30b080fc",
      "tree": "999587b47326fe9f1126971dd8a1ff45042077b4",
      "parents": [
        "3ea3ff19ca3c57b0cf185e30e8d115c48437da91"
      ],
      "author": {
        "name": "zhou zhuohan",
        "email": "843520313@qq.com",
        "time": "Tue May 26 20:28:46 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue May 26 20:28:46 2026 +0800"
      },
      "message": "[fix][client-cpp] Fix TypedMessageTest to use receiveAsync\u003cT\u003e template overload with decoder (#580)"
    },
    {
      "commit": "3ea3ff19ca3c57b0cf185e30e8d115c48437da91",
      "tree": "932158791e8cf598760c405c05978350adeef57b",
      "parents": [
        "7d1002ae4f203ac142a7ad8661c179cee2ffe6c8"
      ],
      "author": {
        "name": "Hideaki Oguni",
        "email": "22386882+izumo27@users.noreply.github.com",
        "time": "Tue May 26 21:25:52 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue May 26 20:25:52 2026 +0800"
      },
      "message": "[improve][client] Implement tls_client_auth for AuthOauth2  (#575)"
    },
    {
      "commit": "7d1002ae4f203ac142a7ad8661c179cee2ffe6c8",
      "tree": "d86c90ac2bc775021806543520996c35ca5d1076",
      "parents": [
        "0666b5c49d0a390d4e0080b3d22d9827974e7842"
      ],
      "author": {
        "name": "Baodi Shi",
        "email": "baodi@apache.org",
        "time": "Mon May 18 11:55:35 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 18 11:55:35 2026 +0800"
      },
      "message": "Fix consumer reconnect state after subscribe failure (#577)"
    },
    {
      "commit": "0666b5c49d0a390d4e0080b3d22d9827974e7842",
      "tree": "7b98373a731766c4f1fe9e4ac70c3522f8a7e504",
      "parents": [
        "ab39c37d00015d0a6c51b8e2ba08e15d7cab8cb1"
      ],
      "author": {
        "name": "Liu Zixian",
        "email": "zixian.liu@dolphindb.com",
        "time": "Wed May 13 10:36:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 13 10:36:22 2026 +0800"
      },
      "message": "[cleanup] remove unused openssl header (#574)"
    },
    {
      "commit": "ab39c37d00015d0a6c51b8e2ba08e15d7cab8cb1",
      "tree": "4b6dd84d1d231d980eff716bb7e704c4232ad0f4",
      "parents": [
        "0a9e01771b197f777c393093159c2911ec3629b0"
      ],
      "author": {
        "name": "David Warburton",
        "email": "david.warburton@gmail.com",
        "time": "Tue May 05 21:50:11 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 06 09:50:11 2026 +0800"
      },
      "message": "[fix][client-cpp] Restore pulsar/Version.h for the dev package (#572)"
    },
    {
      "commit": "0a9e01771b197f777c393093159c2911ec3629b0",
      "tree": "2d0e886b0ce607c51c0f4df89e7b14de46858b8e",
      "parents": [
        "f9995da210cd7b10141213f997cd76c3a9a5dfa7"
      ],
      "author": {
        "name": "dwang-qm",
        "email": "156144641+dwang-qm@users.noreply.github.com",
        "time": "Tue Apr 21 20:19:15 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 22 11:19:15 2026 +0800"
      },
      "message": "[fix][client-cpp] Fail producers immediately when topic is terminated (#567)"
    },
    {
      "commit": "f9995da210cd7b10141213f997cd76c3a9a5dfa7",
      "tree": "08dc50fd9eebb084403600231f87f13c98dad8f2",
      "parents": [
        "69afa1a800ec53659d68c1c7729d22f424d6813f"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Wed Apr 15 17:35:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 15 17:35:02 2026 +0800"
      },
      "message": "[fix][cpp-client] Pass seek error to callback when SEEK command fails (#549)"
    },
    {
      "commit": "69afa1a800ec53659d68c1c7729d22f424d6813f",
      "tree": "0cc960514ece922c6119ff9a097c4e334059a441",
      "parents": [
        "ff074bf87e7f2e44fc6c34ff04ea790523523997"
      ],
      "author": {
        "name": "Bhargav Kumar Konidena",
        "email": "Bhargavkonidena@users.noreply.github.com",
        "time": "Fri Apr 03 18:09:58 2026 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 03 20:39:58 2026 +0800"
      },
      "message": "[feat][client] Support null value messages (#563)"
    },
    {
      "commit": "ff074bf87e7f2e44fc6c34ff04ea790523523997",
      "tree": "3bec6bcf630d1b8d411d066ee651632076210654",
      "parents": [
        "e5afb63dc24d5ebccaf0ff5108106adc8d83bdcb"
      ],
      "author": {
        "name": "Daeho Ro",
        "email": "40587651+daeho-ro@users.noreply.github.com",
        "time": "Thu Apr 02 20:31:54 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 02 19:31:54 2026 +0800"
      },
      "message": "Fix modern boost cancel method without args (#561)"
    },
    {
      "commit": "e5afb63dc24d5ebccaf0ff5108106adc8d83bdcb",
      "tree": "059ef240469db0d9f6ab08ade2fb046c843db905",
      "parents": [
        "00c4daabc640cb56336776fed6e1f5c74c5f147d"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Apr 02 17:41:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 02 17:41:50 2026 +0800"
      },
      "message": "Fix broken CI due to token string not trimmed (#565)"
    },
    {
      "commit": "00c4daabc640cb56336776fed6e1f5c74c5f147d",
      "tree": "87b52a2d55ee51f83779da9039d8d1a8ca23a74a",
      "parents": [
        "03fe428bb520ecc5e7fe21979cccca1fde60642c"
      ],
      "author": {
        "name": "Daeho Ro",
        "email": "40587651+daeho-ro@users.noreply.github.com",
        "time": "Wed Apr 01 12:28:17 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 01 11:28:17 2026 +0800"
      },
      "message": "Fix apple build (#562)"
    },
    {
      "commit": "03fe428bb520ecc5e7fe21979cccca1fde60642c",
      "tree": "48ae79b8f8328e8f3ebb25bc0f978302ab48aaa5",
      "parents": [
        "fcde4857cec3045e72624a168029d6d84eb4c532"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Mar 23 23:30:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 23 08:30:33 2026 -0700"
      },
      "message": "Fix aarch64 build on Alpine (#558)\n\n* Fix aarch64 build on Alpine\n\n* fix workflow not run"
    },
    {
      "commit": "fcde4857cec3045e72624a168029d6d84eb4c532",
      "tree": "e6ff809fee6d400ff7502ec3904fabcfaff2ab1b",
      "parents": [
        "64fbda03c8de318d20a782e7016bd02779110671"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri Mar 20 12:40:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 20 12:40:17 2026 +0800"
      },
      "message": "Fix hasMessageAvailable will return true after seeking to a timestamp newer than the last message (#556)"
    },
    {
      "commit": "64fbda03c8de318d20a782e7016bd02779110671",
      "tree": "27e9ba70ef70376c1d87f85c6dccfd7782ab576a",
      "parents": [
        "1a39e5323a2ec07a10cb8dc8b9d4b1c1aea8d324"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Mar 19 16:01:21 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 19 16:01:21 2026 +0800"
      },
      "message": "Fix connection leak by request timers not cancelled in time (#555)\n\n* Fix connection leak by request timers not cancelled in time\n\n* fix\n\n* fix include style\n\n* revert consumer stats changes and speed up tests\n\n* abstract a common method to insert a request and add tests\n\n* remove duplicated emplace\n\n* remove unexpected error log"
    },
    {
      "commit": "1a39e5323a2ec07a10cb8dc8b9d4b1c1aea8d324",
      "tree": "6077491d8e5bfabe9d0a9a14d964b912c6f98d83",
      "parents": [
        "967529b79f8fae55902b679b7e2248ff8e8f98c3"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Tue Mar 17 19:58:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 17 19:58:04 2026 +0800"
      },
      "message": "[fix][client-cpp] Implement missing pulsar_message_set_schema_version in C API (#552)"
    },
    {
      "commit": "967529b79f8fae55902b679b7e2248ff8e8f98c3",
      "tree": "0df451bca2717f4e7f42e13f847ee658c446fdbe",
      "parents": [
        "40259cc7afb788ea4d27291f2df134a752c1a714"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Tue Mar 17 19:57:26 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 17 19:57:26 2026 +0800"
      },
      "message": "[fix][client-cpp] Fix Reader segfault when messageListenerThreads\u003d0 (#553)"
    },
    {
      "commit": "40259cc7afb788ea4d27291f2df134a752c1a714",
      "tree": "6793fc6002df8a8c491cc818886d179342a2d8d6",
      "parents": [
        "b3d2b58c0394160688dad15873e67cfa8eac349b"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Tue Mar 17 19:18:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 17 19:18:04 2026 +0800"
      },
      "message": "PIP-121: Implement AutoClusterFailover (#547)"
    },
    {
      "commit": "b3d2b58c0394160688dad15873e67cfa8eac349b",
      "tree": "1680d5a2050532738db0e784aeb5c8e1e216f76b",
      "parents": [
        "b47e63dcb21949a0ac7da18d2336a8b92d569cc6"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Mon Mar 16 10:21:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 16 10:21:19 2026 +0800"
      },
      "message": "[Test] Fix log after client close (#548)"
    },
    {
      "commit": "b47e63dcb21949a0ac7da18d2336a8b92d569cc6",
      "tree": "04729f438ab277e5735caaf1deb5cb7b7a071122",
      "parents": [
        "e80f65ef6db05eacda6ff02ca8fcba9963a38a93"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri Mar 13 14:49:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 13 14:49:04 2026 +0800"
      },
      "message": "PIP-121: Introduce ServiceInfoProvider to update service info dynamically (#541)"
    },
    {
      "commit": "e80f65ef6db05eacda6ff02ca8fcba9963a38a93",
      "tree": "b42e66a490b2c0fbb0dda00fb02e9ac442040bd8",
      "parents": [
        "23b60d1fe264fd48775fae7c7ebabae355d3c2a9"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Mar 12 17:58:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 12 17:58:29 2026 +0800"
      },
      "message": "Fix crash due to asio object lifetime and thread safety issue (#551)"
    },
    {
      "commit": "23b60d1fe264fd48775fae7c7ebabae355d3c2a9",
      "tree": "d06ad7e3e0d0bb28eec11540b56c9c9dcaf619b9",
      "parents": [
        "0c6a7c0a688409e6f2c4b066b48bdca24e5ec33b"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Thu Mar 05 22:29:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 05 22:29:13 2026 +0800"
      },
      "message": "Fix incorrect last sequence id when sending messages in batch (#546)\n\n"
    },
    {
      "commit": "0c6a7c0a688409e6f2c4b066b48bdca24e5ec33b",
      "tree": "a4521b44a05b5bcc873d5c6397d4e79c08b0c53a",
      "parents": [
        "e290658827ca7b835e5fe7570722605727cc67c5"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Thu Mar 05 00:31:02 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Mar 04 08:31:02 2026 -0800"
      },
      "message": "[Test][C++] Fix flaky ReaderTest.testAsyncRead (#545)\n\n* fix\n\n* format\n\n* revert test\n\n---------\n\nCo-authored-by: zhangzhibiao \u003czhangzhibiao@bigo.sg\u003e"
    },
    {
      "commit": "e290658827ca7b835e5fe7570722605727cc67c5",
      "tree": "46a1675ef202b10edf8c722ad6e185251e304edf",
      "parents": [
        "bda51d6ecf8eaeb79aecac9ae2ce3802866cea32"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Mar 04 21:48:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Mar 04 21:48:13 2026 +0800"
      },
      "message": "Fix clang tidy errors not detected as well as the errors (#544)\n\n"
    },
    {
      "commit": "bda51d6ecf8eaeb79aecac9ae2ce3802866cea32",
      "tree": "ad4a622217edc36870de529c1643acba1f42b4a3",
      "parents": [
        "11e32c6f2ff1f22d7a22ef68c3ddc6216df70512"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Wed Mar 04 15:40:09 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Mar 04 15:40:09 2026 +0800"
      },
      "message": "[feat][client-cpp] Add operation timeout configuration in milliseconds (#543)\n\n"
    },
    {
      "commit": "11e32c6f2ff1f22d7a22ef68c3ddc6216df70512",
      "tree": "6f8c2e8e913035e869fed10319d11c175e2314e1",
      "parents": [
        "070132b13e38d025673b053127537b53f1c4ff35"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Mar 04 10:51:24 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Mar 04 10:51:24 2026 +0800"
      },
      "message": "Bump dependencies to latest versions for CVEs (#540)\n\n"
    },
    {
      "commit": "070132b13e38d025673b053127537b53f1c4ff35",
      "tree": "a10cee5afe601a56e040832e490bc46e35fa6f79",
      "parents": [
        "2606df96d9e2dbcc90ec8374ea1d4d45c147d128"
      ],
      "author": {
        "name": "zhanglistar",
        "email": "zhanglinuxstar@gmail.com",
        "time": "Tue Mar 03 15:05:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 03 15:05:13 2026 +0800"
      },
      "message": " [improve][client] Enhance connection and timeout logging (#539)\n\n"
    },
    {
      "commit": "2606df96d9e2dbcc90ec8374ea1d4d45c147d128",
      "tree": "9ac253a0c7ddb8acceb3e1ac6f93d14de5c93eec",
      "parents": [
        "b3edc60c5ca46c1df7e0090f7e418a684fd21553"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri Feb 06 19:33:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Feb 06 19:33:16 2026 +0800"
      },
      "message": "Fix multi-topics consumer will crash if one internal consumer fails getBrokerConsumerStatsAsync (#538)\n\n"
    },
    {
      "commit": "b3edc60c5ca46c1df7e0090f7e418a684fd21553",
      "tree": "a790c4dd7add8cbb8a9b88c2e709e58f2e8a8585",
      "parents": [
        "0b893a1622aa7dd702d48afee33af321bb2c06dd"
      ],
      "author": {
        "name": "Andrew Rhoads",
        "email": "andrew.c.rhoads@gmail.com",
        "time": "Tue Feb 03 20:54:34 2026 -0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Feb 04 12:54:34 2026 +0800"
      },
      "message": "Fix use of deprecated Boost Asio API (#535)\n\nexpires_from_now is deprecated and it is now recommended to use expires_after"
    },
    {
      "commit": "0b893a1622aa7dd702d48afee33af321bb2c06dd",
      "tree": "47163beb736e3970ec8c132bd9f3e979d30aaceb",
      "parents": [
        "d040039e3a351056d0b3be31adbad4a0b72fee09"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri Jan 16 14:14:50 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jan 16 14:14:50 2026 +0800"
      },
      "message": "Fix the seek method could be blocked forever when subscribe RPC is slower than seek RPC (#533)\n\n"
    },
    {
      "commit": "d040039e3a351056d0b3be31adbad4a0b72fee09",
      "tree": "bac22fffed52c40724992756f90f1fcb915e292c",
      "parents": [
        "889a04bc71eb207ec064a8cec37709dd3b7bccdb"
      ],
      "author": {
        "name": "Ceyhun Can Ulker",
        "email": "ceyhuncanu@gmail.com",
        "time": "Wed Dec 17 05:08:57 2025 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 17 10:08:57 2025 +0800"
      },
      "message": "[improve][client] Add TLSv1.3 support (#529)\n\n"
    },
    {
      "commit": "889a04bc71eb207ec064a8cec37709dd3b7bccdb",
      "tree": "126df5764dca180ad044a1fa6cc55789b465f997",
      "parents": [
        "adf3c7c0f76702246a9306fc60924984c2d9042e"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Tue Dec 09 10:07:41 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 09 10:07:41 2025 +0800"
      },
      "message": "Support getting encryption context on a message (#526)\n\n"
    },
    {
      "commit": "adf3c7c0f76702246a9306fc60924984c2d9042e",
      "tree": "774b298a98edf3d0d888cd7b4fe582bb354590c4",
      "parents": [
        "c64e0e9635333cf74ebdcd12d77afcf2ecc9a01a"
      ],
      "author": {
        "name": "dann frazier",
        "email": "dann.frazier@chainguard.dev",
        "time": "Sun Dec 07 23:21:28 2025 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 08 14:21:28 2025 +0800"
      },
      "message": "ProtobufNativeSchema: convert abseil string_view to std::string (#527)\n\nThis resolves the following build failure using abseil-cpp 20250814.1"
    },
    {
      "commit": "c64e0e9635333cf74ebdcd12d77afcf2ecc9a01a",
      "tree": "776c8e0595e23fc8e39c1066c66ddfe97d545d4b",
      "parents": [
        "93f10ef76f4e2301472a0ec39ddad8287c1205ee"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Dec 03 20:07:35 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 03 20:07:35 2025 +0800"
      },
      "message": "Bump the C++ standard to 17 (#525)\n\n- Replace `boost::optional` with `std::optional`\n- Replace `boost::any` with `std::any`\n- Use `std::weak_from_this` to create a `weak_ptr` from a `shared_ptr`\n- Leverage initializers for if to simplify code"
    },
    {
      "commit": "93f10ef76f4e2301472a0ec39ddad8287c1205ee",
      "tree": "7ce659f57758a58062e195fc9d016acc8f34976e",
      "parents": [
        "a03eb9278bf96cbda42eb9e7dc1c73ee0b65ea3e"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Nov 19 17:04:59 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 19 17:04:59 2025 +0800"
      },
      "message": "Support get the producer name of a message (#524)\n\n"
    },
    {
      "commit": "a03eb9278bf96cbda42eb9e7dc1c73ee0b65ea3e",
      "tree": "c6bb71fa8d0982bb972dc8fc8bfff7f5c2b0c366",
      "parents": [
        "268aa4e2fdc621137a1a1fff9587ddd200bb0eda"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Nov 06 11:49:38 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Nov 06 11:49:38 2025 +0800"
      },
      "message": "Fix topic lookup segmentation fault after client is closed (#521)\n\n"
    },
    {
      "commit": "268aa4e2fdc621137a1a1fff9587ddd200bb0eda",
      "tree": "268aab12233043776ba45daccffbda6d1d559b6d",
      "parents": [
        "648b48be58f65a15f45d952986f3d9d5936f75a8"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Nov 05 18:58:52 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 05 18:58:52 2025 +0800"
      },
      "message": "Fix possible zombie consumer when closing after reconnection (#518)\n\n"
    },
    {
      "commit": "648b48be58f65a15f45d952986f3d9d5936f75a8",
      "tree": "d22ff7b4734bc966a9f4037e755778288dc67658",
      "parents": [
        "12471ec55099a51d0bcb9f551f83bb17a8358069"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Oct 27 15:20:28 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 27 15:20:28 2025 +0800"
      },
      "message": "Fix a null ACK grouping tracker can be accessed after consumer is closed (#517)\n\nFixes https://github.com/apache/pulsar-client-cpp/issues/516"
    },
    {
      "commit": "12471ec55099a51d0bcb9f551f83bb17a8358069",
      "tree": "f20c4e1ae92db517d6c730fcf91d9c0925679fe4",
      "parents": [
        "3be5267ef781b9a1928c009da1ac53dc60a12a35"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Oct 27 15:00:19 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 27 15:00:19 2025 +0800"
      },
      "message": "Fix APK package installation workflow (#515)\n\n* Fix wrong install directory for APK packages\n\n* Fix DESTDIR\n\n* Build libpulsarwithdeps.a"
    },
    {
      "commit": "3be5267ef781b9a1928c009da1ac53dc60a12a35",
      "tree": "4b0040e32e63f7383beec65fd0356de8f44919e1",
      "parents": [
        "2b84925b097d649091ca0160009cd5e3c1c50062"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri Oct 17 02:05:02 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 16 11:05:02 2025 -0700"
      },
      "message": "Replace Roaring64Map with unordered_set to unblock fat static library build issue (#514)\n\n"
    },
    {
      "commit": "2b84925b097d649091ca0160009cd5e3c1c50062",
      "tree": "2ff3defe27c04d3dc39884cce609a8ff7530b66b",
      "parents": [
        "386dedc47bde8c46fae1705afdf66e4b972c7447"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Oct 16 23:19:24 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 16 08:19:24 2025 -0700"
      },
      "message": "Fix flaky testHasMessageAvailableWhenCreated (#511)\n\n"
    },
    {
      "commit": "386dedc47bde8c46fae1705afdf66e4b972c7447",
      "tree": "e15c26e7ab37c4df6399b1ae8c5a9d3211e53d18",
      "parents": [
        "4366ffe7c96380da0357d5e7e148e4886d6700e0"
      ],
      "author": {
        "name": "Baodi Shi",
        "email": "baodi@apache.org",
        "time": "Thu Oct 16 21:44:04 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 16 21:44:04 2025 +0800"
      },
      "message": "Fix nullptr after listener consumer closed (#510)\n\n"
    },
    {
      "commit": "4366ffe7c96380da0357d5e7e148e4886d6700e0",
      "tree": "cc3b0160b108ef6628088851d2817e7362564675",
      "parents": [
        "5632b4b9107eed0911981d46054f445cbf80ebf3"
      ],
      "author": {
        "name": "Liu Zixian",
        "email": "hdu_sdlzx@163.com",
        "time": "Tue Oct 14 16:13:46 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 14 16:13:46 2025 +0800"
      },
      "message": "Update OpenSSL API (#509)\n\n"
    },
    {
      "commit": "5632b4b9107eed0911981d46054f445cbf80ebf3",
      "tree": "2b3b7d20654f5765f4384fe9bc637a73447ef0f1",
      "parents": [
        "e04b2a983057332f656b9a356c217f0c8db42039"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Oct 13 11:08:20 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 13 11:08:20 2025 +0800"
      },
      "message": "[improve] change RoutingMode default from UseSinglePartition to RoundRobinDistribution (#507)\n\n"
    },
    {
      "commit": "e04b2a983057332f656b9a356c217f0c8db42039",
      "tree": "e5c574b964d3e34c83c003cdfa2344ee52c6013c",
      "parents": [
        "f2f9f65683123cfcdcefff0dde669969a476b347"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri Oct 10 09:43:31 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 10 09:43:31 2025 +0800"
      },
      "message": "Use vcpkg to build debian packages (#506)\n\n"
    },
    {
      "commit": "f2f9f65683123cfcdcefff0dde669969a476b347",
      "tree": "0e4368222374aedd08601a02f140f06ba8fd0cbe",
      "parents": [
        "9f0b6fb40700131de080897ee69bbdfbcacc527a"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Sat Oct 04 13:01:26 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 04 13:01:26 2025 +0800"
      },
      "message": "Adapt to latest Asio APIs (Asio 1.32 or Boost.Asio 1.88) (#477)\n\n"
    },
    {
      "commit": "9f0b6fb40700131de080897ee69bbdfbcacc527a",
      "tree": "d7bdacc6312ea086437f3537db59f619f171db65",
      "parents": [
        "69b86aa12334fd6af5e5ad8d1e1a9a5eab7d3f76"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Sep 29 22:41:24 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 29 22:41:24 2025 +0800"
      },
      "message": "Use vcpkg to build alpine packages (#505)\n\n"
    },
    {
      "commit": "69b86aa12334fd6af5e5ad8d1e1a9a5eab7d3f76",
      "tree": "7f7afddbeb98b39f222ce861b08544b736a9fc15",
      "parents": [
        "fa413e1f67f0177acacb970adb33ffe2cb2aee95"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Sun Sep 28 09:48:55 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 28 09:48:55 2025 +0800"
      },
      "message": "Fix crash caused by Message::getTopicName when the message is a producer message (#503)\n\n"
    },
    {
      "commit": "fa413e1f67f0177acacb970adb33ffe2cb2aee95",
      "tree": "cc4dfadc7186ab81a99cffdcbf187f87e0bd9e30",
      "parents": [
        "54517973f8107c6d17b993e7b9da77c1162d8e26"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Sep 18 07:17:31 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 17 16:17:31 2025 -0700"
      },
      "message": "Fix duplicated subscribed topics not deduplicated (#501)\n\n"
    },
    {
      "commit": "54517973f8107c6d17b993e7b9da77c1162d8e26",
      "tree": "acdc2f50938cc68d7653caf796de43fbfffeba18",
      "parents": [
        "17fcf2af1ec81c1ab372c23a0716c92872d2c0d8"
      ],
      "author": {
        "name": "Guangyang Deng",
        "email": "gydeng.cs@gmail.com",
        "time": "Tue Aug 26 10:06:13 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 26 10:06:13 2025 +0800"
      },
      "message": "fix: remove unnecessary copies (#499)\n\n"
    },
    {
      "commit": "17fcf2af1ec81c1ab372c23a0716c92872d2c0d8",
      "tree": "438d0c0b927e9daf9e6a27381b64bb3f66522fae",
      "parents": [
        "9b86f9e2b037015cc437abc2f5f8b9475846bf95"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Aug 21 19:30:18 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 21 19:30:18 2025 +0800"
      },
      "message": "Fix hasMessageAvailable incorrectly returns true when read to latest after seeking by timestamp (#498)\n\n"
    },
    {
      "commit": "9b86f9e2b037015cc437abc2f5f8b9475846bf95",
      "tree": "9183fe5b894244a93745708164853e058c8b5713",
      "parents": [
        "639786f5ba579f7755f4220459bd613d89561617"
      ],
      "author": {
        "name": "Guangyang Deng",
        "email": "gydeng.cs@gmail.com",
        "time": "Mon Aug 04 14:07:54 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 04 14:07:54 2025 +0800"
      },
      "message": "[improve] modify the negativeACK structure to reduce memory overhead (#497)\n\n"
    },
    {
      "commit": "639786f5ba579f7755f4220459bd613d89561617",
      "tree": "886b55940f13452b9919a6c6b72d36ec1a68a047",
      "parents": [
        "9e119cee53199da5694cd59491d097399ba67a1f"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Jun 23 17:45:20 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 23 17:45:20 2025 +0800"
      },
      "message": "Remove static link to libstdc++ to avoid conflicts (#493)\n\n"
    },
    {
      "commit": "9e119cee53199da5694cd59491d097399ba67a1f",
      "tree": "46678c1da3d98a883fbceb3ece442e4023ccb632",
      "parents": [
        "15e0b00d1115c05832f84491bd0a0f92560ee918"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Jun 11 05:49:18 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 10 14:49:18 2025 -0700"
      },
      "message": "Fix acknowledgeCumulative never returns when accepting an invalid message id for a multi-topics consumer (#492)\n\n"
    },
    {
      "commit": "15e0b00d1115c05832f84491bd0a0f92560ee918",
      "tree": "3ac2fd09bcb6972b3066333623a190f9faa3a056",
      "parents": [
        "b0c44122b389ddf8e2ff9f3bd3d8a4e5d00dcc37"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Jun 11 05:48:50 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 10 14:48:50 2025 -0700"
      },
      "message": "Avoid getLastMessageId RPC when calling hasMessageAvailable after seek by timestamp (#491)\n\n"
    },
    {
      "commit": "b0c44122b389ddf8e2ff9f3bd3d8a4e5d00dcc37",
      "tree": "0e1200e795ffd57be80c13c65191de09e5555308",
      "parents": [
        "0d205096227323e37db173aa2e99a3eb76852d1b"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed May 28 19:45:17 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed May 28 19:45:17 2025 +0800"
      },
      "message": "[CI] Add clang-tidy check with clang-analyzer and performance checks (#490)\n\n"
    },
    {
      "commit": "0d205096227323e37db173aa2e99a3eb76852d1b",
      "tree": "79efb0184495c3d1bbb3f081bafdf2d3b54182e5",
      "parents": [
        "d9dd029c1e0627aed416a354f2806c2acc4b95d8"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Tue May 06 09:17:08 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue May 06 09:17:08 2025 +0800"
      },
      "message": "Fix stage-release.sh does not delete the Windows temporary directories (#488)\n\n"
    },
    {
      "commit": "d9dd029c1e0627aed416a354f2806c2acc4b95d8",
      "tree": "63cf1efd1da927629b7ebb3443fc255f354986cc",
      "parents": [
        "0e1ed3b2af24f5373036b839e4131257e8e75bf2"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Sun May 04 16:47:45 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun May 04 16:47:45 2025 +0800"
      },
      "message": "Fix TableView\u0027s existing key-value will never be updated (#487)\n\n"
    },
    {
      "commit": "0e1ed3b2af24f5373036b839e4131257e8e75bf2",
      "tree": "ccdaca9335a6317187ed2b44be89f8391d312306",
      "parents": [
        "6aeb3816e121859d0691c6f20014c9a1d9bdc51d"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Tue Apr 29 20:33:38 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 29 20:33:38 2025 +0800"
      },
      "message": "Fix the scripts for downloading GitHub Action artifacts (#485)\n\n"
    },
    {
      "commit": "6aeb3816e121859d0691c6f20014c9a1d9bdc51d",
      "tree": "ba3869f9ab100775d31777874ff1b425141c36fc",
      "parents": [
        "eede80b62fbf6c2b26607cec1ce1e0b4e9d857fa"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Apr 28 13:29:00 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Apr 28 13:29:00 2025 +0800"
      },
      "message": "[ci] Fix upload-artifact v3 is not supported (#484)\n\n"
    },
    {
      "commit": "eede80b62fbf6c2b26607cec1ce1e0b4e9d857fa",
      "tree": "c7eeea0898bbba6e68c2e1c765f4104a04093ef6",
      "parents": [
        "f37bf928e61296a8416693aa2a6afbc0ca2c8a82"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Fri Apr 25 17:37:57 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Apr 25 17:37:57 2025 +0800"
      },
      "message": "Bump curl, openssl, zlib to address CVEs (#482)\n\n- openssl 3.1.4 -\u003e 3.5.0\n- zlib 1.3 -\u003e 1.3.1\n- curl 8.4.0 -\u003e 8.13.0\n\nKeep the `protobuf` to an old version (3.21.12) because it\u0027s the last release that supports C++11, see https://protobuf.dev/news/2022-08-03/\n\nKeep the `asio` version not changed (1.28.2) because there are some APIs removed."
    },
    {
      "commit": "f37bf928e61296a8416693aa2a6afbc0ca2c8a82",
      "tree": "63c15190755fb3ee0f181fab7c2e61b910300491",
      "parents": [
        "0a9b7d9e7b5c8e2ddb111c30d242793217c68c65"
      ],
      "author": {
        "name": "erobot",
        "email": "erobot@users.noreply.github.com",
        "time": "Wed Apr 23 10:12:45 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 23 10:12:45 2025 +0800"
      },
      "message": "fix: ignore ping command in connection keepalive logic (#480)\n\nFixes #479 \n\n### Motivation\n\nThe current keepalive logic is too lenient – merely receiving ping commands can keep the connection alive.\n\n### Modifications\n\nIgnore ping command in connection keepalive logic."
    },
    {
      "commit": "0a9b7d9e7b5c8e2ddb111c30d242793217c68c65",
      "tree": "a0100b778fcf515c8f5c6ac03638bcf1c3b7e66d",
      "parents": [
        "fca38274ea2587f0980c40af83d8886ea73538e9"
      ],
      "author": {
        "name": "Brett",
        "email": "3829853+oversearch@users.noreply.github.com",
        "time": "Tue Apr 22 01:45:54 2025 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Apr 22 14:45:54 2025 +0800"
      },
      "message": "Fix multi-topics-consumer new topic listeners stuck in paused state (#481)\n\nThis was introduced in v3.7.0 via #447, which contained a change that attempted to fix an issue where a pre-mature ack of a message before a multi-topic subscriber was ready could have caused a crash.  To fix the original bug, all multi-topic subscriptions are started with their message listener paused. They later get un-paused once all topics are successfully subscribed and connected.  However, on a regex subscription when new topics are discovered, they also start in a paused state, and there\u0027s no mechanism to resume them.  Hence, they get stuck, and no messages for new topics will be processed.\n\nThis change adds a call to resume any new listeners after new topics are added."
    },
    {
      "commit": "fca38274ea2587f0980c40af83d8886ea73538e9",
      "tree": "20a43a03cbbc03658dd2f575594691476d005af9",
      "parents": [
        "d3fd6b2afa2c8ca0df77d60c8e5b9169a0e081ce"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Sat Feb 08 22:49:17 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Feb 08 22:49:17 2025 +0800"
      },
      "message": "Bumped version to 3.8.0-pre (#470)\n\n"
    },
    {
      "commit": "d3fd6b2afa2c8ca0df77d60c8e5b9169a0e081ce",
      "tree": "76856de0505778cccd0ad96919af400d19ef1c25",
      "parents": [
        "afeac788d1e951951516b7aabee4c70af579dda2"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Sat Feb 08 17:41:46 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Feb 08 17:41:46 2025 +0800"
      },
      "message": "Make it optional to link statically to libgcc and libstdc++ (#474)\n\n"
    },
    {
      "commit": "afeac788d1e951951516b7aabee4c70af579dda2",
      "tree": "5d183c828d75b0f1f0da11eedb0d60f986ef0196",
      "parents": [
        "1e8e4d2ab6cf99d2660703b711849d026ee81036"
      ],
      "author": {
        "name": "Masahiro Sakamoto",
        "email": "massakam@lycorp.co.jp",
        "time": "Sat Feb 08 14:46:42 2025 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Feb 08 13:46:42 2025 +0800"
      },
      "message": "Fix an issue where zero queue consumers are unable to receive messages after topic unloading (#473)\n\n"
    },
    {
      "commit": "1e8e4d2ab6cf99d2660703b711849d026ee81036",
      "tree": "c7f4bf9f8275d45384f7619678ee9c183fb4358a",
      "parents": [
        "bdf685492f90b0d079e8885ce33b4402839d0495"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Mon Dec 30 21:35:56 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 30 21:35:56 2024 +0800"
      },
      "message": "Use vcpkg to build macOS packages (#465)\n\n"
    },
    {
      "commit": "bdf685492f90b0d079e8885ce33b4402839d0495",
      "tree": "569ecff1cba35166030325a71c4e34aab4f9e09c",
      "parents": [
        "4ba83e83fbb4319c0b4cda82372caf042e9ccaa6"
      ],
      "author": {
        "name": "erobot",
        "email": "erobot@users.noreply.github.com",
        "time": "Thu Dec 26 13:14:50 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Dec 26 13:14:50 2024 +0800"
      },
      "message": "Fix some compiler warnings in public headers (#468)\n\n### Motivation\r\n\r\nFix some compiler warnings in public headers when using with -Wextra. These warnings prevent projects using -Wextra -Werror to use pulsar client without modifications.\r\n\r\n### Modifications\r\n\r\n1. Modified public headers to fix compiler warnings\r\n2. Add compile options \"-Wextra -Wno-unused-parameter\" to compile examples to help find similar issues"
    },
    {
      "commit": "4ba83e83fbb4319c0b4cda82372caf042e9ccaa6",
      "tree": "5a6b7151ccb05dd6bfcffc7608ce533ef7bd5cfe",
      "parents": [
        "aeff955f2a5e3d87532b606bab02f4067b795bd5"
      ],
      "author": {
        "name": "Masahiro Sakamoto",
        "email": "massakam@lycorp.co.jp",
        "time": "Thu Dec 19 15:42:23 2024 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Dec 19 14:42:23 2024 +0800"
      },
      "message": "Fix issue where cert chain is not taken into account in mTLS authentication (#467)\n\n"
    },
    {
      "commit": "aeff955f2a5e3d87532b606bab02f4067b795bd5",
      "tree": "afd8fe6041281e1417cf74ea1a45ffe3b937e011",
      "parents": [
        "6f7c37aa4b68a5fcf12058d3f3352faba5f37c3c"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Dec 12 18:30:31 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Dec 12 18:30:31 2024 +0800"
      },
      "message": "Fix startMessageInclusive does not work if the 1st message is a chunked message (#462)\n\n"
    },
    {
      "commit": "6f7c37aa4b68a5fcf12058d3f3352faba5f37c3c",
      "tree": "87de3d74574bd7242cc24c5c92a60bb419809aca",
      "parents": [
        "2abbf830f9b2a01ebef9d5511d4f4a9a7b4683d6"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Dec 11 21:56:44 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 11 21:56:44 2024 +0800"
      },
      "message": "Bump macos runner image to 14 (#463)\n\n"
    },
    {
      "commit": "2abbf830f9b2a01ebef9d5511d4f4a9a7b4683d6",
      "tree": "158e3258fae78436cf2cc8bd774c16e8cabdb18d",
      "parents": [
        "e264cf7242c8f85e7f8d66335218ff38c658c8ad"
      ],
      "author": {
        "name": "Okada Haruki",
        "email": "ocadaruma@gmail.com",
        "time": "Mon Dec 09 15:51:17 2024 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 09 14:51:17 2024 +0800"
      },
      "message": "Update README to build wireshark plugin correctly (#460)\n\n"
    },
    {
      "commit": "e264cf7242c8f85e7f8d66335218ff38c658c8ad",
      "tree": "5a477966f7f2daba19e696423c82d990968964cd",
      "parents": [
        "ce6c4bcaca8ff8e088b663690f5835438f926050"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Nov 27 22:51:48 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Nov 27 22:51:48 2024 +0800"
      },
      "message": "Handle the exception from the token supplier (#458)\n\n### Motivation\r\n\r\nWhen a token supplier is passed to the `AuthToken`, if exceptions are\r\nthrown from it, the application will crash immediately. A typical case\r\nis the Python wrapper might raise an exception when trying to get token.\r\n\r\n### Modifications\r\n\r\nCatch the exception in `Commands::newConnect` because the token supplier\r\nis called in it. Then convert it to `ResultAuthenticationError`. Add\r\n`testTokenSupplierException` to verify it."
    },
    {
      "commit": "ce6c4bcaca8ff8e088b663690f5835438f926050",
      "tree": "1c2221e26e6b4639dff3f56292c70e1a189431c2",
      "parents": [
        "3efa80a2667aae599118f27b8741c8236b2386c8"
      ],
      "author": {
        "name": "Baodi Shi",
        "email": "baodi@apache.org",
        "time": "Tue Nov 26 11:19:47 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Nov 26 11:19:47 2024 +0800"
      },
      "message": "Expose keep alive interval for c and c++ client (#457)\n\n* Expose keep alive interval for c and c++ client\r\n\r\n* Optimize"
    },
    {
      "commit": "3efa80a2667aae599118f27b8741c8236b2386c8",
      "tree": "cc0c70f297406b7a3d32009e712f726897ad9246",
      "parents": [
        "2491a5a5f1f8d8640788c9f065411aa59f3cde2b"
      ],
      "author": {
        "name": "Andrew Rhoads",
        "email": "andrew.c.rhoads@gmail.com",
        "time": "Thu Oct 31 03:26:27 2024 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 31 18:26:27 2024 +0800"
      },
      "message": "Fix default operation timeout (#450)\n\n"
    },
    {
      "commit": "2491a5a5f1f8d8640788c9f065411aa59f3cde2b",
      "tree": "90cad27e31ff5ccab19f123557e58e11ba5e721e",
      "parents": [
        "54e529aaf82bddac063c847d4c11d3fba3acf0f3"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Oct 30 09:58:42 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 30 09:58:42 2024 +0800"
      },
      "message": "Fix the YAML format error in latest image (#452)\n\n"
    },
    {
      "commit": "54e529aaf82bddac063c847d4c11d3fba3acf0f3",
      "tree": "f53efb47d28df46e10e07c1153033972244cfdf7",
      "parents": [
        "8b2753a56579ea6cf11e26a0c5a160797518df63"
      ],
      "author": {
        "name": "nkurihar",
        "email": "nkurihar@apache.org",
        "time": "Fri Oct 11 15:44:23 2024 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 11 14:44:23 2024 +0800"
      },
      "message": "Fix ack failure on message listener in multi topics consumer (#447)\n\n"
    },
    {
      "commit": "8b2753a56579ea6cf11e26a0c5a160797518df63",
      "tree": "d5b59b86f4f5af6172c9d8f9827b1ab40fb3dcc0",
      "parents": [
        "1a6c7ce56c170b6992199094bcb2af24a796b3f3"
      ],
      "author": {
        "name": "Baodi Shi",
        "email": "baodi@apache.org",
        "time": "Tue Sep 17 16:55:43 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 17 16:55:43 2024 +0800"
      },
      "message": "Bumped version to 3.7.0-pre (#445)\n\n"
    },
    {
      "commit": "1a6c7ce56c170b6992199094bcb2af24a796b3f3",
      "tree": "8b5ea104e6c7f9f5d25321566353596aea0011ca",
      "parents": [
        "8f269e837cbc20350e9a19505faca8e420a97d24"
      ],
      "author": {
        "name": "erobot",
        "email": "erobot@users.noreply.github.com",
        "time": "Thu Sep 05 14:57:59 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 05 14:57:59 2024 +0800"
      },
      "message": "fix: Keep compatible with old boost versions (#444)\n\n"
    },
    {
      "commit": "8f269e837cbc20350e9a19505faca8e420a97d24",
      "tree": "d1480725d78ba1bbc61a9ca662b439cc9d7afc8e",
      "parents": [
        "2ec734b3d6e3bf77bbfa892d808499a2bfa57c06"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Aug 29 22:10:22 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 29 22:10:22 2024 +0800"
      },
      "message": "Fix buffer overflow for non-batched send when the message metadata size exceeds 64KB (#443)\n\nSee https://github.com/apache/pulsar-client-python/issues/223\r\n\r\n### Motivation\r\n\r\nCurrently a shared buffer is used to store serialized message metadata\r\nfor each send request. However, its capacity is only 64KB, when the metadata\r\nsize exceeds 64KB, buffer overflow could happen.\r\n\r\n### Modifications\r\n\r\nWhen the metadata size is too large, allocate a new buffer instead of\r\nusing the shared buffer. Add `testLargeProperties` to cover it."
    },
    {
      "commit": "2ec734b3d6e3bf77bbfa892d808499a2bfa57c06",
      "tree": "1ca98a2269143f8089d9f7951a757af4cb8fa711",
      "parents": [
        "5940cb518bdf3a13ae7f859fab10d6940eec51b7"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Wed Aug 21 20:44:46 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 21 20:44:46 2024 +0800"
      },
      "message": "Fix invalid memory access on the first pending batch receive callback (#441)\n\n"
    },
    {
      "commit": "5940cb518bdf3a13ae7f859fab10d6940eec51b7",
      "tree": "d87cdb277c667bb8295be1ea390bb2bd12f56047",
      "parents": [
        "2a6916819b2a80a532f827dc96026b8fdc0b15ed"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Tue Aug 13 22:30:48 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 13 22:30:48 2024 +0800"
      },
      "message": "Fix consumer might not subscribe after a reconnection (#438)\n\nFixes https://github.com/apache/pulsar-client-cpp/issues/436\r\n\r\n### Motivation\r\n\r\nWhen a consumer starts grabbing the connection, it registers a timer after the operation timeout. When that\r\ntimer is expired, it will fail the connection and cancel the connection timer. However, it results a race\r\ncondition that:\r\n  1. The consumer\u0027s connection is closed (e.g. the keep alive timer failed)\r\n  2. The connection timer is registered on the executor and will trigger the reconnection after 100ms\r\n  3. The connection timer is cancelled, then the reconnection won\u0027t start.\r\n\r\n### Modifications\r\n\r\nCancel the `creationTimer_` once `HandlerBase#start` succeeded first\r\ntime. Add `testReconnectWhenFirstConnectTimedOut` to cover this case."
    },
    {
      "commit": "2a6916819b2a80a532f827dc96026b8fdc0b15ed",
      "tree": "9a52654f75aa4632a26f0000522734ca080512d1",
      "parents": [
        "35bf161ba25c9ea073b730e3dcdaa50c30703bcb"
      ],
      "author": {
        "name": "Baodi Shi",
        "email": "baodi@apache.org",
        "time": "Mon Jul 22 19:01:39 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jul 22 19:01:39 2024 +0800"
      },
      "message": "feat: expose partitions update interval configuration to C client (#437)\n\n* feat: expose partitions update interval configuration to C client\r\n\r\n* code format"
    },
    {
      "commit": "35bf161ba25c9ea073b730e3dcdaa50c30703bcb",
      "tree": "0c933787e1d27575c268f8e08eb539f14501cad4",
      "parents": [
        "d736a1b68fac6d1d5bd9f785aabf8f952580a597"
      ],
      "author": {
        "name": "Yunze Xu",
        "email": "xyzinfernity@163.com",
        "time": "Thu Jul 04 15:28:03 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 04 09:28:03 2024 +0200"
      },
      "message": "[CI] Use macos-12 to build macOS libraries (#433)\n\n"
    }
  ],
  "next": "d736a1b68fac6d1d5bd9f785aabf8f952580a597"
}
