1
1
package memory
2
2
3
3
import (
4
+ "context"
4
5
"flag"
5
6
"fmt"
6
7
"regexp"
@@ -47,10 +48,11 @@ var (
47
48
// metric idx.metrics_active is the number of currently known metrics in the index
48
49
statMetricsActive = stats .NewGauge32 ("idx.metrics_active" )
49
50
50
- Enabled bool
51
- matchCacheSize int
52
- TagSupport bool
53
- TagQueryWorkers int // number of workers to spin up when evaluation tag expressions
51
+ Enabled bool
52
+ matchCacheSize int
53
+ maxPruneLockTime = time .Millisecond * 100
54
+ TagSupport bool
55
+ TagQueryWorkers int // number of workers to spin up when evaluation tag expressions
54
56
)
55
57
56
58
func ConfigSetup () {
@@ -59,6 +61,7 @@ func ConfigSetup() {
59
61
memoryIdx .BoolVar (& TagSupport , "tag-support" , false , "enables/disables querying based on tags" )
60
62
memoryIdx .IntVar (& TagQueryWorkers , "tag-query-workers" , 50 , "number of workers to spin up to evaluate tag queries" )
61
63
memoryIdx .IntVar (& matchCacheSize , "match-cache-size" , 1000 , "size of regular expression cache in tag query evaluation" )
64
+ memoryIdx .DurationVar (& maxPruneLockTime , "max-prune-lock-time" , time .Millisecond * 100 , "Maximum duration each second a prune job can lock the index." )
62
65
globalconf .Register ("memory-idx" , memoryIdx )
63
66
}
64
67
@@ -1308,13 +1311,24 @@ DEFS:
1308
1311
}
1309
1312
m .RUnlock ()
1310
1313
1314
+ ctx , cancel := context .WithCancel (context .Background ())
1315
+ defer cancel ()
1316
+
1317
+ // create a new timeLimiter that allows us to limit the amount of time we spend
1318
+ // holding a lock to maxPruneLockTime (default 100ms) every second.
1319
+ tl := NewTimeLimiter (ctx , time .Second , maxPruneLockTime )
1320
+
1311
1321
for org , ids := range toPruneTagged {
1312
1322
if len (ids ) == 0 {
1313
1323
continue
1314
1324
}
1325
+ // make sure we are not locking for too long.
1326
+ tl .Wait ()
1327
+ lockStart := time .Now ()
1315
1328
m .Lock ()
1316
1329
defs := m .deleteTaggedByIdSet (org , ids )
1317
1330
m .Unlock ()
1331
+ tl .Add (time .Since (lockStart ))
1318
1332
pruned = append (pruned , defs ... )
1319
1333
}
1320
1334
@@ -1325,28 +1339,33 @@ ORGS:
1325
1339
}
1326
1340
1327
1341
for path := range paths {
1342
+ tl .Wait ()
1343
+ lockStart := time .Now ()
1328
1344
m .Lock ()
1329
1345
tree , ok := m .tree [org ]
1330
1346
1331
1347
if ! ok {
1332
1348
m .Unlock ()
1349
+ tl .Add (time .Since (lockStart ))
1333
1350
continue ORGS
1334
1351
}
1335
1352
1336
1353
n , ok := tree .Items [path ]
1337
1354
1338
1355
if ! ok {
1339
1356
m .Unlock ()
1357
+ tl .Add (time .Since (lockStart ))
1340
1358
log .Debug ("memory-idx: series %s for orgId:%d was identified for pruning but cannot be found." , path , org )
1341
1359
continue
1342
1360
}
1343
1361
1344
1362
log .Debug ("memory-idx: series %s for orgId:%d is stale. pruning it." , n .Path , org )
1345
1363
defs := m .delete (org , n , true , false )
1346
1364
m .Unlock ()
1365
+ tl .Add (time .Since (lockStart ))
1347
1366
pruned = append (pruned , defs ... )
1348
- }
1349
1367
1368
+ }
1350
1369
}
1351
1370
1352
1371
statMetricsActive .Add (- 1 * len (pruned ))
0 commit comments