fix for the lock issue

This commit is contained in:
Radu Ioan Fericean
2015-04-03 22:33:16 +03:00
parent 8037f99cb8
commit eb60e6caf5
6 changed files with 20 additions and 67 deletions

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -18,24 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
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{