From eb60e6caf59cebce071bbdd96486b076000458cb Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 3 Apr 2015 22:33:16 +0300 Subject: [PATCH] fix for the lock issue --- engine/account.go | 20 ++++++++------------ engine/accountlock.go | 11 ++--------- engine/calldesc.go | 6 +++--- engine/responder.go | 19 ++++++------------- engine/sharedgroup.go | 12 ------------ engine/sharedgroup_test.go | 19 +------------------ 6 files changed, 20 insertions(+), 67 deletions(-) diff --git a/engine/account.go b/engine/account.go index 3df7f04e4..293d5bdd6 100644 --- a/engine/account.go +++ b/engine/account.go @@ -566,19 +566,15 @@ func (ub *Account) GetSharedGroups() (groups []string) { return } -func (account *Account) GetUniqueSharedGroupMembers(destination, direction, category, unitType string) ([]string, error) { - creditBalances := account.getBalancesForPrefix(destination, category, account.BalanceMap[CREDIT+direction], "") - unitBalances := account.getBalancesForPrefix(destination, category, account.BalanceMap[unitType+direction], "") +func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) ([]string, error) { + var balances []*Balance + balances = append(balances, account.getBalancesForPrefix(cd.Destination, cd.Category, account.BalanceMap[CREDIT+cd.Direction], "")...) + balances = append(balances, account.getBalancesForPrefix(cd.Destination, cd.Category, account.BalanceMap[cd.TOR+cd.Direction], "")...) // gather all shared group ids var sharedGroupIds []string - for _, cb := range creditBalances { - if cb.SharedGroup != "" { - sharedGroupIds = append(sharedGroupIds, cb.SharedGroup) - } - } - for _, mb := range unitBalances { - if mb.SharedGroup != "" { - sharedGroupIds = append(sharedGroupIds, mb.SharedGroup) + for _, b := range balances { + if b.SharedGroup != "" { + sharedGroupIds = append(sharedGroupIds, b.SharedGroup) } } var memberIds []string @@ -588,7 +584,7 @@ func (account *Account) GetUniqueSharedGroupMembers(destination, direction, cate Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgID)) return nil, err } - for _, memberId := range sharedGroup.GetMembersExceptUser(account.Id) { + for _, memberId := range sharedGroup.MemberIds { if !utils.IsSliceMember(memberIds, memberId) { memberIds = append(memberIds, memberId) } diff --git a/engine/accountlock.go b/engine/accountlock.go index 18462122c..5184ce8f2 100644 --- a/engine/accountlock.go +++ b/engine/accountlock.go @@ -22,21 +22,14 @@ import ( "sync" ) -var AccLock *AccountLock - -func init() { - AccLock = NewAccountLock() -} +// global package variable +var AccLock = &AccountLock{queue: make(map[string]chan bool)} type AccountLock struct { queue map[string]chan bool mu sync.Mutex } -func NewAccountLock() *AccountLock { - return &AccountLock{queue: make(map[string]chan bool)} -} - func (cm *AccountLock) Guard(handler func() (interface{}, error), names ...string) (reply interface{}, err error) { cm.mu.Lock() for _, name := range names { diff --git a/engine/calldesc.go b/engine/calldesc.go index 0c61b104c..50f4dd8c4 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -501,7 +501,7 @@ func (cd *CallDescriptor) GetMaxSessionDuration() (duration time.Duration, err e Logger.Err(fmt.Sprintf("Could not get user balance for <%s>: %s.", cd.GetAccountKey(), err.Error())) return 0, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Category, cd.TOR); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd); err == nil { AccLock.Guard(func() (interface{}, error) { duration, err = cd.getMaxSessionDuration(account) return 0, err @@ -550,7 +550,7 @@ func (cd *CallDescriptor) Debit() (cc *CallCost, err error) { Logger.Err(fmt.Sprintf("Could not get user balance for <%s>: %s.", cd.GetAccountKey(), err.Error())) return nil, err } else { - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Category, cd.TOR); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd); err == nil { AccLock.Guard(func() (interface{}, error) { cc, err = cd.debit(account, false, true) return 0, err @@ -572,7 +572,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) { return nil, err } else { //log.Printf("ACC: %+v", account) - if memberIds, err := account.GetUniqueSharedGroupMembers(cd.Destination, cd.Direction, cd.Category, cd.TOR); err == nil { + if memberIds, err := account.GetUniqueSharedGroupMembers(cd); err == nil { AccLock.Guard(func() (interface{}, error) { remainingDuration, err := cd.getMaxSessionDuration(account) //log.Print("AFTER MAX SESSION: ", cd) diff --git a/engine/responder.go b/engine/responder.go index 0489a6eb4..cdfcd3b66 100644 --- a/engine/responder.go +++ b/engine/responder.go @@ -72,13 +72,11 @@ func (rs *Responder) Debit(arg CallDescriptor, reply *CallCost) (err error) { r, e := rs.getCallCost(&arg, "Responder.Debit") *reply, err = *r, e } else { - r, e := AccLock.Guard(func() (interface{}, error) { - return arg.Debit() - }, arg.GetAccountKey()) + r, e := arg.Debit() if e != nil { return e } else if r != nil { - *reply = *r.(*CallCost) + *reply = *r } } return @@ -89,13 +87,11 @@ func (rs *Responder) MaxDebit(arg CallDescriptor, reply *CallCost) (err error) { r, e := rs.getCallCost(&arg, "Responder.MaxDebit") *reply, err = *r, e } else { - r, e := AccLock.Guard(func() (interface{}, error) { - return arg.MaxDebit() - }, arg.GetAccountKey()) + r, e := arg.MaxDebit() if e != nil { return e } else if r != nil { - *reply = *r.(*CallCost) + *reply = *r } } return @@ -117,11 +113,8 @@ func (rs *Responder) GetMaxSessionTime(arg CallDescriptor, reply *float64) (err if rs.Bal != nil { *reply, err = rs.callMethod(&arg, "Responder.GetMaxSessionTime") } else { - r, e := AccLock.Guard(func() (interface{}, error) { - d, err := arg.GetMaxSessionDuration() - return float64(d), err - }, arg.GetAccountKey()) - *reply, err = r.(float64), e + r, e := arg.GetMaxSessionDuration() + *reply, err = float64(r), e } return } diff --git a/engine/sharedgroup.go b/engine/sharedgroup.go index abbdd2000..dc6295231 100644 --- a/engine/sharedgroup.go +++ b/engine/sharedgroup.go @@ -49,18 +49,6 @@ type SharingParameters struct { RatingSubject string } -func (sg *SharedGroup) GetMembersExceptUser(ubId string) []string { - for i, m := range sg.MemberIds { - if m == ubId { - a := make([]string, len(sg.MemberIds)) - copy(a, sg.MemberIds) - a[i], a = a[len(a)-1], a[:len(a)-1] - return a - } - } - return sg.MemberIds -} - func (sg *SharedGroup) SortBalancesByStrategy(myBalance *Balance, bc BalanceChain) BalanceChain { sharingParameters := sg.AccountParameters[utils.ANY] if sp, hasParamsForAccount := sg.AccountParameters[myBalance.account.Id]; hasParamsForAccount { diff --git a/engine/sharedgroup_test.go b/engine/sharedgroup_test.go index d5565f0ed..a521028de 100644 --- a/engine/sharedgroup_test.go +++ b/engine/sharedgroup_test.go @@ -18,24 +18,7 @@ along with this program. If not, see package engine -import ( - "reflect" - "testing" -) - -func TestSharedGroupGetMembersExcept(t *testing.T) { - sg := &SharedGroup{ - MemberIds: []string{"1", "2", "3"}, - } - a1 := sg.GetMembersExceptUser("1") - a2 := sg.GetMembersExceptUser("2") - a3 := sg.GetMembersExceptUser("3") - if !reflect.DeepEqual(a1, []string{"3", "2"}) || - !reflect.DeepEqual(a2, []string{"1", "3"}) || - !reflect.DeepEqual(a3, []string{"1", "2"}) { - t.Error("Error getting shared group members: ", a1, a2, a3) - } -} +import "testing" func TestSharedPopBalanceByStrategyLow(t *testing.T) { bc := BalanceChain{