Class: Agent::Sessions::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/agent/sessions/session.rb

Overview

One recorded conversation. Everything here comes from a stat or the store's own metadata — except project_path, which may need to read inside the session file (design doc section 7: the on-disk directory encodings are lossy, so the recorded cwd inside the file is the only reliable source). It is computed on first access and memoized, which is why this is a plain class rather than a frozen Data: an instance is immutable except for that one memo.

Equality is identity, not value — unlike every sibling value object here, which gets value equality for free from Data. A value comparison would have to force project_path on both operands, turning a uniq over thousands of sessions into the full content sweep the design works to avoid. A caller keying a mixed-agent collection should use uid, which exists for exactly that. Note to_h includes uid, so its output does not round-trip back through new.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(agent:, id:, path:, started_at:, updated_at:, bytes:, format:, fidelity:, project_path: UNRESOLVED, &project_path_resolver) ⇒ Session

Returns a new instance of Session.



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/agent/sessions/session.rb', line 24

def initialize(agent:, id:, path:, started_at:, updated_at:, bytes:, format:, fidelity:,
               project_path: UNRESOLVED, &project_path_resolver)
  @agent = agent
  @id = id
  @path = path
  @started_at = started_at
  @updated_at = updated_at
  @bytes = bytes
  @format = format
  @fidelity = fidelity
  @project_path = project_path
  @project_path_resolver = project_path_resolver
end

Instance Attribute Details

#agentObject (readonly)

Returns the value of attribute agent.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def agent
  @agent
end

#bytesObject (readonly)

Returns the value of attribute bytes.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def bytes
  @bytes
end

#fidelityObject (readonly)

Returns the value of attribute fidelity.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def fidelity
  @fidelity
end

#formatObject (readonly)

Returns the value of attribute format.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def format
  @format
end

#idObject (readonly)

Returns the value of attribute id.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def id
  @id
end

#pathObject (readonly)

Returns the value of attribute path.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def path
  @path
end

#started_atObject (readonly)

Returns the value of attribute started_at.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def started_at
  @started_at
end

#updated_atObject (readonly)

Returns the value of attribute updated_at.



22
23
24
# File 'lib/agent/sessions/session.rb', line 22

def updated_at
  @updated_at
end

Instance Method Details

#inspectObject

Never calls project_path: inspecting a session in a debugger must not trigger the read that enumeration deliberately deferred.



67
68
69
70
71
72
# File 'lib/agent/sessions/session.rb', line 67

def inspect
  resolved = @project_path.equal?(UNRESOLVED) ? "(unresolved)" : @project_path.inspect
  "#<#{self.class.name} agent: #{agent.inspect}, id: #{id.inspect}, path: #{path.inspect}, " \
    "project_path: #{resolved}, started_at: #{started_at.inspect}, updated_at: #{updated_at.inspect}, " \
    "bytes: #{bytes.inspect}, format: #{format.inspect}, fidelity: #{fidelity.inspect}>"
end

#project_pathObject

A resolver that raises is deliberately not memoized: a failed read is not an answer, so the next call retries rather than freezing the failure in place.

Not thread-safe by design: concurrent first access can run the resolver more than once, but every run yields the same value and the assignment is atomic on MRI, so there is no torn read to guard against. Do not add a mutex.



47
48
49
50
51
52
53
# File 'lib/agent/sessions/session.rb', line 47

def project_path
  return @project_path unless @project_path.equal?(UNRESOLVED)

  @project_path = @project_path_resolver&.call
  @project_path_resolver = nil
  @project_path
end

#to_hObject

The honest full dump — includes project_path, so it forces that read. Callers listing thousands of sessions should build their own slimmer rows.



57
58
59
60
61
62
63
# File 'lib/agent/sessions/session.rb', line 57

def to_h
  {
    agent: agent, id: id, uid: uid, path: path, project_path: project_path,
    started_at: started_at, updated_at: updated_at,
    bytes: bytes, format: format, fidelity: fidelity
  }
end

#uidObject

Collision-free across a mixed-agent collection, where bare ids may repeat.



39
# File 'lib/agent/sessions/session.rb', line 39

def uid = "#{agent}:#{id}"