You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by rf...@apache.org on 2026/08/26 02:35:03 UTC
(pulsar-client-go) branch master updated: fix(pulsaradmin): preserve explicit zero receiver queue size (#1529)
This is an automated email from the ASF dual-hosted git repository.
freeznet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar-client-go.git
The following commit(s) were added to refs/heads/master by this push:
new 61d7a95e fix(pulsaradmin): preserve explicit zero receiver queue size (#1529)
61d7a95e is described below
commit 61d7a95e66cddf329adc6d925a8bd60ccd26eda5
Author: Rui Fu <fr...@users.noreply.github.com>
AuthorDate: Wed Aug 26 10:34:58 2026 +0800
fix(pulsaradmin): preserve explicit zero receiver queue size (#1529)
Signed-off-by: Rui Fu <rf...@apache.org>
---
pulsaradmin/pkg/utils/consumer_config.go | 69 +++++++++++++++--
pulsaradmin/pkg/utils/consumer_config_test.go | 106 ++++++++++++++++++++++++++
2 files changed, 167 insertions(+), 8 deletions(-)
diff --git a/pulsaradmin/pkg/utils/consumer_config.go b/pulsaradmin/pkg/utils/consumer_config.go
index f609ae48..fce92616 100644
--- a/pulsaradmin/pkg/utils/consumer_config.go
+++ b/pulsaradmin/pkg/utils/consumer_config.go
@@ -17,13 +17,66 @@
package utils
+import "encoding/json"
+
type ConsumerConfig struct {
- SchemaType string `json:"schemaType,omitempty" yaml:"schemaType"`
- SerdeClassName string `json:"serdeClassName,omitempty" yaml:"serdeClassName"`
- RegexPattern bool `json:"regexPattern,omitempty" yaml:"regexPattern"`
- ReceiverQueueSize int `json:"receiverQueueSize,omitempty" yaml:"receiverQueueSize"`
- SchemaProperties map[string]string `json:"schemaProperties,omitempty" yaml:"schemaProperties"`
- ConsumerProperties map[string]string `json:"consumerProperties,omitempty" yaml:"consumerProperties"`
- CryptoConfig *CryptoConfig `json:"cryptoConfig,omitempty" yaml:"cryptoConfig"`
- PoolMessages bool `json:"poolMessages,omitempty" yaml:"poolMessages"`
+ SchemaType string `json:"schemaType,omitempty" yaml:"schemaType"`
+ SerdeClassName string `json:"serdeClassName,omitempty" yaml:"serdeClassName"`
+ RegexPattern bool `json:"regexPattern,omitempty" yaml:"regexPattern"`
+ ReceiverQueueSize int `json:"-" yaml:"receiverQueueSize"`
+ receiverQueueSizeSet bool
+ SchemaProperties map[string]string `json:"schemaProperties,omitempty" yaml:"schemaProperties"`
+ ConsumerProperties map[string]string `json:"consumerProperties,omitempty" yaml:"consumerProperties"`
+ CryptoConfig *CryptoConfig `json:"cryptoConfig,omitempty" yaml:"cryptoConfig"`
+ PoolMessages bool `json:"poolMessages,omitempty" yaml:"poolMessages"`
+}
+
+// SetReceiverQueueSize records an explicitly configured receiver queue size. It is required when
+// the value is zero so JSON marshaling can distinguish zero from an unset value.
+func (c *ConsumerConfig) SetReceiverQueueSize(value int) {
+ c.ReceiverQueueSize = value
+ c.receiverQueueSizeSet = true
+}
+
+// HasReceiverQueueSize reports whether receiverQueueSize was explicitly configured or returned by
+// the server. Non-zero values assigned directly remain supported for backward compatibility.
+func (c ConsumerConfig) HasReceiverQueueSize() bool {
+ return c.receiverQueueSizeSet || c.ReceiverQueueSize != 0
+}
+
+type consumerConfigJSON ConsumerConfig
+
+func (c ConsumerConfig) MarshalJSON() ([]byte, error) {
+ var receiverQueueSize *int
+ if c.HasReceiverQueueSize() {
+ value := c.ReceiverQueueSize
+ receiverQueueSize = &value
+ }
+
+ return json.Marshal(struct {
+ consumerConfigJSON
+ ReceiverQueueSize *int `json:"receiverQueueSize,omitempty"`
+ }{
+ consumerConfigJSON: consumerConfigJSON(c),
+ ReceiverQueueSize: receiverQueueSize,
+ })
+}
+
+func (c *ConsumerConfig) UnmarshalJSON(data []byte) error {
+ var value struct {
+ consumerConfigJSON
+ ReceiverQueueSize *int `json:"receiverQueueSize,omitempty"`
+ }
+ if err := json.Unmarshal(data, &value); err != nil {
+ return err
+ }
+
+ *c = ConsumerConfig(value.consumerConfigJSON)
+ c.ReceiverQueueSize = 0
+ c.receiverQueueSizeSet = false
+ if value.ReceiverQueueSize != nil {
+ c.SetReceiverQueueSize(*value.ReceiverQueueSize)
+ }
+
+ return nil
}
diff --git a/pulsaradmin/pkg/utils/consumer_config_test.go b/pulsaradmin/pkg/utils/consumer_config_test.go
new file mode 100644
index 00000000..57c18d46
--- /dev/null
+++ b/pulsaradmin/pkg/utils/consumer_config_test.go
@@ -0,0 +1,106 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package utils
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestConsumerConfigReceiverQueueSizeJSON(t *testing.T) {
+ tests := []struct {
+ name string
+ config ConsumerConfig
+ want string
+ }{
+ {
+ name: "unset is omitted",
+ config: ConsumerConfig{},
+ want: `{}`,
+ },
+ {
+ name: "direct non-zero assignment and other fields remain supported",
+ config: ConsumerConfig{
+ SchemaType: "STRING",
+ RegexPattern: true,
+ ReceiverQueueSize: 100,
+ SchemaProperties: map[string]string{"schema": "value"},
+ ConsumerProperties: map[string]string{"consumer": "value"},
+ PoolMessages: true,
+ },
+ want: `{
+ "schemaType":"STRING",
+ "regexPattern":true,
+ "receiverQueueSize":100,
+ "schemaProperties":{"schema":"value"},
+ "consumerProperties":{"consumer":"value"},
+ "poolMessages":true
+ }`,
+ },
+ {
+ name: "explicit zero is included",
+ config: func() ConsumerConfig {
+ config := ConsumerConfig{}
+ config.SetReceiverQueueSize(0)
+ return config
+ }(),
+ want: `{"receiverQueueSize":0}`,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ data, err := json.Marshal(test.config)
+ require.NoError(t, err)
+ assert.JSONEq(t, test.want, string(data))
+ })
+ }
+}
+
+func TestConsumerConfigReceiverQueueSizeUnmarshalJSON(t *testing.T) {
+ tests := []struct {
+ name string
+ payload string
+ want int
+ isSet bool
+ schema string
+ }{
+ {name: "unset", payload: `{}`, want: 0, isSet: false},
+ {name: "explicit zero", payload: `{"receiverQueueSize":0}`, want: 0, isSet: true},
+ {
+ name: "non-zero with other fields",
+ payload: `{"receiverQueueSize":100,"schemaType":"STRING"}`,
+ want: 100,
+ isSet: true,
+ schema: "STRING",
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ var config ConsumerConfig
+ require.NoError(t, json.Unmarshal([]byte(test.payload), &config))
+ assert.Equal(t, test.want, config.ReceiverQueueSize)
+ assert.Equal(t, test.isSet, config.HasReceiverQueueSize())
+ assert.Equal(t, test.schema, config.SchemaType)
+ })
+ }
+}