Files
yt-dlp-webui/server/memory_db.go

122 lines
2.7 KiB
Go

package server
import (
"errors"
"fmt"
"log"
"os"
"sync"
"github.com/goccy/go-json"
"github.com/google/uuid"
"github.com/marcopeocchi/yt-dlp-web-ui/server/cli"
)
// In-Memory volatile Thread-Safe Key-Value Storage
type MemoryDB struct {
table sync.Map
}
// Get a process pointer given its id
func (m *MemoryDB) Get(id string) (*Process, error) {
entry, ok := db.table.Load(id)
if !ok {
return nil, errors.New("no process found for the given key")
}
return entry.(*Process), nil
}
// Store a pointer of a process and return its id
func (m *MemoryDB) Set(process *Process) string {
id := uuid.Must(uuid.NewRandom()).String()
db.table.Store(id, process)
return id
}
// Update a process info/metadata, given the process id
func (m *MemoryDB) UpdateInfo(id string, info DownloadInfo) error {
entry, ok := db.table.Load(id)
if ok {
entry.(*Process).Info = info
db.table.Store(id, entry)
return nil
}
return fmt.Errorf("can't update row with id %s", id)
}
// Update a process progress data, given the process id
// Used for updating completition percentage or ETA
func (m *MemoryDB) UpdateProgress(id string, progress DownloadProgress) error {
entry, ok := db.table.Load(id)
if ok {
entry.(*Process).Progress = progress
db.table.Store(id, entry)
return nil
}
return fmt.Errorf("can't update row with id %s", id)
}
// Removes a process progress, given the process id
func (m *MemoryDB) Delete(id string) {
db.table.Delete(id)
}
func (m *MemoryDB) Keys() *[]string {
running := []string{}
db.table.Range(func(key, value any) bool {
running = append(running, key.(string))
return true
})
return &running
}
// Returns a slice of all currently stored processes progess
func (m *MemoryDB) All() *[]ProcessResponse {
running := []ProcessResponse{}
db.table.Range(func(key, value any) bool {
running = append(running, ProcessResponse{
Id: key.(string),
Info: value.(*Process).Info,
Progress: value.(*Process).Progress,
})
return true
})
return &running
}
// WIP: Persist the database in a single file named "session.dat"
func (m *MemoryDB) Persist() {
running := m.All()
session, err := json.Marshal(Session{
Processes: *running,
})
if err != nil {
log.Println(cli.Red, "Failed to persist database", cli.Reset)
return
}
err = os.WriteFile("session.dat", session, 0700)
if err != nil {
log.Println(cli.Red, "Failed to persist database", cli.Reset)
}
}
// WIP: Restore a persisted state
func (m *MemoryDB) Restore() {
feed, _ := os.ReadFile("session.dat")
session := Session{}
json.Unmarshal(feed, &session)
for _, proc := range session.Processes {
db.table.Store(proc.Id, &Process{
id: proc.Id,
url: proc.Info.URL,
Info: proc.Info,
Progress: proc.Progress,
mem: m,
})
}
}