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

hanahmily pushed a commit to branch bug-hq-sync
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git


The following commit(s) were added to refs/heads/bug-hq-sync by this push:
     new 470cd5402 fix(handoff): return error instead of warning when sidx part 
has no valid timestamp
470cd5402 is described below

commit 470cd5402e200aedbc4e3a08ef1db9f82dd6b40a
Author: Hongtao Gao <[email protected]>
AuthorDate: Sun Apr 12 03:26:01 2026 +0000

    fix(handoff): return error instead of warning when sidx part has no valid 
timestamp
    
    When neither minTimestamp nor segmentID is valid in manifest.json, the
    previous code only logged a warning and returned MinTimestamp=0. The
    receiving chunked sync handler rejects MinTimestamp<=0, causing infinite
    replay retries. Now returns an explicit error to fail fast.
    
    via [HAPI](https://hapi.run)
    
    Co-Authored-By: HAPI <[email protected]>
---
 banyand/trace/handoff_controller.go  |  4 ++--
 banyand/trace/handoff_replay_test.go | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/banyand/trace/handoff_controller.go 
b/banyand/trace/handoff_controller.go
index 4b4aed0d4..4e69f7559 100644
--- a/banyand/trace/handoff_controller.go
+++ b/banyand/trace/handoff_controller.go
@@ -1273,8 +1273,8 @@ func (hc *handoffController) readPartFromHandoff(nodeAddr 
string, partID uint64,
                case pm.SegmentID > 0:
                        streamingPart.MinTimestamp = pm.SegmentID
                default:
-                       hc.l.Warn().Uint64("partID", partID).Str("partType", 
partType).
-                               Msg("sidx handoff replay: part has no valid 
timestamp (MinTimestamp=nil, SegmentID=0)")
+                       release()
+                       return nil, func() {}, fmt.Errorf("sidx part %d has no 
valid timestamp (MinTimestamp=nil, SegmentID=0)", partID)
                }
                if pm.MaxTimestamp != nil {
                        streamingPart.MaxTimestamp = *pm.MaxTimestamp
diff --git a/banyand/trace/handoff_replay_test.go 
b/banyand/trace/handoff_replay_test.go
index 4adbd6014..ee66fbb9a 100644
--- a/banyand/trace/handoff_replay_test.go
+++ b/banyand/trace/handoff_replay_test.go
@@ -698,3 +698,37 @@ func 
TestHandoffController_ReadPartFromHandoff_SidxInvalidManifest(t *testing.T)
        require.Error(t, readErr)
        assert.Contains(t, readErr.Error(), "failed to parse manifest.json")
 }
+
+func TestHandoffController_ReadPartFromHandoff_SidxNoValidTimestamp(t 
*testing.T) {
+       tempDir, defFn := test.Space(require.New(t))
+       defer defFn()
+
+       fileSystem := fs.NewLocalFileSystem()
+       l := logger.GetLogger("test")
+
+       sourceRoot := filepath.Join(tempDir, "source")
+       fileSystem.MkdirIfNotExist(sourceRoot, storage.DirPerm)
+       partID := uint64(0x74)
+
+       // Manifest with no minTimestamp and segmentID=0 (invalid)
+       manifest := []byte(`{
+               "compressedSizeBytes": 128,
+               "totalCount": 5,
+               "blocksCount": 1,
+               "minKey": 1,
+               "maxKey": 10,
+               "segmentID": 0
+       }`)
+       sourcePath := createTestSidxPart(t, fileSystem, sourceRoot, partID, 
manifest)
+
+       nodeAddr := testNodeAddrPrimary
+       controller, err := newHandoffController(fileSystem, tempDir, nil, 
[]string{nodeAddr}, 0, l, nil)
+       require.NoError(t, err)
+       defer controller.close()
+
+       require.NoError(t, controller.enqueueForNode(nodeAddr, partID, 
"sidx_trace_id", sourcePath, "group1", 1))
+
+       _, _, readErr := controller.readPartFromHandoff(nodeAddr, partID, 
"sidx_trace_id")
+       require.Error(t, readErr)
+       assert.Contains(t, readErr.Error(), "has no valid timestamp")
+}

Reply via email to