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.
		
		
		
		
		
			
		
			
				
					
					
						
							207 lines
						
					
					
						
							6.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							207 lines
						
					
					
						
							6.8 KiB
						
					
					
				
								package erasure_coding
							 | 
						|
								
							 | 
						|
								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 erasure coding specific settings
							 | 
						|
								type Config struct {
							 | 
						|
									base.BaseConfig
							 | 
						|
									QuietForSeconds  int     `json:"quiet_for_seconds"`
							 | 
						|
									FullnessRatio    float64 `json:"fullness_ratio"`
							 | 
						|
									CollectionFilter string  `json:"collection_filter"`
							 | 
						|
									MinSizeMB        int     `json:"min_size_mb"`
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// NewDefaultConfig creates a new default erasure coding configuration
							 | 
						|
								func NewDefaultConfig() *Config {
							 | 
						|
									return &Config{
							 | 
						|
										BaseConfig: base.BaseConfig{
							 | 
						|
											Enabled:             true,
							 | 
						|
											ScanIntervalSeconds: 60 * 60, // 1 hour
							 | 
						|
											MaxConcurrent:       1,
							 | 
						|
										},
							 | 
						|
										QuietForSeconds:  300, // 5 minutes
							 | 
						|
										FullnessRatio:    0.8, // 80%
							 | 
						|
										CollectionFilter: "",
							 | 
						|
										MinSizeMB:        30, // 30MB (more reasonable than 100MB)
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// GetConfigSpec returns the configuration schema for erasure coding tasks
							 | 
						|
								func GetConfigSpec() base.ConfigSpec {
							 | 
						|
									return base.ConfigSpec{
							 | 
						|
										Fields: []*config.Field{
							 | 
						|
											{
							 | 
						|
												Name:         "enabled",
							 | 
						|
												JSONName:     "enabled",
							 | 
						|
												Type:         config.FieldTypeBool,
							 | 
						|
												DefaultValue: true,
							 | 
						|
												Required:     false,
							 | 
						|
												DisplayName:  "Enable Erasure Coding Tasks",
							 | 
						|
												Description:  "Whether erasure coding tasks should be automatically created",
							 | 
						|
												HelpText:     "Toggle this to enable or disable automatic erasure coding task generation",
							 | 
						|
												InputType:    "checkbox",
							 | 
						|
												CSSClasses:   "form-check-input",
							 | 
						|
											},
							 | 
						|
											{
							 | 
						|
												Name:         "scan_interval_seconds",
							 | 
						|
												JSONName:     "scan_interval_seconds",
							 | 
						|
												Type:         config.FieldTypeInterval,
							 | 
						|
												DefaultValue: 60 * 60,
							 | 
						|
												MinValue:     10 * 60,
							 | 
						|
												MaxValue:     24 * 60 * 60,
							 | 
						|
												Required:     true,
							 | 
						|
												DisplayName:  "Scan Interval",
							 | 
						|
												Description:  "How often to scan for volumes needing erasure coding",
							 | 
						|
												HelpText:     "The system will check for volumes that need erasure coding at this interval",
							 | 
						|
												Placeholder:  "1",
							 | 
						|
												Unit:         config.UnitHours,
							 | 
						|
												InputType:    "interval",
							 | 
						|
												CSSClasses:   "form-control",
							 | 
						|
											},
							 | 
						|
											{
							 | 
						|
												Name:         "max_concurrent",
							 | 
						|
												JSONName:     "max_concurrent",
							 | 
						|
												Type:         config.FieldTypeInt,
							 | 
						|
												DefaultValue: 1,
							 | 
						|
												MinValue:     1,
							 | 
						|
												MaxValue:     5,
							 | 
						|
												Required:     true,
							 | 
						|
												DisplayName:  "Max Concurrent Tasks",
							 | 
						|
												Description:  "Maximum number of erasure coding tasks that can run simultaneously",
							 | 
						|
												HelpText:     "Limits the number of erasure coding operations running at the same time",
							 | 
						|
												Placeholder:  "1 (default)",
							 | 
						|
												Unit:         config.UnitCount,
							 | 
						|
												InputType:    "number",
							 | 
						|
												CSSClasses:   "form-control",
							 | 
						|
											},
							 | 
						|
											{
							 | 
						|
												Name:         "quiet_for_seconds",
							 | 
						|
												JSONName:     "quiet_for_seconds",
							 | 
						|
												Type:         config.FieldTypeInterval,
							 | 
						|
												DefaultValue: 300,
							 | 
						|
												MinValue:     60,
							 | 
						|
												MaxValue:     3600,
							 | 
						|
												Required:     true,
							 | 
						|
												DisplayName:  "Quiet Period",
							 | 
						|
												Description:  "Minimum time volume must be quiet before erasure coding",
							 | 
						|
												HelpText:     "Volume must not be modified for this duration before erasure coding",
							 | 
						|
												Placeholder:  "5",
							 | 
						|
												Unit:         config.UnitMinutes,
							 | 
						|
												InputType:    "interval",
							 | 
						|
												CSSClasses:   "form-control",
							 | 
						|
											},
							 | 
						|
											{
							 | 
						|
												Name:         "fullness_ratio",
							 | 
						|
												JSONName:     "fullness_ratio",
							 | 
						|
												Type:         config.FieldTypeFloat,
							 | 
						|
												DefaultValue: 0.8,
							 | 
						|
												MinValue:     0.1,
							 | 
						|
												MaxValue:     1.0,
							 | 
						|
												Required:     true,
							 | 
						|
												DisplayName:  "Fullness Ratio",
							 | 
						|
												Description:  "Minimum fullness ratio to trigger erasure coding",
							 | 
						|
												HelpText:     "Only volumes with this fullness ratio or higher will be erasure coded",
							 | 
						|
												Placeholder:  "0.80 (80%)",
							 | 
						|
												Unit:         config.UnitNone,
							 | 
						|
												InputType:    "number",
							 | 
						|
												CSSClasses:   "form-control",
							 | 
						|
											},
							 | 
						|
											{
							 | 
						|
												Name:         "collection_filter",
							 | 
						|
												JSONName:     "collection_filter",
							 | 
						|
												Type:         config.FieldTypeString,
							 | 
						|
												DefaultValue: "",
							 | 
						|
												Required:     false,
							 | 
						|
												DisplayName:  "Collection Filter",
							 | 
						|
												Description:  "Only process volumes from specific collections",
							 | 
						|
												HelpText:     "Leave empty to process all collections, or specify collection name",
							 | 
						|
												Placeholder:  "my_collection",
							 | 
						|
												InputType:    "text",
							 | 
						|
												CSSClasses:   "form-control",
							 | 
						|
											},
							 | 
						|
											{
							 | 
						|
												Name:         "min_size_mb",
							 | 
						|
												JSONName:     "min_size_mb",
							 | 
						|
												Type:         config.FieldTypeInt,
							 | 
						|
												DefaultValue: 30,
							 | 
						|
												MinValue:     1,
							 | 
						|
												MaxValue:     1000,
							 | 
						|
												Required:     true,
							 | 
						|
												DisplayName:  "Minimum Size (MB)",
							 | 
						|
												Description:  "Minimum volume size to consider for erasure coding",
							 | 
						|
												HelpText:     "Only volumes larger than this size will be considered for erasure coding",
							 | 
						|
												Placeholder:  "30",
							 | 
						|
												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_ErasureCodingConfig{
							 | 
						|
											ErasureCodingConfig: &worker_pb.ErasureCodingTaskConfig{
							 | 
						|
												FullnessRatio:    float64(c.FullnessRatio),
							 | 
						|
												QuietForSeconds:  int32(c.QuietForSeconds),
							 | 
						|
												MinVolumeSizeMb:  int32(c.MinSizeMB),
							 | 
						|
												CollectionFilter: c.CollectionFilter,
							 | 
						|
											},
							 | 
						|
										},
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// 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) // Direct seconds-to-seconds mapping
							 | 
						|
								
							 | 
						|
									// Set erasure coding-specific fields from the task config
							 | 
						|
									if ecConfig := policy.GetErasureCodingConfig(); ecConfig != nil {
							 | 
						|
										c.FullnessRatio = float64(ecConfig.FullnessRatio)
							 | 
						|
										c.QuietForSeconds = int(ecConfig.QuietForSeconds)
							 | 
						|
										c.MinSizeMB = int(ecConfig.MinVolumeSizeMb)
							 | 
						|
										c.CollectionFilter = ecConfig.CollectionFilter
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									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
							 | 
						|
									if persistence, ok := configPersistence.(interface {
							 | 
						|
										LoadErasureCodingTaskPolicy() (*worker_pb.TaskPolicy, error)
							 | 
						|
									}); ok {
							 | 
						|
										if policy, err := persistence.LoadErasureCodingTaskPolicy(); err == nil && policy != nil {
							 | 
						|
											if err := config.FromTaskPolicy(policy); err == nil {
							 | 
						|
												glog.V(1).Infof("Loaded erasure coding configuration from persistence")
							 | 
						|
												return config
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									glog.V(1).Infof("Using default erasure coding configuration")
							 | 
						|
									return config
							 | 
						|
								}
							 |