You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

209 lines
7.4 KiB

package ec_vacuum
import (
"fmt"
"github.com/seaweedfs/seaweedfs/weed/admin/config"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/worker_pb"
"github.com/seaweedfs/seaweedfs/weed/worker/tasks/base"
)
// Config extends BaseConfig with EC vacuum specific settings
type Config struct {
base.BaseConfig
DeletionThreshold float64 `json:"deletion_threshold"` // Minimum deletion ratio to trigger vacuum
MinVolumeAgeSeconds int `json:"min_volume_age_seconds"` // Minimum age before considering vacuum (in seconds)
CollectionFilter string `json:"collection_filter"` // Filter by collection
MinSizeMB int `json:"min_size_mb"` // Minimum original volume size
}
// NewDefaultConfig creates a new default EC vacuum configuration
func NewDefaultConfig() *Config {
return &Config{
BaseConfig: base.BaseConfig{
Enabled: true,
ScanIntervalSeconds: 24 * 60 * 60, // 24 hours
MaxConcurrent: 1,
},
DeletionThreshold: 0.3, // 30% deletions trigger vacuum
MinVolumeAgeSeconds: 72 * 60 * 60, // 3 days minimum age (72 hours in seconds)
CollectionFilter: "", // No filter by default
MinSizeMB: 100, // 100MB minimum size
}
}
// GetConfigSpec returns the configuration schema for EC vacuum tasks
func GetConfigSpec() base.ConfigSpec {
return base.ConfigSpec{
Fields: []*config.Field{
{
Name: "enabled",
JSONName: "enabled",
Type: config.FieldTypeBool,
DefaultValue: true,
Required: false,
DisplayName: "Enable EC Vacuum Tasks",
Description: "Whether EC vacuum tasks should be automatically created",
HelpText: "Toggle this to enable or disable automatic EC vacuum task generation",
InputType: "checkbox",
CSSClasses: "form-check-input",
},
{
Name: "scan_interval_seconds",
JSONName: "scan_interval_seconds",
Type: config.FieldTypeInterval,
DefaultValue: 24 * 60 * 60,
MinValue: 6 * 60 * 60, // 6 hours minimum
MaxValue: 7 * 24 * 60 * 60, // 7 days maximum
Required: true,
DisplayName: "Scan Interval",
Description: "How often to scan for EC volumes needing vacuum",
HelpText: "The system will check for EC volumes with deletions at this interval",
Placeholder: "24",
Unit: config.UnitHours,
InputType: "interval",
CSSClasses: "form-control",
},
{
Name: "max_concurrent",
JSONName: "max_concurrent",
Type: config.FieldTypeInt,
DefaultValue: 1,
MinValue: 1,
MaxValue: 3,
Required: true,
DisplayName: "Max Concurrent Tasks",
Description: "Maximum number of EC vacuum tasks that can run simultaneously",
HelpText: "Limits the number of EC vacuum operations running at the same time",
Placeholder: "1 (default)",
Unit: config.UnitCount,
InputType: "number",
CSSClasses: "form-control",
},
{
Name: "deletion_threshold",
JSONName: "deletion_threshold",
Type: config.FieldTypeFloat,
DefaultValue: 0.3,
MinValue: 0.1,
MaxValue: 0.8,
Required: true,
DisplayName: "Deletion Threshold",
Description: "Minimum ratio of deletions to trigger vacuum",
HelpText: "EC volumes with this ratio of deleted content will be vacuumed",
Placeholder: "0.3 (30%)",
Unit: config.UnitNone,
InputType: "number",
CSSClasses: "form-control",
},
{
Name: "min_volume_age_seconds",
JSONName: "min_volume_age_seconds",
Type: config.FieldTypeInterval,
DefaultValue: 72 * 60 * 60, // 72 hours in seconds
MinValue: 24 * 60 * 60, // 24 hours in seconds
MaxValue: 30 * 24 * 60 * 60, // 30 days in seconds
Required: true,
DisplayName: "Minimum Volume Age",
Description: "Minimum age before considering EC volume for vacuum",
HelpText: "Only EC volumes older than this will be considered for vacuum",
Placeholder: "72",
Unit: config.UnitHours,
InputType: "interval",
CSSClasses: "form-control",
},
{
Name: "collection_filter",
JSONName: "collection_filter",
Type: config.FieldTypeString,
DefaultValue: "",
Required: false,
DisplayName: "Collection Filter",
Description: "Only vacuum EC volumes in this collection (empty = all collections)",
HelpText: "Leave empty to vacuum EC volumes in all collections",
Placeholder: "e.g., 'logs' or leave empty",
Unit: config.UnitNone,
InputType: "text",
CSSClasses: "form-control",
},
{
Name: "min_size_mb",
JSONName: "min_size_mb",
Type: config.FieldTypeInt,
DefaultValue: 100,
MinValue: 10,
MaxValue: 10000,
Required: true,
DisplayName: "Minimum Size (MB)",
Description: "Minimum original EC volume size to consider for vacuum",
HelpText: "Only EC volumes larger than this size will be considered for vacuum",
Placeholder: "100",
Unit: config.UnitNone,
InputType: "number",
CSSClasses: "form-control",
},
},
}
}
// ToTaskPolicy converts configuration to a TaskPolicy protobuf message
func (c *Config) ToTaskPolicy() *worker_pb.TaskPolicy {
return &worker_pb.TaskPolicy{
Enabled: c.Enabled,
MaxConcurrent: int32(c.MaxConcurrent),
RepeatIntervalSeconds: int32(c.ScanIntervalSeconds),
CheckIntervalSeconds: int32(c.ScanIntervalSeconds),
TaskConfig: &worker_pb.TaskPolicy_EcVacuumConfig{
EcVacuumConfig: &worker_pb.EcVacuumTaskConfig{
DeletionThreshold: c.DeletionThreshold,
MinVolumeAgeSeconds: int32(c.MinVolumeAgeSeconds),
CollectionFilter: c.CollectionFilter,
MinSizeMb: int32(c.MinSizeMB),
},
},
}
}
// FromTaskPolicy loads configuration from a TaskPolicy protobuf message
func (c *Config) FromTaskPolicy(policy *worker_pb.TaskPolicy) error {
if policy == nil {
return fmt.Errorf("policy is nil")
}
// Set general TaskPolicy fields
c.Enabled = policy.Enabled
c.MaxConcurrent = int(policy.MaxConcurrent)
c.ScanIntervalSeconds = int(policy.RepeatIntervalSeconds)
// Load EC vacuum-specific fields from TaskConfig field
if ecVacuumConfig := policy.GetEcVacuumConfig(); ecVacuumConfig != nil {
c.DeletionThreshold = ecVacuumConfig.DeletionThreshold
c.MinVolumeAgeSeconds = int(ecVacuumConfig.MinVolumeAgeSeconds)
c.CollectionFilter = ecVacuumConfig.CollectionFilter
c.MinSizeMB = int(ecVacuumConfig.MinSizeMb)
}
// If no EcVacuumConfig found, keep existing values (defaults)
return nil
}
// LoadConfigFromPersistence loads configuration from the persistence layer if available
func LoadConfigFromPersistence(configPersistence interface{}) *Config {
config := NewDefaultConfig()
// Try to load from persistence if available using generic method
if persistence, ok := configPersistence.(interface {
LoadTaskPolicyGeneric(taskType string) (*worker_pb.TaskPolicy, error)
}); ok {
if policy, err := persistence.LoadTaskPolicyGeneric("ec_vacuum"); err == nil && policy != nil {
if err := config.FromTaskPolicy(policy); err == nil {
glog.V(1).Infof("Loaded EC vacuum configuration from persistence")
return config
}
}
}
glog.V(1).Infof("Using default EC vacuum configuration")
return config
}