From 8f1d25e372b09a70d4f9b81ebd31f7541ec30f61 Mon Sep 17 00:00:00 2001 From: Carson Ip Date: Tue, 4 Jun 2024 19:54:03 +0100 Subject: [PATCH] [exporterhelper] Fix shutdown hang on unstarted exporter Fixes #10306 --- exporter/exporterhelper/batch_sender.go | 9 ++++++--- exporter/exporterhelper/batch_sender_test.go | 9 +++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/exporter/exporterhelper/batch_sender.go b/exporter/exporterhelper/batch_sender.go index a22d78a6610..8c69c4c1f61 100644 --- a/exporter/exporterhelper/batch_sender.go +++ b/exporter/exporterhelper/batch_sender.go @@ -54,7 +54,7 @@ func newBatchSender(cfg exporterbatcher.Config, set exporter.CreateSettings, logger: set.Logger, mergeFunc: mf, mergeSplitFunc: msf, - shutdownCh: make(chan struct{}), + shutdownCh: nil, shutdownCompleteCh: make(chan struct{}), stopped: &atomic.Bool{}, resetTimerCh: make(chan struct{}), @@ -63,6 +63,7 @@ func newBatchSender(cfg exporterbatcher.Config, set exporter.CreateSettings, } func (bs *batchSender) Start(_ context.Context, _ component.Host) error { + bs.shutdownCh = make(chan struct{}) timer := time.NewTimer(bs.cfg.FlushTimeout) go func() { for { @@ -227,7 +228,9 @@ func (bs *batchSender) updateActiveBatch(ctx context.Context, req Request) { func (bs *batchSender) Shutdown(context.Context) error { bs.stopped.Store(true) - close(bs.shutdownCh) - <-bs.shutdownCompleteCh + if bs.shutdownCh != nil { + close(bs.shutdownCh) + <-bs.shutdownCompleteCh + } return nil } diff --git a/exporter/exporterhelper/batch_sender_test.go b/exporter/exporterhelper/batch_sender_test.go index c05f0dd54da..ebb84512de8 100644 --- a/exporter/exporterhelper/batch_sender_test.go +++ b/exporter/exporterhelper/batch_sender_test.go @@ -436,6 +436,15 @@ func TestBatchSender_WithBatcherOption(t *testing.T) { } } +func TestBatchSender_UnstartedShutdown(t *testing.T) { + be, err := newBaseExporter(defaultSettings, defaultDataType, newNoopObsrepSender, + WithBatcher(exporterbatcher.NewDefaultConfig(), WithRequestBatchFuncs(fakeBatchMergeFunc, fakeBatchMergeSplitFunc))) + require.NoError(t, err) + + err = be.Shutdown(context.Background()) + require.NoError(t, err) +} + // TestBatchSender_ShutdownDeadlock tests that the exporter does not deadlock when shutting down while a batch is being // merged. func TestBatchSender_ShutdownDeadlock(t *testing.T) {