You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ha...@apache.org on 2026/05/12 01:58:11 UTC

(skywalking-banyandb) 03/04: Make the InspectAll CI more stable (#1122)

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

hanahmily pushed a commit to branch v0.10.x
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git

commit d18d4a50df5a761b66aeebccbea7706a8e576930
Author: mrproliu <74...@qq.com>
AuthorDate: Sat May 9 11:44:31 2026 +0800

    Make the InspectAll CI more stable (#1122)
---
 .../queue/sub/group_lifecycle_cold_tier_test.go    | 28 +++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/banyand/queue/sub/group_lifecycle_cold_tier_test.go b/banyand/queue/sub/group_lifecycle_cold_tier_test.go
index 46beacd4c..11eea1cde 100644
--- a/banyand/queue/sub/group_lifecycle_cold_tier_test.go
+++ b/banyand/queue/sub/group_lifecycle_cold_tier_test.go
@@ -20,6 +20,7 @@ package sub
 import (
 	"context"
 	"fmt"
+	"runtime"
 	"sync"
 	"sync/atomic"
 	"testing"
@@ -51,6 +52,12 @@ type coldTierRepo struct {
 	concurrentNow atomic.Int32
 	concurrentMax atomic.Int32
 	panicCount    atomic.Int32
+	// expectOverlap, when > 1, makes CollectDataInfo yield until
+	// concurrentMax has reached the configured value. The C subtest sets
+	// this to 2 so the "at least two simultaneous calls" assertion is
+	// observed deterministically rather than depending on the Go
+	// scheduler interleaving short-lived goroutines.
+	expectOverlap int32
 }
 
 func (r *coldTierRepo) GroupRegistry() schema.Group {
@@ -78,6 +85,22 @@ func (r *coldTierRepo) CollectDataInfo(_ context.Context, group string) (out []*
 	if r.hook != nil {
 		return r.hook(group, int(idx-1))
 	}
+	// Eventually-style overlap barrier: yield cooperatively until
+	// concurrentMax has reached expectOverlap, so the C_ConcurrentInspectAll
+	// assertion deterministically observes concurrent fan-out even when
+	// the runtime serializes short-lived goroutines (e.g. GOMAXPROCS=1).
+	// This replaces an arbitrary time.Sleep -- both wasteful when overlap
+	// happens fast and racy when the scheduler serializes calls. Polling
+	// concurrentMax (which only grows) lets every goroutine return as
+	// soon as overlap was observed at any point, not only while it is
+	// still happening. The wait is bounded so a regression that genuinely
+	// serializes InspectAll fails the assertion rather than hanging.
+	if target := atomic.LoadInt32(&r.expectOverlap); target > 1 {
+		deadline := time.Now().Add(time.Second)
+		for r.concurrentMax.Load() < target && time.Now().Before(deadline) {
+			runtime.Gosched()
+		}
+	}
 	return coldTierEmptyDataInfo(), nil, nil
 }
 
@@ -191,7 +214,10 @@ func TestInspectAll_ColdTier_Integration(t *testing.T) {
 	})
 
 	t.Run("C_ConcurrentInspectAll", func(t *testing.T) {
-		repo := &coldTierRepo{groupRegistry: &mockGroupRegistry{groups: groups}}
+		repo := &coldTierRepo{
+			groupRegistry: &mockGroupRegistry{groups: groups},
+			expectOverlap: 2,
+		}
 		s := &server{log: logger.GetLogger("cold-tier-C"), metadataRepo: repo}
 
 		const callers = 8