Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: match cache restore-keys in creation reverse order #2153

Merged
merged 4 commits into from
Jan 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion pkg/artifactcache/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"net/http"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync/atomic"
Expand Down Expand Up @@ -52,28 +53,28 @@
h.logger = logger

if dir == "" {
home, err := os.UserHomeDir()
if err != nil {
return nil, err
}
dir = filepath.Join(home, ".cache", "actcache")

Check warning on line 60 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L56-L60

Added lines #L56 - L60 were not covered by tests
}
if err := os.MkdirAll(dir, 0o755); err != nil {
return nil, err
}

Check warning on line 64 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L63-L64

Added lines #L63 - L64 were not covered by tests

h.dir = dir

storage, err := NewStorage(filepath.Join(dir, "cache"))
if err != nil {
return nil, err
}

Check warning on line 71 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L70-L71

Added lines #L70 - L71 were not covered by tests
h.storage = storage

if outboundIP != "" {
h.outboundIP = outboundIP

Check warning on line 75 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L75

Added line #L75 was not covered by tests
} else if ip := common.GetOutboundIP(); ip == nil {
return nil, fmt.Errorf("unable to determine outbound IP address")

Check warning on line 77 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L77

Added line #L77 was not covered by tests
} else {
h.outboundIP = ip.String()
}
Expand All @@ -92,16 +93,16 @@

listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) // listen on all interfaces
if err != nil {
return nil, err
}

Check warning on line 97 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L96-L97

Added lines #L96 - L97 were not covered by tests
server := &http.Server{
ReadHeaderTimeout: 2 * time.Second,
Handler: router,
}
go func() {
if err := server.Serve(listener); err != nil && errors.Is(err, net.ErrClosed) {
logger.Errorf("http serve: %v", err)
}

Check warning on line 105 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L104-L105

Added lines #L104 - L105 were not covered by tests
}()
h.listener = listener
h.server = server
Expand All @@ -118,14 +119,14 @@

func (h *Handler) Close() error {
if h == nil {
return nil
}

Check warning on line 123 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L122-L123

Added lines #L122 - L123 were not covered by tests
var retErr error
if h.server != nil {
err := h.server.Close()
if err != nil {
retErr = err
}

Check warning on line 129 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L128-L129

Added lines #L128 - L129 were not covered by tests
h.server = nil
}
if h.listener != nil {
Expand All @@ -134,8 +135,8 @@
err = nil
}
if err != nil {
retErr = err
}

Check warning on line 139 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L138-L139

Added lines #L138 - L139 were not covered by tests
h.listener = nil
}
return retErr
Expand Down Expand Up @@ -164,29 +165,29 @@

db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 170 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L168-L170

Added lines #L168 - L170 were not covered by tests
defer db.Close()

cache, err := h.findCache(db, keys, version)
if err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 177 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L175-L177

Added lines #L175 - L177 were not covered by tests
if cache == nil {
h.responseJSON(w, r, 204)
return
}

if ok, err := h.storage.Exist(cache.ID); err != nil {
h.responseJSON(w, r, 500, err)
return

Check warning on line 185 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L184-L185

Added lines #L184 - L185 were not covered by tests
} else if !ok {
_ = db.Delete(cache.ID, cache)
h.responseJSON(w, r, 204)
return
}

Check warning on line 190 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L187-L190

