Skip to content

Commit

Permalink
[bugfix] fix poll vote count responses on client and fedi API vote cr…
Browse files Browse the repository at this point in the history
…eation (#2343)

* increment poll votes *before* enqueuing vote to client API worker

* increment vote counts before federating status update after vote in local poll

* improved vote count calculation during backend -> frontend model conversion
  • Loading branch information
NyaaaWhatsUpDoc authored Nov 8, 2023
1 parent e9e5dc5 commit 34d0879
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 24 deletions.
10 changes: 5 additions & 5 deletions internal/processing/polls/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ func (p *Processor) PollVote(ctx context.Context, requester *gtsmodel.Account, p
return nil, gtserror.NewErrorInternalError(err)
}

// Before enqueuing it, increment the poll
// vote counts on the copy attached to the
// PollVote (that we also later return).
poll.IncrementVotes(choices)

// Enqueue worker task to handle side-effects of user poll vote(s).
p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{
APActivityType: ap.ActivityCreate,
Expand All @@ -98,11 +103,6 @@ func (p *Processor) PollVote(ctx context.Context, requester *gtsmodel.Account, p
OriginAccount: requester,
})

// Before returning the converted poll model,
// increment the vote counts on our local copy
// to get latest, instead of another db query.
poll.IncrementVotes(choices)

// Return converted API model poll.
return p.toAPIPoll(ctx, requester, poll)
}
4 changes: 4 additions & 0 deletions internal/processing/workers/fromfediapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ func (p *fediAPI) CreatePollVote(ctx context.Context, fMsg messages.FromFediAPI)
p.surface.invalidateStatusFromTimelines(ctx, vote.Poll.StatusID)

if *status.Local {
// Before federating it, increment the
// poll vote counts on our local copy.
status.Poll.IncrementVotes(vote.Choices)

// These were poll votes in a local status, we need to
// federate the updated status model with latest vote counts.
if err := p.federate.UpdateStatus(ctx, status); err != nil {
Expand Down
37 changes: 18 additions & 19 deletions internal/typeutils/internaltofrontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -1310,13 +1310,21 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
}

var (
options []apimodel.PollOption
totalVotes int
totalVoters int
voteCounts []int
ownChoices []int
isAuthor bool
)

// Preallocate a slice of frontend model poll choices.
options = make([]apimodel.PollOption, len(poll.Options))

// Add the titles to all of the options.
for i, title := range poll.Options {
options[i].Title = title
}

if requester != nil {
// Get vote by requester in poll (if any).
vote, err := c.state.DB.GetPollVoteBy(ctx,
Expand All @@ -1335,45 +1343,36 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
// case that counts are hidden.
totalVotes = len(vote.Choices)
totalVoters = 1
for _, choice := range ownChoices {
options[choice].VotesCount++
}
}

// Check if requester is author of source status.
isAuthor = (requester.ID == poll.Status.AccountID)
}

// Preallocate a slice of frontend model poll choices.
options := make([]apimodel.PollOption, len(poll.Options))

// Add the titles to all of the options.
for i, title := range poll.Options {
options[i].Title = title
}

if isAuthor || !*poll.HideCounts {
// A remote status,
// the simple route!
//
// Pull cached remote values.
totalVoters = *poll.Voters
voteCounts = poll.Votes

// Accumulate total from all counts.
for _, count := range poll.Votes {
totalVotes += count
}
totalVoters = (*poll.Voters)

// When this is status author, or hide counts
// is disabled, set the counts known per vote.
for i, count := range voteCounts {
// is disabled, set the counts known per vote,
// and accumulate all the vote totals.
for i, count := range poll.Votes {
options[i].VotesCount = count
totalVotes += count
}
}

return &apimodel.Poll{
ID: poll.ID,
ExpiresAt: util.FormatISO8601(poll.ExpiresAt),
Expired: poll.Closed(),
Multiple: *poll.Multiple,
Multiple: (*poll.Multiple),
VotesCount: totalVotes,
VotersCount: totalVoters,
Voted: (isAuthor || len(ownChoices) > 0),
Expand Down

0 comments on commit 34d0879

Please sign in to comment.