Set snowflake IDs for backdated statuses (#5260)
- Rename Mastodon::TimestampIds into Mastodon::Snowflake for clarity - Skip for statuses coming from inbox, aka delivered in real-time - Skip for statuses that claim to be from the future
This commit is contained in:
parent
6e4046fc3f
commit
0717d9b3e6
16 changed files with 83 additions and 43 deletions
|
@ -1,8 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Mastodon::TimestampIds
|
||||
module Mastodon::Snowflake
|
||||
DEFAULT_REGEX = /timestamp_id\('(?<seq_prefix>\w+)'/
|
||||
|
||||
class Callbacks
|
||||
def self.around_create(record)
|
||||
now = Time.now.utc
|
||||
|
||||
if record.created_at.nil? || record.created_at >= now || record.created_at == record.updated_at
|
||||
yield
|
||||
else
|
||||
record.id = Mastodon::Snowflake.id_at(record.created_at)
|
||||
tries = 0
|
||||
|
||||
begin
|
||||
yield
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
raise if tries > 100
|
||||
|
||||
tries += 1
|
||||
record.id += rand(100)
|
||||
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
# Our ID will be composed of the following:
|
||||
# 6 bytes (48 bits) of millisecond-level timestamp
|
||||
|
@ -114,6 +138,13 @@ module Mastodon::TimestampIds
|
|||
end
|
||||
end
|
||||
|
||||
def id_at(timestamp)
|
||||
id = timestamp.to_i * 1000 + rand(1000)
|
||||
id = id << 16
|
||||
id += rand(2**16)
|
||||
id
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def already_defined?
|
Loading…
Add table
Add a link
Reference in a new issue