Added lines #L187 - L190 were not covered by tests
h.responseJSON(w, r, 200, map[string]any{
"result": "hit",
"archiveLocation": fmt.Sprintf("%s%s/artifacts/%d", h.ExternalURL(), urlBase, cache.ID),
Expand All @@ -208,15 +209,15 @@
cache.FillKeyVersionHash()
db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 214 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L212-L214

Added lines #L212 - L214 were not covered by tests
defer db.Close()
if err := db.FindOne(cache, bolthold.Where("KeyVersionHash").Eq(cache.KeyVersionHash)); err != nil {
if !errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 220 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L218-L220

Added lines #L218 - L220 were not covered by tests
} else {
h.responseJSON(w, r, 400, fmt.Errorf("already exist"))
return
Expand All @@ -226,14 +227,14 @@
cache.CreatedAt = now
cache.UsedAt = now
if err := db.Insert(bolthold.NextSequence(), cache); err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 232 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L230-L232

Added lines #L230 - L232 were not covered by tests
// write back id to db
if err := db.Update(cache.ID, cache); err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 237 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L235-L237

Added lines #L235 - L237 were not covered by tests
h.responseJSON(w, r, 200, map[string]any{
"cacheId": cache.ID,
})
Expand All @@ -250,17 +251,17 @@
cache := &Cache{}
db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 256 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L254-L256

Added lines #L254 - L256 were not covered by tests
defer db.Close()
if err := db.Get(id, cache); err != nil {
if errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id))
return
}
h.responseJSON(w, r, 500, err)
return

Check warning on line 264 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L263-L264

Added lines #L263 - L264 were not covered by tests
}

if cache.Complete {
Expand All @@ -274,8 +275,8 @@
return
}
if err := h.storage.Write(cache.ID, start, r.Body); err != nil {
h.responseJSON(w, r, 500, err)
}

Check warning on line 279 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L278-L279

Added lines #L278 - L279 were not covered by tests
h.useCache(id)
h.responseJSON(w, r, 200)
}
Expand All @@ -291,17 +292,17 @@
cache := &Cache{}
db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 297 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L295-L297

Added lines #L295 - L297 were not covered by tests
defer db.Close()
if err := db.Get(id, cache); err != nil {
if errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id))
return
}
h.responseJSON(w, r, 500, err)
return

Check warning on line 305 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L304-L305

Added lines #L304 - L305 were not covered by tests
}

