harbor/src/pkg/cached/manager.go
Chenyu Zhang 1a1ce634cc
Fix the process of cache layer (#17010)
fix: fix cache layer issues (#16995,#16997,#16996,#17038)

1. Load config and initialize cache layer in jobservice(for GC)
2. Cache artifact by digest the key should contains repository name
3. Repository cache cleanup error when update
4. Skip save cache when request ctx in transaction

Signed-off-by: chlins <chenyuzh@vmware.com>
2022-07-06 16:11:53 +08:00

101 lines
3.1 KiB
Go

// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cached
import (
"context"
"fmt"
"github.com/goharbor/harbor/src/lib/cache"
"github.com/goharbor/harbor/src/lib/errors"
)
const (
// Resource type definitions
// ResourceTypeArtifact defines artifact type.
ResourceTypeArtifact = "artifact"
// ResourceTypeProject defines project type.
ResourceTypeProject = "project"
// ResourceTypeProject defines project metadata type.
ResourceTypeProjectMeta = "project_metadata"
// ResourceTypeRepository defines repository type.
ResourceTypeRepository = "repository"
// ResourceTypeManifest defines manifest type.
ResourceTypeManifest = "manifest"
)
// Manager is the interface for resource cache manager.
// Provides common interfaces for admin to view and manage resource cache.
type Manager interface {
// CacheClient returns the cache client.
CacheClient(ctx context.Context) cache.Cache
// ResourceType returns the resource type.
// eg. artifact、project、tag、repository
ResourceType(ctx context.Context) string
// CountCache returns current this resource occupied cache count.
CountCache(ctx context.Context) (int64, error)
// DeleteCache deletes specific cache by key.
DeleteCache(ctx context.Context, key string) error
// FlushAll flush this resource's all cache.
FlushAll(ctx context.Context) error
// TODO for more extensions like metrics.
}
// ObjectKey normalizes cache object key.
type ObjectKey struct {
// namespace as group or prefix, eg. artifact:id
namespace string
}
// NewObjectKey returns object key with namespace.
func NewObjectKey(ns string) *ObjectKey {
return &ObjectKey{namespace: ns}
}
// Format formats fields to string.
// eg. namespace: 'artifact'
// Format("id", 100, "digest", "aaa"): "artifact:id:100:digest:aaa"
func (ok *ObjectKey) Format(keysAndValues ...interface{}) (string, error) {
// keysAndValues must be paired.
if len(keysAndValues)%2 != 0 {
return "", errors.Errorf("invalid keysAndValues: %v", keysAndValues...)
}
s := ok.namespace
for i := 0; i < len(keysAndValues); i++ {
// even is key
if i%2 == 0 {
key, match := keysAndValues[i].(string)
if !match {
return "", errors.Errorf("key must be string, invalid key type: %#v", keysAndValues[i])
}
s += fmt.Sprintf(":%s", key)
} else {
switch keysAndValues[i].(type) {
case int, int16, int32, int64:
s += fmt.Sprintf(":%d", keysAndValues[i])
case string:
s += fmt.Sprintf(":%s", keysAndValues[i])
default:
return "", errors.Errorf("unsupported value type: %#v", keysAndValues[i])
}
}
}
return s, nil
}