diff options
Diffstat (limited to 'weed/worker/tasks/erasure_coding/ui.go')
| -rw-r--r-- | weed/worker/tasks/erasure_coding/ui.go | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/weed/worker/tasks/erasure_coding/ui.go b/weed/worker/tasks/erasure_coding/ui.go deleted file mode 100644 index e17cba89a..000000000 --- a/weed/worker/tasks/erasure_coding/ui.go +++ /dev/null @@ -1,309 +0,0 @@ -package erasure_coding - -import ( - "fmt" - "html/template" - "strconv" - "time" - - "github.com/seaweedfs/seaweedfs/weed/glog" - "github.com/seaweedfs/seaweedfs/weed/worker/types" -) - -// UIProvider provides the UI for erasure coding task configuration -type UIProvider struct { - detector *EcDetector - scheduler *Scheduler -} - -// NewUIProvider creates a new erasure coding UI provider -func NewUIProvider(detector *EcDetector, scheduler *Scheduler) *UIProvider { - return &UIProvider{ - detector: detector, - scheduler: scheduler, - } -} - -// GetTaskType returns the task type -func (ui *UIProvider) GetTaskType() types.TaskType { - return types.TaskTypeErasureCoding -} - -// GetDisplayName returns the human-readable name -func (ui *UIProvider) GetDisplayName() string { - return "Erasure Coding" -} - -// GetDescription returns a description of what this task does -func (ui *UIProvider) GetDescription() string { - return "Converts volumes to erasure coded format for improved data durability and fault tolerance" -} - -// GetIcon returns the icon CSS class for this task type -func (ui *UIProvider) GetIcon() string { - return "fas fa-shield-alt text-info" -} - -// ErasureCodingConfig represents the erasure coding configuration -type ErasureCodingConfig struct { - Enabled bool `json:"enabled"` - VolumeAgeHoursSeconds int `json:"volume_age_hours_seconds"` - FullnessRatio float64 `json:"fullness_ratio"` - ScanIntervalSeconds int `json:"scan_interval_seconds"` - MaxConcurrent int `json:"max_concurrent"` - ShardCount int `json:"shard_count"` - ParityCount int `json:"parity_count"` - CollectionFilter string `json:"collection_filter"` -} - -// Helper functions for duration conversion -func secondsToDuration(seconds int) time.Duration { - return time.Duration(seconds) * time.Second -} - -func durationToSeconds(d time.Duration) int { - return int(d.Seconds()) -} - -// formatDurationForUser formats seconds as a user-friendly duration string -func formatDurationForUser(seconds int) string { - d := secondsToDuration(seconds) - if d < time.Minute { - return fmt.Sprintf("%ds", seconds) - } - if d < time.Hour { - return fmt.Sprintf("%.0fm", d.Minutes()) - } - if d < 24*time.Hour { - return fmt.Sprintf("%.1fh", d.Hours()) - } - return fmt.Sprintf("%.1fd", d.Hours()/24) -} - -// RenderConfigForm renders the configuration form HTML -func (ui *UIProvider) RenderConfigForm(currentConfig interface{}) (template.HTML, error) { - config := ui.getCurrentECConfig() - - // Build form using the FormBuilder helper - form := types.NewFormBuilder() - - // Detection Settings - form.AddCheckboxField( - "enabled", - "Enable Erasure Coding Tasks", - "Whether erasure coding tasks should be automatically created", - config.Enabled, - ) - - form.AddNumberField( - "volume_age_hours_seconds", - "Volume Age Threshold", - "Only apply erasure coding to volumes older than this duration", - float64(config.VolumeAgeHoursSeconds), - true, - ) - - form.AddNumberField( - "scan_interval_seconds", - "Scan Interval", - "How often to scan for volumes needing erasure coding", - float64(config.ScanIntervalSeconds), - true, - ) - - // Scheduling Settings - form.AddNumberField( - "max_concurrent", - "Max Concurrent Tasks", - "Maximum number of erasure coding tasks that can run simultaneously", - float64(config.MaxConcurrent), - true, - ) - - // Erasure Coding Parameters - form.AddNumberField( - "shard_count", - "Data Shards", - "Number of data shards for erasure coding (recommended: 10)", - float64(config.ShardCount), - true, - ) - - form.AddNumberField( - "parity_count", - "Parity Shards", - "Number of parity shards for erasure coding (recommended: 4)", - float64(config.ParityCount), - true, - ) - - // Generate organized form sections using Bootstrap components - html := ` -<div class="row"> - <div class="col-12"> - <div class="card mb-4"> - <div class="card-header"> - <h5 class="mb-0"> - <i class="fas fa-shield-alt me-2"></i> - Erasure Coding Configuration - </h5> - </div> - <div class="card-body"> -` + string(form.Build()) + ` - </div> - </div> - </div> -</div> - -<div class="row"> - <div class="col-12"> - <div class="card mb-3"> - <div class="card-header"> - <h5 class="mb-0"> - <i class="fas fa-info-circle me-2"></i> - Performance Impact - </h5> - </div> - <div class="card-body"> - <div class="alert alert-info" role="alert"> - <h6 class="alert-heading">Important Notes:</h6> - <p class="mb-2"><strong>Performance:</strong> Erasure coding is CPU and I/O intensive. Consider running during off-peak hours.</p> - <p class="mb-0"><strong>Durability:</strong> With ` + fmt.Sprintf("%d+%d", config.ShardCount, config.ParityCount) + ` configuration, can tolerate up to ` + fmt.Sprintf("%d", config.ParityCount) + ` shard failures.</p> - </div> - </div> - </div> - </div> -</div>` - - return template.HTML(html), nil -} - -// ParseConfigForm parses form data into configuration -func (ui *UIProvider) ParseConfigForm(formData map[string][]string) (interface{}, error) { - config := &ErasureCodingConfig{} - - // Parse enabled - config.Enabled = len(formData["enabled"]) > 0 - - // Parse volume age hours - if values, ok := formData["volume_age_hours_seconds"]; ok && len(values) > 0 { - hours, err := strconv.Atoi(values[0]) - if err != nil { - return nil, fmt.Errorf("invalid volume age hours: %w", err) - } - config.VolumeAgeHoursSeconds = hours - } - - // Parse scan interval - if values, ok := formData["scan_interval_seconds"]; ok && len(values) > 0 { - interval, err := strconv.Atoi(values[0]) - if err != nil { - return nil, fmt.Errorf("invalid scan interval: %w", err) - } - config.ScanIntervalSeconds = interval - } - - // Parse max concurrent - if values, ok := formData["max_concurrent"]; ok && len(values) > 0 { - maxConcurrent, err := strconv.Atoi(values[0]) - if err != nil { - return nil, fmt.Errorf("invalid max concurrent: %w", err) - } - if maxConcurrent < 1 { - return nil, fmt.Errorf("max concurrent must be at least 1") - } - config.MaxConcurrent = maxConcurrent - } - - // Parse shard count - if values, ok := formData["shard_count"]; ok && len(values) > 0 { - shardCount, err := strconv.Atoi(values[0]) - if err != nil { - return nil, fmt.Errorf("invalid shard count: %w", err) - } - if shardCount < 1 { - return nil, fmt.Errorf("shard count must be at least 1") - } - config.ShardCount = shardCount - } - - // Parse parity count - if values, ok := formData["parity_count"]; ok && len(values) > 0 { - parityCount, err := strconv.Atoi(values[0]) - if err != nil { - return nil, fmt.Errorf("invalid parity count: %w", err) - } - if parityCount < 1 { - return nil, fmt.Errorf("parity count must be at least 1") - } - config.ParityCount = parityCount - } - - return config, nil -} - -// GetCurrentConfig returns the current configuration -func (ui *UIProvider) GetCurrentConfig() interface{} { - return ui.getCurrentECConfig() -} - -// ApplyConfig applies the new configuration -func (ui *UIProvider) ApplyConfig(config interface{}) error { - ecConfig, ok := config.(ErasureCodingConfig) - if !ok { - return fmt.Errorf("invalid config type, expected ErasureCodingConfig") - } - - // Apply to detector - if ui.detector != nil { - ui.detector.SetEnabled(ecConfig.Enabled) - ui.detector.SetVolumeAgeHours(ecConfig.VolumeAgeHoursSeconds) - ui.detector.SetScanInterval(secondsToDuration(ecConfig.ScanIntervalSeconds)) - } - - // Apply to scheduler - if ui.scheduler != nil { - ui.scheduler.SetEnabled(ecConfig.Enabled) - ui.scheduler.SetMaxConcurrent(ecConfig.MaxConcurrent) - } - - glog.V(1).Infof("Applied erasure coding configuration: enabled=%v, age_threshold=%v, max_concurrent=%d, shards=%d+%d", - ecConfig.Enabled, ecConfig.VolumeAgeHoursSeconds, ecConfig.MaxConcurrent, ecConfig.ShardCount, ecConfig.ParityCount) - - return nil -} - -// getCurrentECConfig gets the current configuration from detector and scheduler -func (ui *UIProvider) getCurrentECConfig() ErasureCodingConfig { - config := ErasureCodingConfig{ - // Default values (fallback if detectors/schedulers are nil) - Enabled: true, - VolumeAgeHoursSeconds: 24 * 3600, // 24 hours in seconds - ScanIntervalSeconds: 2 * 3600, // 2 hours in seconds - MaxConcurrent: 1, - ShardCount: 10, - ParityCount: 4, - } - - // Get current values from detector - if ui.detector != nil { - config.Enabled = ui.detector.IsEnabled() - config.VolumeAgeHoursSeconds = ui.detector.GetVolumeAgeHours() - config.ScanIntervalSeconds = durationToSeconds(ui.detector.ScanInterval()) - } - - // Get current values from scheduler - if ui.scheduler != nil { - config.MaxConcurrent = ui.scheduler.GetMaxConcurrent() - } - - return config -} - -// RegisterUI registers the erasure coding UI provider with the UI registry -func RegisterUI(uiRegistry *types.UIRegistry, detector *EcDetector, scheduler *Scheduler) { - uiProvider := NewUIProvider(detector, scheduler) - uiRegistry.RegisterUI(uiProvider) - - glog.V(1).Infof("✅ Registered erasure coding task UI provider") -} |