if cache.Complete {
Expand All @@ -321,16 +322,16 @@

db, err = h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 327 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L325-L327

Added lines #L325 - L327 were not covered by tests
defer db.Close()

cache.Complete = true
if err := db.Update(cache.ID, cache); err != nil {
h.responseJSON(w, r, 500, err)
return
}

Check warning on line 334 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L332-L334

Added lines #L332 - L334 were not covered by tests

h.responseJSON(w, r, 200)
}
Expand Down Expand Up @@ -365,8 +366,8 @@
// if not found, return (nil, nil) instead of an error.
func (h *Handler) findCache(db *bolthold.Store, keys []string, version string) (*Cache, error) {
if len(keys) == 0 {
return nil, nil
}

Check warning on line 370 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L369-L370

Added lines #L369 - L370 were not covered by tests
key := keys[0] // the first key is for exact match.

cache := &Cache{
Expand All @@ -377,8 +378,8 @@

if err := db.FindOne(cache, bolthold.Where("KeyVersionHash").Eq(cache.KeyVersionHash)); err != nil {
if !errors.Is(err, bolthold.ErrNotFound) {
return nil, err
}

Check warning on line 382 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L381-L382

Added lines #L381 - L382 were not covered by tests
} else if cache.Complete {
return cache, nil
}
Expand All @@ -386,20 +387,25 @@

for _, prefix := range keys[1:] {
found := false
if err := db.ForEach(bolthold.Where("Key").Ge(prefix).And("Version").Eq(version).SortBy("Key"), func(v *Cache) error {
prefixPattern := fmt.Sprintf("^%s", regexp.QuoteMeta(prefix))
re, err := regexp.Compile(prefixPattern)
if err != nil {
continue

Check warning on line 393 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L393

Added line #L393 was not covered by tests
}
if err := db.ForEach(bolthold.Where("Key").RegExp(re).And("Version").Eq(version).SortBy("CreatedAt").Reverse(), func(v *Cache) error {
if !strings.HasPrefix(v.Key, prefix) {
return stop
}

Check warning on line 398 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L397-L398

Added lines #L397 - L398 were not covered by tests
if v.Complete {
cache = v
found = true
return stop
}
return nil

Check warning on line 404 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L404

Added line #L404 was not covered by tests
}); err != nil {
if !errors.Is(err, stop) {
return nil, err
}

Check warning on line 408 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L407-L408

Added lines #L407 - L408 were not covered by tests
}
if found {
return cache, nil
Expand All @@ -411,8 +417,8 @@
func (h *Handler) useCache(id int64) {
db, err := h.openDB()
if err != nil {
return
}

Check warning on line 421 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L420-L421

Added lines #L420 - L421 were not covered by tests
defer db.Close()
cache := &Cache{}
if err := db.Get(id, cache); err != nil {
Expand All @@ -424,11 +430,11 @@

func (h *Handler) gcCache() {
if atomic.LoadInt32(&h.gcing) != 0 {
return
}

Check warning on line 434 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L433-L434

Added lines #L433 - L434 were not covered by tests
if !atomic.CompareAndSwapInt32(&h.gcing, 0, 1) {
return
}

Check warning on line 437 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L436-L437

Added lines #L436 - L437 were not covered by tests
defer atomic.StoreInt32(&h.gcing, 0)

if time.Since(h.gcAt) < time.Hour {
Expand All @@ -446,52 +452,52 @@

db, err := h.openDB()
if err != nil {
return
}

Check warning on line 456 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L455-L456

Added lines #L455 - L456 were not covered by tests
defer db.Close()

var caches []*Cache
if err := db.Find(&caches, bolthold.Where("UsedAt").Lt(time.Now().Add(-keepTemp).Unix())); err != nil {
h.logger.Warnf("find caches: %v", err)

Check warning on line 461 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L461

Added line #L461 was not covered by tests
} else {
for _, cache := range caches {
if cache.Complete {
continue

Check warning on line 465 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L464-L465

Added lines #L464 - L465 were not covered by tests
}
h.storage.Remove(cache.ID)
if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err)
continue

Check warning on line 470 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L467-L470

Added lines #L467 - L470 were not covered by tests
}
h.logger.Infof("deleted cache: %+v", cache)

Check warning on line 472 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L472

Added line #L472 was not covered by tests
}
}

caches = caches[:0]
if err := db.Find(&caches, bolthold.Where("UsedAt").Lt(time.Now().Add(-keepUnused).Unix())); err != nil {
h.logger.Warnf("find caches: %v", err)

Check warning on line 478 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L478

Added line #L478 was not covered by tests
} else {
for _, cache := range caches {
h.storage.Remove(cache.ID)
if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err)
continue

Check warning on line 484 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L481-L484

Added lines #L481 - L484 were not covered by tests
}
h.logger.Infof("deleted cache: %+v", cache)

Check warning on line 486 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L486

Added line #L486 was not covered by tests
}
}

caches = caches[:0]
if err := db.Find(&caches, bolthold.Where("CreatedAt").Lt(time.Now().Add(-keepUsed).Unix())); err != nil {
h.logger.Warnf("find caches: %v", err)

Check warning on line 492 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L492

Added line #L492 was not covered by tests
} else {
for _, cache := range caches {
h.storage.Remove(cache.ID)
if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err)
continue

Check warning on line 498 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L495-L498

Added lines #L495 - L498 were not covered by tests
}
h.logger.Infof("deleted cache: %+v", cache)

Check warning on line 500 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L500

Added line #L500 was not covered by tests
}
}
}
Expand Down Expand Up @@ -524,7 +530,7 @@
}
stop, err := strconv.ParseInt(s2, 10, 64)
if err != nil {
return 0, 0, fmt.Errorf("parse %q: %w", s, err)
}

Check warning on line 534 in pkg/artifactcache/handler.go

View check run for this annotation

Codecov / codecov/patch

pkg/artifactcache/handler.go#L533-L534

Added lines #L533 - L534 were not covered by tests
return start, stop, nil
}
Loading