Class: Tempest::CursorStore

Inherits:
Object
  • Object
show all
Defined in:
lib/tempest/cursor_store.rb

Overview

Persists the last-seen Jetstream ‘time_us` so a restarted tempest can hand the server a cursor and replay events from the previous session. Stored alongside session.json under XDG_CONFIG_HOME. Staleness is decided by the caller (StreamManager checks saved_at against its replay window).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path:) ⇒ CursorStore

Returns a new instance of CursorStore.



22
23
24
# File 'lib/tempest/cursor_store.rb', line 22

def initialize(path:)
  @path = path
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



26
27
28
# File 'lib/tempest/cursor_store.rb', line 26

def path
  @path
end

Class Method Details

.default_path(env = ENV) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/tempest/cursor_store.rb', line 13

def self.default_path(env = ENV)
  explicit = env["TEMPEST_CURSOR_PATH"]
  return explicit if explicit && !explicit.empty?

  base = env["XDG_CONFIG_HOME"]
  base = File.join(env["HOME"].to_s, ".config") if base.nil? || base.empty?
  File.join(base, "tempest", "cursor.json")
end

Instance Method Details

#clearObject



48
49
50
# File 'lib/tempest/cursor_store.rb', line 48

def clear
  File.delete(@path) if File.exist?(@path)
end

#loadObject



37
38
39
40
41
42
43
44
45
46
# File 'lib/tempest/cursor_store.rb', line 37

def load
  return nil unless File.exist?(@path)

  data = JSON.parse(File.read(@path))
  return nil unless data.is_a?(Hash) && data["time_us"] && data["saved_at"]

  { time_us: data["time_us"], saved_at: Time.iso8601(data["saved_at"]) }
rescue JSON::ParserError, ArgumentError
  nil
end

#save(time_us:, at: Time.now) ⇒ Object



28
29
30
31
32
33
34
35
# File 'lib/tempest/cursor_store.rb', line 28

def save(time_us:, at: Time.now)
  payload = { "time_us" => time_us, "saved_at" => at.utc.iso8601(6) }

  FileUtils.mkdir_p(File.dirname(@path))
  File.open(@path, File::WRONLY | File::CREAT | File::TRUNC, 0o600) do |io|
    io.write(JSON.generate(payload))
  end
end