Keeps the turns of one conversation, and writes them through Mead.Session.Store when the
session has a storage directory.
The state holds the turns with the newest first and the directory, or nil when persistence
is off. Only append/2 is write-first: a turn that cannot be recorded is refused and memory is
left untouched, so a conversation never accepts a turn it would forget. update_last/2 and
mark_interrupted/1 always change memory and then try to write, because the caller already
holds the answer; a closed turn that never reached the disk comes back after a restart as an
interrupted one, which is accurate.
When the file passes :compact_after_bytes the history rewrites it from memory with
Mead.Session.Store.compact/3; a failed rewrite is logged and never fails a write.
The agent is started before the session server, so a server crash leaves the history untouched.
Summary
Functions
Returns all turns in chronological order.
Records a turn as the newest one, or refuses it when it cannot be written.
Returns a specification to start this module under a supervisor.
Rewrites the file of the session as one record per turn, from the turns in memory.
Marks every turn still in progress as interrupted, and records that when there was one.
Starts the history for options[:session_id], registered under Mead.Registry.
Replaces the newest turn with the result of function applied to it.
Types
@type persistence_error() :: {:error, {:persistence, term()}}
Functions
@spec all(String.t()) :: [Mead.Session.Turn.t()]
Returns all turns in chronological order.
@spec append(String.t(), Mead.Session.Turn.t()) :: :ok | persistence_error()
Records a turn as the newest one, or refuses it when it cannot be written.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec compact(String.t()) :: {:ok, %{bytes_before: non_neg_integer(), bytes_after: non_neg_integer()}} | {:error, :not_found | :corrupt_history | {:persistence, term()}}
Rewrites the file of the session as one record per turn, from the turns in memory.
Returns the sizes before and after, {:error, :not_found} when there is no storage or no file
yet, or the persistence error; the original file is untouched on an error.
@spec mark_interrupted(String.t()) :: :ok | persistence_error()
Marks every turn still in progress as interrupted, and records that when there was one.
@spec start_link(keyword()) :: Agent.on_start()
Starts the history for options[:session_id], registered under Mead.Registry.
:directory is where to write (or nil), :resume is a list of turns in chronological
order to start from, and :compact_after_bytes is the file size from which the file is
compacted (absent means never). :max_turns is how many of the newest turns a compaction keeps
(absent means all).
@spec update_last(String.t(), (Mead.Session.Turn.t() -> Mead.Session.Turn.t())) :: :ok | persistence_error()
Replaces the newest turn with the result of function applied to it.
Memory changes even when the write fails; the error tells the caller the disk is behind.