shad-go/distbuild/pkg/filecache/filecache.go

112 lines
2.1 KiB
Go
Raw Normal View History

2020-03-10 12:08:59 +00:00
package filecache
import (
"errors"
"io"
"os"
"path/filepath"
2020-03-10 12:08:59 +00:00
2023-10-02 19:32:41 +00:00
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/artifact"
"gitlab.com/manytask/itmo-go/private/distbuild/pkg/build"
2020-03-10 12:08:59 +00:00
)
var (
ErrNotFound = errors.New("file not found")
2020-04-04 18:45:29 +00:00
ErrExists = errors.New("file exists")
2020-03-10 12:08:59 +00:00
ErrWriteLocked = errors.New("file is locked for write")
ErrReadLocked = errors.New("file is locked for read")
)
const fileName = "file"
func convertErr(err error) error {
switch {
case errors.Is(err, artifact.ErrNotFound):
return ErrNotFound
case errors.Is(err, artifact.ErrExists):
return ErrExists
case errors.Is(err, artifact.ErrWriteLocked):
return ErrWriteLocked
case errors.Is(err, artifact.ErrReadLocked):
return ErrReadLocked
default:
return err
}
}
2020-03-10 12:08:59 +00:00
type Cache struct {
cache *artifact.Cache
2020-03-10 12:08:59 +00:00
}
func New(rootDir string) (*Cache, error) {
cache, err := artifact.NewCache(rootDir)
if err != nil {
return nil, err
}
c := &Cache{cache: cache}
return c, nil
2020-03-10 12:08:59 +00:00
}
func (c *Cache) Range(fileFn func(file build.ID) error) error {
return c.cache.Range(fileFn)
2020-03-10 12:08:59 +00:00
}
func (c *Cache) Remove(file build.ID) error {
return convertErr(c.cache.Remove(file))
}
type fileWriter struct {
f *os.File
commit func() error
}
func (f *fileWriter) Write(p []byte) (int, error) {
return f.f.Write(p)
}
func (f *fileWriter) Close() error {
closeErr := f.f.Close()
commitErr := f.commit()
if closeErr != nil {
return closeErr
}
return commitErr
}
func (c *Cache) Write(file build.ID) (w io.WriteCloser, abort func() error, err error) {
path, commit, abortDir, err := c.cache.Create(file)
if err != nil {
err = convertErr(err)
return
}
f, err := os.Create(filepath.Join(path, fileName))
if err != nil {
_ = abort()
return
}
w = &fileWriter{f: f, commit: commit}
abort = func() error {
closeErr := f.Close()
abortErr := abortDir()
if closeErr != nil {
return closeErr
}
return abortErr
}
return
2020-03-10 12:08:59 +00:00
}
func (c *Cache) Get(file build.ID) (path string, unlock func(), err error) {
root, unlock, err := c.cache.Get(file)
path = filepath.Join(root, fileName)
err = convertErr(err)
return
2020-03-10 12:08:59 +00:00
}