@@ -12,6 +12,7 @@ import (
12
12
"github.com/google/uuid"
13
13
"github.com/grafana/tempo/modules/blockbuilder/util"
14
14
"github.com/grafana/tempo/modules/overrides"
15
+ "github.com/grafana/tempo/pkg/boundedwaitgroup"
15
16
"github.com/grafana/tempo/pkg/livetraces"
16
17
"github.com/grafana/tempo/pkg/model"
17
18
"github.com/grafana/tempo/pkg/tempopb"
@@ -23,6 +24,7 @@ import (
23
24
"github.com/grafana/tempo/tempodb/wal"
24
25
"github.com/prometheus/client_golang/prometheus"
25
26
"github.com/prometheus/client_golang/prometheus/promauto"
27
+ "go.uber.org/atomic"
26
28
)
27
29
28
30
var metricBlockBuilderFlushedBlocks = promauto .NewCounterVec (
@@ -33,7 +35,10 @@ var metricBlockBuilderFlushedBlocks = promauto.NewCounterVec(
33
35
}, []string {"tenant" },
34
36
)
35
37
36
- const reasonTraceTooLarge = "trace_too_large"
38
+ const (
39
+ reasonTraceTooLarge = "trace_too_large"
40
+ flushConcurrency = 4
41
+ )
37
42
38
43
// TODO - This needs locking
39
44
type tenantStore struct {
@@ -192,34 +197,62 @@ func (s *tenantStore) Flush(ctx context.Context, store tempodb.Writer) error {
192
197
s .blocksMtx .Lock ()
193
198
defer s .blocksMtx .Unlock ()
194
199
195
- completeBlocks := make ([]tempodb.WriteableBlock , 0 , len (s .walBlocks ))
196
- // Write all blocks
197
- for _ , block := range s .walBlocks {
198
- completeBlock , err := s .buildWriteableBlock (ctx , block )
199
- if err != nil {
200
- return err
201
- }
200
+ var (
201
+ completeBlocks = make ([]tempodb.WriteableBlock , len (s .walBlocks ))
202
+ jobErr = atomic .NewError (nil )
203
+ wg = boundedwaitgroup .New (flushConcurrency )
204
+ )
205
+
206
+ // Convert WALs to backend blocks
207
+ for i , block := range s .walBlocks {
208
+ wg .Add (1 )
209
+ go func (i int , block common.WALBlock ) {
210
+ defer wg .Done ()
211
+
212
+ completeBlock , err := s .buildWriteableBlock (ctx , block )
213
+ if err != nil {
214
+ jobErr .Store (err )
215
+ return
216
+ }
202
217
203
- err = block .Clear ()
204
- if err != nil {
205
- return err
206
- }
218
+ err = block .Clear ()
219
+ if err != nil {
220
+ jobErr .Store (err )
221
+ return
222
+ }
207
223
208
- completeBlocks = append (completeBlocks , completeBlock )
224
+ completeBlocks [i ] = completeBlock
225
+ }(i , block )
226
+ }
227
+
228
+ wg .Wait ()
229
+ if err := jobErr .Load (); err != nil {
230
+ return err
209
231
}
210
232
211
- level .Info (s .logger ).Log ("msg" , "writing blocks to storage" , "num_blocks" , len (completeBlocks ))
212
233
// Write all blocks to the store
234
+ level .Info (s .logger ).Log ("msg" , "writing blocks to storage" , "num_blocks" , len (completeBlocks ))
213
235
for _ , block := range completeBlocks {
214
- level .Info (s .logger ).Log ("msg" , "writing block to storage" , "block_id" , block .BlockMeta ().BlockID .String ())
215
- if err := store .WriteBlock (ctx , block ); err != nil {
216
- return err
217
- }
218
- metricBlockBuilderFlushedBlocks .WithLabelValues (s .tenantID ).Inc ()
236
+ wg .Add (1 )
237
+ go func (block tempodb.WriteableBlock ) {
238
+ defer wg .Done ()
239
+ level .Info (s .logger ).Log ("msg" , "writing block to storage" , "block_id" , block .BlockMeta ().BlockID .String ())
240
+ if err := store .WriteBlock (ctx , block ); err != nil {
241
+ jobErr .Store (err )
242
+ return
243
+ }
219
244
220
- if err := s .wal .LocalBackend ().ClearBlock ((uuid .UUID )(block .BlockMeta ().BlockID ), s .tenantID ); err != nil {
221
- return err
222
- }
245
+ metricBlockBuilderFlushedBlocks .WithLabelValues (s .tenantID ).Inc ()
246
+
247
+ if err := s .wal .LocalBackend ().ClearBlock ((uuid .UUID )(block .BlockMeta ().BlockID ), s .tenantID ); err != nil {
248
+ jobErr .Store (err )
249
+ }
250
+ }(block )
251
+ }
252
+
253
+ wg .Wait ()
254
+ if err := jobErr .Load (); err != nil {
255
+ return err
223
256
}
224
257
225
258
// Clear the blocks
0 commit comments