mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-28 07:50:44 +01:00
* filer: shut down test filers' meta-log buffers, fixing the 32-bit OOM Each log_buffer.NewLogBuffer preallocates five 8 MiB windows and spawns loopFlush/loopInterval goroutines that keep them reachable. The weed/filer tests built ~70 filers and aggregators that almost never called ShutdownLogBuffer, pinning ~2.8 GB plus live churn, and the linux/386 job ran out of its ~4 GiB address space inside newSealedBuffers. - MetaAggregator.Shutdown now retires MetaLogBuffer too: the "aggr" buffer's loops previously outlived the aggregator. - newTestFiler and newTestFilerWithStubStore register t.Cleanup shutdowns; the one-off filer/aggregator literals defer theirs. * filer: wait for the aggregated meta-log buffer to stop in Shutdown ShutdownLogBuffer only signals the stop; loopFlush and its pooled windows exit asynchronously. Match Filer.Shutdown's local-buffer sequence so the aggregator returns with the buffer's memory already released. * filer: cancel test filers' flush context before buffer shutdown The stub-store helpers build real NewFiler instances, so the queued shutdown flush retries appendToFile every ~737ms under flushCtx, which nothing ever cancelled — the buffer and its pool stayed alive past each test. Cancelling first lets the flush drop the window and WaitForShutdown confirms loopFlush exited. * filer: wait for test log buffers to drain after shutdown The stub-flush buffers cannot hang, but without WaitForShutdown their loopFlush goroutines release the pooled windows asynchronously — the memory this PR means to free is still counted as live while the next test allocates.
90 lines
2.3 KiB
Go
90 lines
2.3 KiB
Go
package filer
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
|
)
|
|
|
|
func TestOnPeerUpdateRepeatedAdd(t *testing.T) {
|
|
peer := pb.ServerAddress("127.0.0.1:1")
|
|
ma := NewMetaAggregator(nil, pb.ServerAddress("127.0.0.1:2"), nil)
|
|
defer ma.Shutdown()
|
|
|
|
add := &master_pb.ClusterNodeUpdate{Address: string(peer), IsAdd: true}
|
|
ma.OnPeerUpdate(add, time.Now())
|
|
first, found := ma.peerChans[peer]
|
|
if !found {
|
|
t.Fatal("expecting a subscription after the first add")
|
|
}
|
|
|
|
ma.OnPeerUpdate(add, time.Now())
|
|
if ma.peerChans[peer] != first {
|
|
t.Fatal("expecting the same subscription after a repeated add")
|
|
}
|
|
select {
|
|
case <-first:
|
|
t.Fatal("expecting the subscription to stay alive after a repeated add")
|
|
default:
|
|
}
|
|
|
|
ma.OnPeerUpdate(&master_pb.ClusterNodeUpdate{Address: string(peer)}, time.Now())
|
|
if _, found := ma.peerChans[peer]; found {
|
|
t.Fatal("expecting the subscription to be removed")
|
|
}
|
|
}
|
|
|
|
// Shutdown must close every peer's stopChan and wait for the loops, which is
|
|
// what lets each loop's deferred offset save run before the store closes.
|
|
func TestMetaAggregatorShutdownStopsPeerLoops(t *testing.T) {
|
|
ma := NewMetaAggregator(nil, pb.ServerAddress("127.0.0.1:2"), nil)
|
|
|
|
stopChan := make(chan struct{})
|
|
peer := pb.ServerAddress("127.0.0.1:1")
|
|
ma.peerChans[peer] = stopChan
|
|
ma.peerWg.Add(1)
|
|
exited := make(chan struct{})
|
|
go func() {
|
|
defer ma.peerWg.Done()
|
|
<-stopChan
|
|
close(exited)
|
|
}()
|
|
|
|
done := make(chan struct{})
|
|
go func() {
|
|
ma.Shutdown()
|
|
close(done)
|
|
}()
|
|
|
|
select {
|
|
case <-done:
|
|
case <-time.After(3 * time.Second):
|
|
t.Fatal("Shutdown did not return")
|
|
}
|
|
select {
|
|
case <-exited:
|
|
default:
|
|
t.Fatal("peer loop was not stopped")
|
|
}
|
|
}
|
|
|
|
// After Shutdown begins, a peer-add update arriving on the still-connected
|
|
// master watch must not start a subscription: it would have no stop signal
|
|
// and could run past the store close.
|
|
func TestOnPeerUpdateAfterShutdownRejected(t *testing.T) {
|
|
ma := NewMetaAggregator(nil, pb.ServerAddress("127.0.0.1:2"), nil)
|
|
ma.Shutdown()
|
|
|
|
peer := pb.ServerAddress("127.0.0.1:1")
|
|
ma.OnPeerUpdate(&master_pb.ClusterNodeUpdate{Address: string(peer), IsAdd: true}, time.Now())
|
|
|
|
ma.peerChansLock.Lock()
|
|
_, found := ma.peerChans[peer]
|
|
ma.peerChansLock.Unlock()
|
|
if found {
|
|
t.Fatal("peer subscription started after shutdown")
|
|
}
|
|
}
|