Class: DiscordStore::Log::Record
- Inherits:
-
Object
- Object
- DiscordStore::Log::Record
- Defined in:
- lib/discord_store/log/record.rb
Overview
One entry in the log.
lsn is the Discord message ID, which is a snowflake, which means the log
sequence number is free, globally unique, and carries its own timestamp.
position disambiguates records packed into the same message.
Instance Attribute Summary collapse
-
#channel_id ⇒ Object
readonly
Returns the value of attribute channel_id.
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#lsn ⇒ Object
readonly
Returns the value of attribute lsn.
-
#nonce ⇒ Object
readonly
Returns the value of attribute nonce.
-
#position ⇒ Object
readonly
Returns the value of attribute position.
-
#stream ⇒ Object
readonly
Returns the value of attribute stream.
Class Method Summary collapse
- .from_wire(hash, lsn:, position:, channel_id: nil) ⇒ Record
-
.tombstone(stream:, target:) ⇒ Record
A record that marks
targetdeleted.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
-
#created_at ⇒ Time?
When Discord accepted this record.
-
#cursor ⇒ String?
A cursor that orders correctly within a partition.
- #hash ⇒ Object
-
#initialize(stream:, data:, nonce: nil, lsn: nil, position: 0, channel_id: nil) ⇒ Record
constructor
A new instance of Record.
- #inspect ⇒ Object
-
#to_wire ⇒ Hash
Wire form.
-
#tombstone? ⇒ Boolean
Whether this record marks a deleted predecessor.
Constructor Details
#initialize(stream:, data:, nonce: nil, lsn: nil, position: 0, channel_id: nil) ⇒ Record
Returns a new instance of Record.
18 19 20 21 22 23 24 25 |
# File 'lib/discord_store/log/record.rb', line 18 def initialize(stream:, data:, nonce: nil, lsn: nil, position: 0, channel_id: nil) @stream = stream.to_s @data = data @nonce = nonce || SecureRandom.uuid @lsn = lsn&.to_s @position = position @channel_id = channel_id&.to_s end |
Instance Attribute Details
#channel_id ⇒ Object (readonly)
Returns the value of attribute channel_id.
13 14 15 |
# File 'lib/discord_store/log/record.rb', line 13 def channel_id @channel_id end |
#data ⇒ Object (readonly)
Returns the value of attribute data.
13 14 15 |
# File 'lib/discord_store/log/record.rb', line 13 def data @data end |
#lsn ⇒ Object (readonly)
Returns the value of attribute lsn.
13 14 15 |
# File 'lib/discord_store/log/record.rb', line 13 def lsn @lsn end |
#nonce ⇒ Object (readonly)
Returns the value of attribute nonce.
13 14 15 |
# File 'lib/discord_store/log/record.rb', line 13 def nonce @nonce end |
#position ⇒ Object (readonly)
Returns the value of attribute position.
13 14 15 |
# File 'lib/discord_store/log/record.rb', line 13 def position @position end |
#stream ⇒ Object (readonly)
Returns the value of attribute stream.
13 14 15 |
# File 'lib/discord_store/log/record.rb', line 13 def stream @stream end |
Class Method Details
.from_wire(hash, lsn:, position:, channel_id: nil) ⇒ Record
56 57 58 59 60 61 62 63 |
# File 'lib/discord_store/log/record.rb', line 56 def self.from_wire(hash, lsn:, position:, channel_id: nil) unless hash.is_a?(Hash) && hash.key?("s") raise CorruptRecordError, "record at #{lsn}:#{position} is not a discord_store record" end new(stream: hash["s"], data: hash["d"], nonce: hash["n"], lsn: lsn, position: position, channel_id: channel_id) end |
.tombstone(stream:, target:) ⇒ Record
A record that marks target deleted. The log never rewrites history, so
a delete is an append like everything else.
71 72 73 |
# File 'lib/discord_store/log/record.rb', line 71 def self.tombstone(stream:, target:) new(stream: stream, data: { "__tombstone" => true, "target" => target.to_s }) end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
75 76 77 |
# File 'lib/discord_store/log/record.rb', line 75 def ==(other) other.is_a?(Record) && other.stream == stream && other.data == data && other.nonce == nonce end |
#created_at ⇒ Time?
When Discord accepted this record. Read straight out of the snowflake; no created_at column required.
31 32 33 |
# File 'lib/discord_store/log/record.rb', line 31 def created_at @lsn && Snowflake.at(@lsn) end |
#cursor ⇒ String?
A cursor that orders correctly within a partition.
38 39 40 |
# File 'lib/discord_store/log/record.rb', line 38 def cursor @lsn && format("%<lsn>s:%<position>04d", lsn: @lsn, position: @position) end |
#hash ⇒ Object
80 |
# File 'lib/discord_store/log/record.rb', line 80 def hash = [stream, data, nonce].hash |
#inspect ⇒ Object
82 83 84 85 |
# File 'lib/discord_store/log/record.rb', line 82 def inspect "#<DiscordStore::Log::Record stream=#{stream.inspect} lsn=#{lsn.inspect} " \ "position=#{position} data=#{data.inspect}>" end |
#to_wire ⇒ Hash
Wire form. Keys are short because every byte competes for the 2000 characters a message can hold, and a shorter key is one more record per request.
50 51 52 |
# File 'lib/discord_store/log/record.rb', line 50 def to_wire { "s" => stream, "n" => nonce, "d" => data } end |
#tombstone? ⇒ Boolean
Returns whether this record marks a deleted predecessor.
43 |
# File 'lib/discord_store/log/record.rb', line 43 def tombstone? = data.is_a?(Hash) && data["__tombstone"] == true |