Hi guys I am trying to make a party system using websockets where people can enter a queue and then get matched with 5 people similar to them. Right now I'm having trouble with this part:
type PartyHub struct {
Partys map[string]*Party
PartialPartys []*PartialParty
Queue []*Member
AddParty chan *Party
RemoveParty chan *Party
AddPartialParty chan *PartialParty
RemovePartialParty chan *PartialParty
EnterQueue chan *Member
LeaveQueue chan *Member
Mu sync.Mutex
}
// Run will begin monitoring the channels
// to register and unregister partys as they are
// created or destroyed
func (p *PartyHub) Run() {
for {
select {
case member := <-p.EnterQueue:
go p.SortMemberIntoParty(member)
go p.SortMemberIntoParty(member)
go p.SortMemberIntoParty(member)
go p.SortMemberIntoParty(member)
go p.SortMemberIntoParty(member)
log.Println(p.PartialPartys)
case party := <-p.AddPartialParty:
p.Mu.Lock()
defer p.Mu.Unlock()
p.PartialPartys = append(p.PartialPartys, party)
}
}
}
// SortMemberIntoParty will take a new user entering the queue and find an appropriate Party
// for the member to join, taking into account RankTollerance, Rank
func (p *PartyHub) SortMemberIntoParty(member *Member) {
p.Mu.Lock()
defer p.Mu.Unlock()
if len(p.PartialPartys) == 0 {
log.Println("Here")
newParty := &PartialParty{Accepting: true, Members: []*Member{member}}
p.AddPartialParty <- newParty
return
}
foundPartyForMember := false
for _, party := range p.PartialPartys {
goodFitForParty := true
for _, partyMember := range party.Members {
log.Println(member.Type == partyMember.Type, member.Rank >= partyMember.Rank-partyMember.RankTol, member.Rank <= partyMember.Rank+partyMember.RankTol)
if member.Type == partyMember.Type && member.Rank >= partyMember.Rank-partyMember.RankTol && member.Rank <= partyMember.Rank+partyMember.RankTol {
goodFitForParty = true
continue
} else {
goodFitForParty = false
break
}
}
if !goodFitForParty {
continue
} else {
foundPartyForMember = true
party.Mu.Lock()
defer party.Mu.Unlock()
party.Members = append(party.Members, member)
if len(party.Members) == 5 {
party.Accepting = false
go party.SendReadyCheck()
}
break
}
}
if !foundPartyForMember {
newParty := &PartialParty{Accepting: true, Members: []*Member{member}}
p.AddPartialParty <- newParty
}
log.Println("Sorting Members")
}
The only problem is, the 5 goroutines
seem to finish quicker than the data knows what happened.
For example: p.PartialPartys
says it has no parties.
What I need is to have p.PartialPartys
always up to date for every goroutine
that accesses that field of the PartyHub
struct I though the sync.Mutex
would do this for me but it doesn't seem to be the case, can anybody tell me the best way to keep all my goroutines in sync with the same data?