2023-06-29 09:13:01 +00:00
|
|
|
package policer
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
|
|
|
objectcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
2024-05-16 09:26:49 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object/util"
|
2023-06-29 09:13:01 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object_manager/placement"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/replicator"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
|
|
|
netmapSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
|
|
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
|
|
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
|
|
|
"github.com/panjf2000/ants/v2"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
// KeySpaceIterator is the interface that allows iterating over the key space
|
|
|
|
// of local storage.
|
|
|
|
// Note that the underlying implementation might be circular: i.e. it can restart
|
|
|
|
// when the end of the key space is reached.
|
|
|
|
type KeySpaceIterator interface {
|
2024-05-13 13:50:21 +00:00
|
|
|
Next(context.Context, uint32) ([]objectcore.Info, error)
|
2023-07-06 15:23:52 +00:00
|
|
|
Rewind()
|
2023-06-29 09:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RedundantCopyCallback is a callback to pass
|
|
|
|
// the redundant local copy of the object.
|
|
|
|
type RedundantCopyCallback func(context.Context, oid.Address)
|
|
|
|
|
|
|
|
// BuryFunc is the function to bury (i.e. inhume) an object.
|
|
|
|
type BuryFunc func(context.Context, oid.Address) error
|
|
|
|
|
|
|
|
// Replicator is the interface to a consumer of replication tasks.
|
|
|
|
type Replicator interface {
|
2024-05-13 13:50:21 +00:00
|
|
|
HandleReplicationTask(ctx context.Context, task replicator.Task, res replicator.TaskResult)
|
2024-05-14 11:43:21 +00:00
|
|
|
HandlePullTask(ctx context.Context, task replicator.Task)
|
2024-05-16 09:26:49 +00:00
|
|
|
HandleLocalPutTask(ctx context.Context, task replicator.Task)
|
2023-06-29 09:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RemoteObjectHeaderFunc is the function to obtain HEAD info from a specific remote node.
|
2024-05-14 11:43:21 +00:00
|
|
|
type RemoteObjectHeaderFunc func(context.Context, netmapSDK.NodeInfo, oid.Address, bool) (*objectSDK.Object, error)
|
|
|
|
|
|
|
|
// LocalObjectHeaderFunc is the function to obtain HEAD info from the current node.
|
|
|
|
type LocalObjectHeaderFunc func(context.Context, oid.Address) (*objectSDK.Object, error)
|
2023-06-29 09:13:01 +00:00
|
|
|
|
2024-05-16 09:26:49 +00:00
|
|
|
type RemoteObjectGetFunc func(context.Context, netmapSDK.NodeInfo, oid.Address) (*objectSDK.Object, error)
|
|
|
|
|
|
|
|
type LocalObjectGetFunc func(context.Context, oid.Address) (*objectSDK.Object, error)
|
|
|
|
|
2023-06-29 09:13:01 +00:00
|
|
|
type cfg struct {
|
|
|
|
headTimeout time.Duration
|
|
|
|
|
|
|
|
log *logger.Logger
|
|
|
|
|
|
|
|
keySpaceIterator KeySpaceIterator
|
|
|
|
|
|
|
|
buryFn BuryFunc
|
|
|
|
|
|
|
|
cnrSrc container.Source
|
|
|
|
|
|
|
|
placementBuilder placement.Builder
|
|
|
|
|
|
|
|
remoteHeader RemoteObjectHeaderFunc
|
|
|
|
|
2024-05-14 11:43:21 +00:00
|
|
|
localHeader LocalObjectHeaderFunc
|
|
|
|
|
2023-06-29 09:13:01 +00:00
|
|
|
netmapKeys netmap.AnnouncedKeys
|
|
|
|
|
|
|
|
replicator Replicator
|
|
|
|
|
|
|
|
cbRedundantCopy RedundantCopyCallback
|
|
|
|
|
|
|
|
taskPool *ants.Pool
|
|
|
|
|
|
|
|
batchSize, cacheSize uint32
|
|
|
|
|
2024-04-27 12:24:11 +00:00
|
|
|
evictDuration, sleepDuration time.Duration
|
2023-10-04 16:20:59 +00:00
|
|
|
|
|
|
|
metrics MetricsRegister
|
2024-05-16 09:26:49 +00:00
|
|
|
|
|
|
|
remoteObject RemoteObjectGetFunc
|
|
|
|
|
|
|
|
localObject LocalObjectGetFunc
|
|
|
|
|
|
|
|
keyStorage *util.KeyStorage
|
2023-06-29 09:13:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func defaultCfg() *cfg {
|
|
|
|
return &cfg{
|
2024-10-21 07:22:54 +00:00
|
|
|
log: logger.NewLoggerWrapper(zap.L()),
|
2023-06-29 09:13:01 +00:00
|
|
|
batchSize: 10,
|
|
|
|
cacheSize: 1024, // 1024 * address size = 1024 * 64 = 64 MiB
|
2023-07-06 15:29:16 +00:00
|
|
|
sleepDuration: 1 * time.Second,
|
2023-06-29 09:13:01 +00:00
|
|
|
evictDuration: 30 * time.Second,
|
2023-10-11 12:13:28 +00:00
|
|
|
metrics: noopMetrics{},
|
2023-06-29 09:13:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Option is an option for Policer constructor.
|
|
|
|
type Option func(*cfg)
|
|
|
|
|
|
|
|
// WithHeadTimeout returns option to set Head timeout of Policer.
|
|
|
|
func WithHeadTimeout(v time.Duration) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.headTimeout = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithLogger returns option to set Logger of Policer.
|
|
|
|
func WithLogger(v *logger.Logger) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.log = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithKeySpaceIterator(it KeySpaceIterator) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.keySpaceIterator = it
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithBuryFunc(f BuryFunc) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.buryFn = f
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithContainerSource returns option to set container source of Policer.
|
|
|
|
func WithContainerSource(v container.Source) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.cnrSrc = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithPlacementBuilder returns option to set object placement builder of Policer.
|
|
|
|
func WithPlacementBuilder(v placement.Builder) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.placementBuilder = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-14 15:05:55 +00:00
|
|
|
// WithRemoteObjectHeaderFunc returns option to set remote object header receiver of Policer.
|
2023-06-29 09:13:01 +00:00
|
|
|
func WithRemoteObjectHeaderFunc(v RemoteObjectHeaderFunc) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.remoteHeader = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-14 11:43:21 +00:00
|
|
|
// WithLocalObjectHeaderFunc returns option to set local object header receiver of Policer.
|
|
|
|
func WithLocalObjectHeaderFunc(v LocalObjectHeaderFunc) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.localHeader = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-16 09:26:49 +00:00
|
|
|
func WithRemoteObjectGetFunc(v RemoteObjectGetFunc) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.remoteObject = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithLocalObjectGetFunc(v LocalObjectGetFunc) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.localObject = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-29 09:13:01 +00:00
|
|
|
// WithNetmapKeys returns option to set tool to work with announced public keys.
|
|
|
|
func WithNetmapKeys(v netmap.AnnouncedKeys) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.netmapKeys = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithReplicator returns option to set object replicator of Policer.
|
|
|
|
func WithReplicator(v Replicator) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.replicator = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithRedundantCopyCallback returns option to set
|
|
|
|
// callback to pass redundant local object copies
|
|
|
|
// detected by Policer.
|
|
|
|
func WithRedundantCopyCallback(cb RedundantCopyCallback) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.cbRedundantCopy = cb
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithPool returns option to set pool for
|
|
|
|
// policy and replication operations.
|
|
|
|
func WithPool(p *ants.Pool) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.taskPool = p
|
|
|
|
}
|
|
|
|
}
|
2023-10-11 12:13:28 +00:00
|
|
|
|
|
|
|
// WithMetrics returns option to set metrics.
|
|
|
|
func WithMetrics(m MetricsRegister) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.metrics = m
|
|
|
|
}
|
|
|
|
}
|
2024-05-16 09:26:49 +00:00
|
|
|
|
|
|
|
func WithKeyStorage(ks *util.KeyStorage) Option {
|
|
|
|
return func(c *cfg) {
|
|
|
|
c.keyStorage = ks
|
|
|
|
}
|
|
|
|
}
|