mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Sort item IDs before locking to prevent deadlock
applies to stats,thresholds and resources
This commit is contained in:
committed by
Dan Christian Bogos
parent
2a190c08c7
commit
5f66cd2220
@@ -20,7 +20,9 @@ package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -676,13 +678,17 @@ func (rS *ResourceService) matchingResourcesForEvent(tnt string, ev *utils.CGREv
|
||||
return
|
||||
}
|
||||
}
|
||||
rs = make(Resources, 0, len(rIDs))
|
||||
for resName := range rIDs {
|
||||
|
||||
// Lock items in sorted order to prevent AB-BA deadlock.
|
||||
itemIDs := slices.Sorted(maps.Keys(rIDs))
|
||||
|
||||
rs = make(Resources, 0, len(itemIDs))
|
||||
for _, id := range itemIDs {
|
||||
lkPrflID := guardian.Guardian.GuardIDs("",
|
||||
config.CgrConfig().GeneralCfg().LockingTimeout,
|
||||
resourceProfileLockKey(tnt, resName))
|
||||
resourceProfileLockKey(tnt, id))
|
||||
var rPrf *ResourceProfile
|
||||
if rPrf, err = rS.dm.GetResourceProfile(tnt, resName,
|
||||
if rPrf, err = rS.dm.GetResourceProfile(tnt, id,
|
||||
true, true, utils.NonTransactional); err != nil {
|
||||
guardian.Guardian.UnguardIDs(lkPrflID)
|
||||
if err == utils.ErrNotFound {
|
||||
|
||||
@@ -20,7 +20,9 @@ package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -174,13 +176,17 @@ func (sS *StatService) matchingStatQueuesForEvent(tnt string, statsIDs []string,
|
||||
return
|
||||
}
|
||||
}
|
||||
sqs = make(StatQueues, 0, len(sqIDs))
|
||||
for sqID := range sqIDs {
|
||||
|
||||
// Lock items in sorted order to prevent AB-BA deadlock.
|
||||
itemIDs := slices.Sorted(maps.Keys(sqIDs))
|
||||
|
||||
sqs = make(StatQueues, 0, len(itemIDs))
|
||||
for _, id := range itemIDs {
|
||||
lkPrflID := guardian.Guardian.GuardIDs("",
|
||||
config.CgrConfig().GeneralCfg().LockingTimeout,
|
||||
statQueueProfileLockKey(tnt, sqID))
|
||||
statQueueProfileLockKey(tnt, id))
|
||||
var sqPrfl *StatQueueProfile
|
||||
if sqPrfl, err = sS.dm.GetStatQueueProfile(tnt, sqID, true, true, utils.NonTransactional); err != nil {
|
||||
if sqPrfl, err = sS.dm.GetStatQueueProfile(tnt, id, true, true, utils.NonTransactional); err != nil {
|
||||
guardian.Guardian.UnguardIDs(lkPrflID)
|
||||
if err == utils.ErrNotFound {
|
||||
err = nil
|
||||
|
||||
@@ -20,13 +20,13 @@ package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"slices"
|
||||
|
||||
"github.com/cgrates/birpc/context"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/guardian"
|
||||
@@ -472,13 +472,17 @@ func (tS *ThresholdService) matchingThresholdsForEvent(tnt string, args *utils.C
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
ts = make(Thresholds, 0, len(tIDs))
|
||||
for tID := range tIDs {
|
||||
|
||||
// Lock items in sorted order to prevent AB-BA deadlock.
|
||||
itemIDs := slices.Sorted(maps.Keys(tIDs))
|
||||
|
||||
ts = make(Thresholds, 0, len(itemIDs))
|
||||
for _, id := range itemIDs {
|
||||
lkPrflID := guardian.Guardian.GuardIDs("",
|
||||
config.CgrConfig().GeneralCfg().LockingTimeout,
|
||||
thresholdProfileLockKey(tnt, tID))
|
||||
thresholdProfileLockKey(tnt, id))
|
||||
var tPrfl *ThresholdProfile
|
||||
if tPrfl, err = tS.dm.GetThresholdProfile(tnt, tID, true, true, utils.NonTransactional); err != nil {
|
||||
if tPrfl, err = tS.dm.GetThresholdProfile(tnt, id, true, true, utils.NonTransactional); err != nil {
|
||||
guardian.Guardian.UnguardIDs(lkPrflID)
|
||||
if err == utils.ErrNotFound {
|
||||
err = nil
|
||||
|
||||
Reference in New Issue
Block a user