Commit 40065bbb authored by Anders Jensen Løvig's avatar Anders Jensen Løvig
Browse files

Fix race condition

parent 193d973e
Pipeline #21899 canceled with stages
......@@ -221,7 +221,7 @@ func (election *Election) nextPhase(reason Reason) {
if reason != ReasonVotes && election.Config.CloseSleep != 0 {
log.Printf("Election: waiting %s for late ballots\n", election.Config.CloseSleep)
election.Status.Phase = PhaseCloseWait
go delay(election, now, ReasonCloseTimeout, ReasonVotes, PhaseClosed)
delayAsync(election, now, ReasonCloseTimeout, ReasonVotes, PhaseClosed)
break
} else {
// If we received all votes go directly to next phase
......@@ -248,7 +248,7 @@ func (election *Election) nextPhase(reason Reason) {
if len(election.Agreement.ballotLists) < election.Participants.Servers && election.Config.CloseSleep != 0 {
election.Status.Phase = PhasePreTally
log.Printf("Election: waiting %s for ballots lists\n", election.Config.CloseSleep)
go delay(election, time.Now(), ReasonTallyTimeout, ReasonBallotList, PhaseTally)
delayAsync(election, time.Now(), ReasonTallyTimeout, ReasonBallotList, PhaseTally)
break
}
fallthrough
......@@ -296,20 +296,24 @@ func (election *Election) createResults() *Result {
}
}
func delay(e *Election, now time.Time, r1, r2 Reason, p Phase) {
var reason Reason
// Wait for timeout or all votes received.
select {
case <-time.After(time.Until(now.Add(e.Config.CloseSleep))):
reason = r1
case <-e.Status.PhaseChannel:
reason = r2
}
// Then next phase
e.Lock()
defer e.Unlock()
// Actually close the election
e.Status.Phase = p
e.nextPhase(reason)
func delayAsync(e *Election, now time.Time, r1, r2 Reason, p Phase) {
until := time.Until(now.Add(e.Config.CloseSleep))
go func() {
var reason Reason
// Wait for timeout or all votes received.
select {
case <-time.After(until):
reason = r1
case <-e.Status.PhaseChannel:
reason = r2
}
// Then next phase
e.Lock()
defer e.Unlock()
// Actually close the election
e.Status.Phase = p
e.nextPhase(reason)
}()
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment