-
Notifications
You must be signed in to change notification settings - Fork 170
/
file_cache.go
74 lines (59 loc) · 1.77 KB
/
file_cache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package auth
import (
"errors"
"fmt"
"log"
"os"
"path/filepath"
"github.com/azure/azure-dev/cli/azd/pkg/osutil"
"github.com/gofrs/flock"
)
// fileCache implements Cache by storing the data to disk. The cache key is used as part of the
// filename for the stored object. Files are stored in [root] and are named [prefix][key].[ext].
//
// [root] is the root directory for the cache, and must be created beforehand.
type fileCache struct {
prefix string
root string
ext string
}
func (c *fileCache) Read(key string) ([]byte, error) {
cachePath := c.pathForCache(key)
lockPath := c.pathForLock(key)
fl := flock.New(lockPath)
if err := fl.Lock(); err != nil {
return nil, fmt.Errorf("locking file %s: %w", lockPath, err)
}
defer func() {
if err := fl.Unlock(); err != nil {
log.Printf("failed to release file lock: %v", err)
}
}()
contents, err := os.ReadFile(cachePath)
if errors.Is(err, os.ErrNotExist) {
return nil, errCacheKeyNotFound
}
return contents, err
}
func (c *fileCache) Set(key string, value []byte) error {
cachePath := c.pathForCache(key)
lockPath := c.pathForLock(key)
fl := flock.New(lockPath)
if err := fl.Lock(); err != nil {
return fmt.Errorf("locking file %s: %w", lockPath, err)
}
defer func() {
if err := fl.Unlock(); err != nil {
log.Printf("failed to release file lock: %v", err)
}
}()
return os.WriteFile(cachePath, value, osutil.PermissionFileOwnerOnly)
}
func (c *fileCache) pathForCache(key string) string {
return filepath.Join(c.root, fmt.Sprintf("%s%s.%s", c.prefix, key, c.ext))
}
func (c *fileCache) pathForLock(key string) string {
return filepath.Join(c.root, fmt.Sprintf("%s%s.%s.lock", c.prefix, key, c.ext))
}