Files
core/session/snapshot.go
2023-07-19 16:42:30 +02:00

98 lines
1.7 KiB
Go

package session
import (
"bytes"
"io"
"github.com/datarhei/core/v16/io/fs"
)
type SnapshotSource interface {
io.ReadCloser
}
type SnapshotSink interface {
io.WriteCloser
Cancel() error
}
type Snapshot interface {
Persist(sink SnapshotSink) error
Release()
}
type historySource struct {
fs fs.Filesystem
path string
data *bytes.Reader
}
// NewHistorySource returns a new SnapshotSource which reads the previously stored
// session history. If there's no data, a nil source with a nil error will be returned.
// If there's data, a non-nil source with a nil error will be returned. Otherwise
// the source will be nil and the error non-nil.
func NewHistorySource(filesystem fs.Filesystem, path string) (SnapshotSource, error) {
s := &historySource{
fs: filesystem,
path: path,
}
if _, err := s.fs.Stat(s.path); err != nil {
if err == fs.ErrNotExist {
return nil, nil
}
return nil, err
}
data, err := s.fs.ReadFile(s.path)
if err != nil {
return nil, err
}
s.data = bytes.NewReader(data)
return s, nil
}
func (s *historySource) Read(p []byte) (int, error) {
return s.data.Read(p)
}
func (s *historySource) Close() error {
s.data = nil
return nil
}
type historySink struct {
fs fs.Filesystem
path string
data *bytes.Buffer
}
func NewHistorySink(fs fs.Filesystem, path string) (SnapshotSink, error) {
s := &historySink{
fs: fs,
path: path,
data: &bytes.Buffer{},
}
return s, nil
}
func (s *historySink) Write(p []byte) (int, error) {
return s.data.Write(p)
}
func (s *historySink) Close() error {
_, _, err := s.fs.WriteFileSafe(s.path, s.data.Bytes())
s.data = nil
return err
}
func (s *historySink) Cancel() error {
s.data = nil
return nil
}