This is an automated email from the ASF dual-hosted git repository.

Duansg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/master by this push:
     new fd8056b066 [fix] keep zero-row metrics data in redis queue codec 
(#4305)
fd8056b066 is described below

commit fd8056b0662739f14fbcdbbbed0e8be70863707f
Author: NekoPunch <[email protected]>
AuthorDate: Sun Aug 9 08:50:47 2026 -0700

    [fix] keep zero-row metrics data in redis queue codec (#4305)
    
    Co-authored-by: Duansg <[email protected]>
---
 .../common/serialize/RedisMetricsDataCodec.java    |   8 +-
 .../serialize/RedisMetricsDataCodecTest.java       | 104 +++++++++++++++++++++
 2 files changed, 107 insertions(+), 5 deletions(-)

diff --git 
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/serialize/RedisMetricsDataCodec.java
 
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/serialize/RedisMetricsDataCodec.java
index 37c5ff3798..ecee6e4236 100644
--- 
a/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/serialize/RedisMetricsDataCodec.java
+++ 
b/hertzbeat-common-core/src/main/java/org/apache/hertzbeat/common/serialize/RedisMetricsDataCodec.java
@@ -69,13 +69,11 @@ public class RedisMetricsDataCodec implements 
RedisCodec<String, CollectRep.Metr
             try (ByteArrayInputStream in = new ByteArrayInputStream(bytes);
                  ArrowStreamReader reader = new ArrowStreamReader(
                          Channels.newChannel(in), allocator)) {
-                reader.loadNextBatch();
-                VectorSchemaRoot root = reader.getVectorSchemaRoot();
-                if (root == null || root.getRowCount() == 0) {
-                    log.warn("Empty data received");
+                if (!reader.loadNextBatch()) {
+                    log.warn("No record batch in metrics data stream, 
discarding");
                     return null;
                 }
-                return new CollectRep.MetricsData(root);
+                return new 
CollectRep.MetricsData(reader.getVectorSchemaRoot());
             }
         } catch (Exception e) {
             log.error("Failed to decode metrics data", e);
diff --git 
a/hertzbeat-common-core/src/test/java/org/apache/hertzbeat/common/serialize/RedisMetricsDataCodecTest.java
 
b/hertzbeat-common-core/src/test/java/org/apache/hertzbeat/common/serialize/RedisMetricsDataCodecTest.java
new file mode 100644
index 0000000000..e3b44cb244
--- /dev/null
+++ 
b/hertzbeat-common-core/src/test/java/org/apache/hertzbeat/common/serialize/RedisMetricsDataCodecTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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 org.apache.hertzbeat.common.serialize;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.util.List;
+import org.apache.arrow.memory.BufferAllocator;
+import org.apache.arrow.memory.RootAllocator;
+import org.apache.arrow.vector.VectorSchemaRoot;
+import org.apache.arrow.vector.ipc.ArrowStreamWriter;
+import org.apache.arrow.vector.types.pojo.ArrowType;
+import org.apache.arrow.vector.types.pojo.Field;
+import org.apache.arrow.vector.types.pojo.Schema;
+import org.apache.hertzbeat.common.entity.message.CollectRep;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test case for {@link RedisMetricsDataCodec}
+ */
+class RedisMetricsDataCodecTest {
+
+    private RedisMetricsDataCodec codec;
+
+    @BeforeEach
+    void setUp() {
+        codec = new RedisMetricsDataCodec();
+    }
+
+    @Test
+    void encodeDecodePreservesRows() {
+        CollectRep.MetricsData data = CollectRep.MetricsData.newBuilder()
+                .setId(123L)
+                .setApp("linux")
+                .setMetrics("cpu")
+                .setCode(CollectRep.Code.SUCCESS)
+                
.addField(CollectRep.Field.newBuilder().setName("usage").setType(0).build())
+                
.addValueRow(CollectRep.ValueRow.newBuilder().addColumn("42").build())
+                .build();
+
+        try (CollectRep.MetricsData decoded = 
codec.decodeValue(codec.encodeValue(data))) {
+            assertNotNull(decoded);
+            assertEquals(123L, decoded.getId());
+            assertEquals(CollectRep.Code.SUCCESS, decoded.getCode());
+            assertEquals(1, decoded.getValues().size());
+            assertEquals("42", decoded.getValues().get(0).getColumns(0));
+        }
+    }
+
+    @Test
+    void encodeDecodeKeepsZeroRowTimeout() {
+        CollectRep.MetricsData timeout = CollectRep.MetricsData.newBuilder()
+                .setId(456L)
+                .setApp("linux")
+                .setMetrics("cpu")
+                .setPriority(0)
+                .setCode(CollectRep.Code.TIMEOUT)
+                .setMsg("Collect Timeout No Response")
+                .build();
+
+        try (CollectRep.MetricsData decoded = 
codec.decodeValue(codec.encodeValue(timeout))) {
+            assertNotNull(decoded);
+            assertEquals(456L, decoded.getId());
+            assertEquals(CollectRep.Code.TIMEOUT, decoded.getCode());
+            assertEquals("Collect Timeout No Response", decoded.getMsg());
+            assertEquals(0, decoded.getPriority());
+            assertEquals(0, decoded.rowCount());
+        }
+    }
+
+    @Test
+    void decodeSchemaOnlyStreamReturnsNull() throws Exception {
+        Schema schema = new Schema(List.of(Field.nullable("usage", new 
ArrowType.Utf8())));
+        try (BufferAllocator allocator = new RootAllocator();
+             VectorSchemaRoot root = VectorSchemaRoot.create(schema, 
allocator);
+             ByteArrayOutputStream out = new ByteArrayOutputStream();
+             ArrowStreamWriter writer = new ArrowStreamWriter(root, null, 
Channels.newChannel(out))) {
+            writer.start();
+            writer.end();
+
+            assertNull(codec.decodeValue(ByteBuffer.wrap(out.toByteArray())));
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to