Add voters count support (#11917)
* Add voters count to polls * Add ActivityPub serialization and parsing of voters count * Add support for voters count in WebUI * Move incrementation of voters count out of redis lock * Reword “voters” to “people”
This commit is contained in:
parent
cfe2d1cc4a
commit
3babf8464b
13 changed files with 113 additions and 20 deletions
|
@ -28,6 +28,8 @@ class ActivityPub::ProcessPollService < BaseService
|
|||
end
|
||||
end
|
||||
|
||||
voters_count = @json['votersCount']
|
||||
|
||||
latest_options = items.map { |item| item['name'].presence || item['content'] }
|
||||
|
||||
# If for some reasons the options were changed, it invalidates all previous
|
||||
|
@ -39,7 +41,8 @@ class ActivityPub::ProcessPollService < BaseService
|
|||
last_fetched_at: Time.now.utc,
|
||||
expires_at: expires_at,
|
||||
options: latest_options,
|
||||
cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 }
|
||||
cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 },
|
||||
voters_count: voters_count
|
||||
)
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
poll.reload
|
||||
|
|
|
@ -174,7 +174,7 @@ class PostStatusService < BaseService
|
|||
def poll_attributes
|
||||
return if @options[:poll].blank?
|
||||
|
||||
@options[:poll].merge(account: @account)
|
||||
@options[:poll].merge(account: @account, voters_count: 0)
|
||||
end
|
||||
|
||||
def scheduled_options
|
||||
|
|
|
@ -12,12 +12,24 @@ class VoteService < BaseService
|
|||
@choices = choices
|
||||
@votes = []
|
||||
|
||||
ApplicationRecord.transaction do
|
||||
@choices.each do |choice|
|
||||
@votes << @poll.votes.create!(account: @account, choice: choice)
|
||||
already_voted = true
|
||||
|
||||
RedisLock.acquire(lock_options) do |lock|
|
||||
if lock.acquired?
|
||||
already_voted = @poll.votes.where(account: @account).exists?
|
||||
|
||||
ApplicationRecord.transaction do
|
||||
@choices.each do |choice|
|
||||
@votes << @poll.votes.create!(account: @account, choice: choice)
|
||||
end
|
||||
end
|
||||
else
|
||||
raise Mastodon::RaceConditionError
|
||||
end
|
||||
end
|
||||
|
||||
increment_voters_count! unless already_voted
|
||||
|
||||
ActivityTracker.increment('activity:interactions')
|
||||
|
||||
if @poll.account.local?
|
||||
|
@ -53,4 +65,18 @@ class VoteService < BaseService
|
|||
def build_json(vote)
|
||||
Oj.dump(serialize_payload(vote, ActivityPub::VoteSerializer))
|
||||
end
|
||||
|
||||
def increment_voters_count!
|
||||
unless @poll.voters_count.nil?
|
||||
@poll.voters_count = @poll.voters_count + 1
|
||||
@poll.save
|
||||
end
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
@poll.reload
|
||||
retry
|
||||
end
|
||||
|
||||
def lock_options
|
||||
{ redis: Redis.current, key: "vote:#{@poll.id}:#{@account.id}" }
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue