initial commit
This commit is contained in:
15
pkg/cache/cache.go
vendored
Normal file
15
pkg/cache/cache.go
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package cache
|
||||
|
||||
import "io"
|
||||
|
||||
type Cache interface {
|
||||
Get(key string, writer io.Writer) error
|
||||
GetString(key string) (string, error)
|
||||
GetJSON(key string, value any) error
|
||||
|
||||
Set(key string, value io.Reader) error
|
||||
SetJSON(key string, value any) error
|
||||
SetString(key string, value string) error
|
||||
|
||||
Delete(key string) error
|
||||
}
|
160
pkg/cache/directory.go
vendored
Normal file
160
pkg/cache/directory.go
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Directory struct {
|
||||
BaseFolder string
|
||||
MaxLife time.Duration
|
||||
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
var _ Cache = &Directory{}
|
||||
|
||||
func (d *Directory) GetPath(key string) string {
|
||||
return filepath.Join(d.BaseFolder, key+".json")
|
||||
}
|
||||
|
||||
func (d *Directory) Cleanup(_ context.Context) error {
|
||||
d.lock.Lock()
|
||||
|
||||
defer func() {
|
||||
d.lock.Unlock()
|
||||
}()
|
||||
|
||||
// go through the BaseFilder looking for any files that are older than MaxLife
|
||||
return filepath.Walk(d.BaseFolder, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ignore directories
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// only files that end in .json
|
||||
if filepath.Ext(path) != ".json" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if the openFile is older than MaxLife, delete it
|
||||
if time.Since(info.ModTime()) > d.MaxLife {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// AutoCleanupRoutine will continually loop and cleanup the directory, until the context is cancelled or an error occurs
|
||||
// returns nil on context cancellation, or an error if one occurs during cleanup
|
||||
func (d *Directory) AutoCleanupRoutine(ctx context.Context) error {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
|
||||
case <-time.After(d.MaxLife):
|
||||
err := d.Cleanup(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Directory) openFile(key string) (*os.File, error) {
|
||||
path := d.GetPath(key)
|
||||
|
||||
return os.Open(path)
|
||||
}
|
||||
|
||||
func (d *Directory) Set(key string, value io.Reader) error {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
fp, err := d.openFile(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func(fp *os.File) {
|
||||
_ = fp.Close()
|
||||
}(fp)
|
||||
|
||||
_, err = io.Copy(fp, value)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Directory) SetJSON(key string, value any) error {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
fp, err := d.openFile(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func(fp *os.File) {
|
||||
_ = fp.Close()
|
||||
}(fp)
|
||||
|
||||
return json.NewEncoder(fp).Encode(value)
|
||||
}
|
||||
|
||||
func (d *Directory) SetString(key, value string) error {
|
||||
return d.Set(key, bytes.NewReader([]byte(value)))
|
||||
}
|
||||
|
||||
func (d *Directory) Get(key string, w io.Writer) error {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
fp, err := d.openFile(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
_, err = io.Copy(w, fp)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Directory) GetJSON(key string, v any) error {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
fp, err := d.openFile(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer fp.Close()
|
||||
|
||||
return json.NewEncoder(fp).Encode(v)
|
||||
}
|
||||
|
||||
func (d *Directory) GetString(key string) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
err := d.Get(key, &buf)
|
||||
return buf.String(), err
|
||||
}
|
||||
|
||||
func (d *Directory) Delete(key string) error {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
return os.Remove(d.GetPath(key))
|
||||
}
|
Reference in New Issue
Block a user