Files
RenewCMS/internal/infrastructure/update/jsonJobStore.go
T

91 lines
1.7 KiB
Go

package update
import (
domain "RenewCMS/internal/domain/update"
"encoding/json"
"os"
"path/filepath"
"sync"
)
type JSONJobStore struct {
path string
mu sync.Mutex
}
var _ domain.JobStore = &JSONJobStore{}
func NewJSONJobStore(path string) *JSONJobStore {
store := &JSONJobStore{path: path}
store.failInterruptedJob()
return store
}
func (s *JSONJobStore) failInterruptedJob() {
job, found := s.read()
if !found || !job.IsRunning() {
return
}
job.State = domain.StateFailed
job.Error = domain.ErrorKindDownload
job.DownloadedBytes = 0
job.TotalBytes = 0
_ = s.write(job)
}
func (s *JSONJobStore) Load() (domain.Job, bool) {
s.mu.Lock()
defer s.mu.Unlock()
job, found := s.read()
if !found {
return domain.Job{}, false
}
if job.State == domain.StateReady && !fileExists(job.StagedBinary) {
return domain.Job{}, false
}
return job, true
}
func (s *JSONJobStore) Save(job domain.Job) error {
s.mu.Lock()
defer s.mu.Unlock()
return s.write(job)
}
func (s *JSONJobStore) read() (domain.Job, bool) {
content, err := os.ReadFile(s.path)
if err != nil {
return domain.Job{}, false
}
var job domain.Job
if err := json.Unmarshal(content, &job); err != nil || job.State == "" {
return domain.Job{}, false
}
return job, true
}
func (s *JSONJobStore) write(job domain.Job) error {
content, err := json.Marshal(job)
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(s.path), os.ModePerm); err != nil {
return err
}
temporary := s.path + ".tmp"
if err := os.WriteFile(temporary, content, statusFilePermissions); err != nil {
return err
}
return os.Rename(temporary, s.path)
}
func fileExists(path string) bool {
if path == "" {
return false
}
info, err := os.Stat(path)
return err == nil && !info.IsDir()
}