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.
		
		
		
		
		
			
		
			
				
					
					
						
							184 lines
						
					
					
						
							4.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							184 lines
						
					
					
						
							4.8 KiB
						
					
					
				
								package tasks
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"reflect"
							 | 
						|
								
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/glog"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/pb/worker_pb"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/worker/types"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								// BaseUIProvider provides common UIProvider functionality for all tasks
							 | 
						|
								type BaseUIProvider struct {
							 | 
						|
									taskType            types.TaskType
							 | 
						|
									displayName         string
							 | 
						|
									description         string
							 | 
						|
									icon                string
							 | 
						|
									schemaFunc          func() *TaskConfigSchema
							 | 
						|
									configFunc          func() types.TaskConfig
							 | 
						|
									applyTaskPolicyFunc func(policy *worker_pb.TaskPolicy) error
							 | 
						|
									applyTaskConfigFunc func(config types.TaskConfig) error
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// NewBaseUIProvider creates a new base UI provider
							 | 
						|
								func NewBaseUIProvider(
							 | 
						|
									taskType types.TaskType,
							 | 
						|
									displayName string,
							 | 
						|
									description string,
							 | 
						|
									icon string,
							 | 
						|
									schemaFunc func() *TaskConfigSchema,
							 | 
						|
									configFunc func() types.TaskConfig,
							 | 
						|
									applyTaskPolicyFunc func(policy *worker_pb.TaskPolicy) error,
							 | 
						|
									applyTaskConfigFunc func(config types.TaskConfig) error,
							 | 
						|
								) *BaseUIProvider {
							 | 
						|
									return &BaseUIProvider{
							 | 
						|
										taskType:            taskType,
							 | 
						|
										displayName:         displayName,
							 | 
						|
										description:         description,
							 | 
						|
										icon:                icon,
							 | 
						|
										schemaFunc:          schemaFunc,
							 | 
						|
										configFunc:          configFunc,
							 | 
						|
										applyTaskPolicyFunc: applyTaskPolicyFunc,
							 | 
						|
										applyTaskConfigFunc: applyTaskConfigFunc,
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// GetTaskType returns the task type
							 | 
						|
								func (ui *BaseUIProvider) GetTaskType() types.TaskType {
							 | 
						|
									return ui.taskType
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// GetDisplayName returns the human-readable name
							 | 
						|
								func (ui *BaseUIProvider) GetDisplayName() string {
							 | 
						|
									return ui.displayName
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// GetDescription returns a description of what this task does
							 | 
						|
								func (ui *BaseUIProvider) GetDescription() string {
							 | 
						|
									return ui.description
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// GetIcon returns the icon CSS class for this task type
							 | 
						|
								func (ui *BaseUIProvider) GetIcon() string {
							 | 
						|
									return ui.icon
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// GetCurrentConfig returns the current configuration as TaskConfig
							 | 
						|
								func (ui *BaseUIProvider) GetCurrentConfig() types.TaskConfig {
							 | 
						|
									return ui.configFunc()
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// ApplyTaskPolicy applies protobuf TaskPolicy configuration
							 | 
						|
								func (ui *BaseUIProvider) ApplyTaskPolicy(policy *worker_pb.TaskPolicy) error {
							 | 
						|
									return ui.applyTaskPolicyFunc(policy)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// ApplyTaskConfig applies TaskConfig interface configuration
							 | 
						|
								func (ui *BaseUIProvider) ApplyTaskConfig(config types.TaskConfig) error {
							 | 
						|
									return ui.applyTaskConfigFunc(config)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// CommonConfigGetter provides a common pattern for getting current configuration
							 | 
						|
								type CommonConfigGetter[T any] struct {
							 | 
						|
									defaultConfig T
							 | 
						|
									detectorFunc  func() T
							 | 
						|
									schedulerFunc func() T
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// NewCommonConfigGetter creates a new common config getter
							 | 
						|
								func NewCommonConfigGetter[T any](
							 | 
						|
									defaultConfig T,
							 | 
						|
									detectorFunc func() T,
							 | 
						|
									schedulerFunc func() T,
							 | 
						|
								) *CommonConfigGetter[T] {
							 | 
						|
									return &CommonConfigGetter[T]{
							 | 
						|
										defaultConfig: defaultConfig,
							 | 
						|
										detectorFunc:  detectorFunc,
							 | 
						|
										schedulerFunc: schedulerFunc,
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// GetConfig returns the merged configuration
							 | 
						|
								func (cg *CommonConfigGetter[T]) GetConfig() T {
							 | 
						|
									config := cg.defaultConfig
							 | 
						|
								
							 | 
						|
									// Apply detector values if available
							 | 
						|
									if cg.detectorFunc != nil {
							 | 
						|
										detectorConfig := cg.detectorFunc()
							 | 
						|
										mergeConfigs(&config, detectorConfig)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// Apply scheduler values if available
							 | 
						|
									if cg.schedulerFunc != nil {
							 | 
						|
										schedulerConfig := cg.schedulerFunc()
							 | 
						|
										mergeConfigs(&config, schedulerConfig)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return config
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// mergeConfigs merges non-zero values from source into dest
							 | 
						|
								func mergeConfigs[T any](dest *T, source T) {
							 | 
						|
									destValue := reflect.ValueOf(dest).Elem()
							 | 
						|
									sourceValue := reflect.ValueOf(source)
							 | 
						|
								
							 | 
						|
									if destValue.Kind() != reflect.Struct || sourceValue.Kind() != reflect.Struct {
							 | 
						|
										return
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									for i := 0; i < destValue.NumField(); i++ {
							 | 
						|
										destField := destValue.Field(i)
							 | 
						|
										sourceField := sourceValue.Field(i)
							 | 
						|
								
							 | 
						|
										if !destField.CanSet() {
							 | 
						|
											continue
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										// Only copy non-zero values
							 | 
						|
										if !sourceField.IsZero() {
							 | 
						|
											if destField.Type() == sourceField.Type() {
							 | 
						|
												destField.Set(sourceField)
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// RegisterUIFunc provides a common registration function signature
							 | 
						|
								type RegisterUIFunc[D, S any] func(uiRegistry *types.UIRegistry, detector D, scheduler S)
							 | 
						|
								
							 | 
						|
								// CommonRegisterUI provides a common registration implementation
							 | 
						|
								func CommonRegisterUI[D, S any](
							 | 
						|
									taskType types.TaskType,
							 | 
						|
									displayName string,
							 | 
						|
									uiRegistry *types.UIRegistry,
							 | 
						|
									detector D,
							 | 
						|
									scheduler S,
							 | 
						|
									schemaFunc func() *TaskConfigSchema,
							 | 
						|
									configFunc func() types.TaskConfig,
							 | 
						|
									applyTaskPolicyFunc func(policy *worker_pb.TaskPolicy) error,
							 | 
						|
									applyTaskConfigFunc func(config types.TaskConfig) error,
							 | 
						|
								) {
							 | 
						|
									// Get metadata from schema
							 | 
						|
									schema := schemaFunc()
							 | 
						|
									description := "Task configuration"
							 | 
						|
									icon := "fas fa-cog"
							 | 
						|
								
							 | 
						|
									if schema != nil {
							 | 
						|
										description = schema.Description
							 | 
						|
										icon = schema.Icon
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									uiProvider := NewBaseUIProvider(
							 | 
						|
										taskType,
							 | 
						|
										displayName,
							 | 
						|
										description,
							 | 
						|
										icon,
							 | 
						|
										schemaFunc,
							 | 
						|
										configFunc,
							 | 
						|
										applyTaskPolicyFunc,
							 | 
						|
										applyTaskConfigFunc,
							 | 
						|
									)
							 | 
						|
								
							 | 
						|
									uiRegistry.RegisterUI(uiProvider)
							 | 
						|
									glog.V(1).Infof("✅ Registered %s task UI provider", taskType)
							 | 
						|
								}
							 |