Browse Source

refactor to use BaseUIProvider

worker-execute-ec-tasks
chrislu 4 months ago
parent
commit
b80971e85e
  1. 119
      weed/worker/tasks/balance/ui.go
  2. 123
      weed/worker/tasks/erasure_coding/ui.go
  3. 218
      weed/worker/tasks/ui_base.go
  4. 136
      weed/worker/tasks/vacuum/ui.go

119
weed/worker/tasks/balance/ui.go

@ -8,40 +8,6 @@ import (
"github.com/seaweedfs/seaweedfs/weed/worker/types"
)
// UIProvider provides the UI for balance task configuration
type UIProvider struct {
detector *BalanceDetector
scheduler *BalanceScheduler
}
// NewUIProvider creates a new balance UI provider
func NewUIProvider(detector *BalanceDetector, scheduler *BalanceScheduler) *UIProvider {
return &UIProvider{
detector: detector,
scheduler: scheduler,
}
}
// GetTaskType returns the task type
func (ui *UIProvider) GetTaskType() types.TaskType {
return types.TaskTypeBalance
}
// GetDisplayName returns the human-readable name
func (ui *UIProvider) GetDisplayName() string {
return "Volume Balance"
}
// GetDescription returns a description of what this task does
func (ui *UIProvider) GetDescription() string {
return "Redistributes volumes across volume servers to optimize storage utilization and performance"
}
// GetIcon returns the icon CSS class for this task type
func (ui *UIProvider) GetIcon() string {
return "fas fa-balance-scale text-secondary"
}
// BalanceConfig represents the balance configuration matching the schema
type BalanceConfig struct {
Enabled bool `json:"enabled"`
@ -51,8 +17,22 @@ type BalanceConfig struct {
MinServerCount int `json:"min_server_count"`
}
// GetCurrentConfig returns the current configuration
func (ui *UIProvider) GetCurrentConfig() interface{} {
// BalanceUILogic contains the business logic for balance UI operations
type BalanceUILogic struct {
detector *BalanceDetector
scheduler *BalanceScheduler
}
// NewBalanceUILogic creates new balance UI logic
func NewBalanceUILogic(detector *BalanceDetector, scheduler *BalanceScheduler) *BalanceUILogic {
return &BalanceUILogic{
detector: detector,
scheduler: scheduler,
}
}
// GetCurrentConfig returns the current balance configuration
func (logic *BalanceUILogic) GetCurrentConfig() interface{} {
config := &BalanceConfig{
// Default values from schema (matching task_config_schema.go)
Enabled: true,
@ -63,55 +43,40 @@ func (ui *UIProvider) GetCurrentConfig() interface{} {
}
// Get current values from detector
if ui.detector != nil {
config.Enabled = ui.detector.IsEnabled()
config.ImbalanceThreshold = ui.detector.GetThreshold()
config.ScanIntervalSeconds = int(ui.detector.ScanInterval().Seconds())
if logic.detector != nil {
config.Enabled = logic.detector.IsEnabled()
config.ImbalanceThreshold = logic.detector.GetThreshold()
config.ScanIntervalSeconds = int(logic.detector.ScanInterval().Seconds())
}
// Get current values from scheduler
if ui.scheduler != nil {
config.MaxConcurrent = ui.scheduler.GetMaxConcurrent()
config.MinServerCount = ui.scheduler.GetMinServerCount()
if logic.scheduler != nil {
config.MaxConcurrent = logic.scheduler.GetMaxConcurrent()
config.MinServerCount = logic.scheduler.GetMinServerCount()
}
return config
}
// ApplyConfig applies the new configuration
func (ui *UIProvider) ApplyConfig(config interface{}) error {
// ApplyConfig applies the balance configuration
func (logic *BalanceUILogic) ApplyConfig(config interface{}) error {
balanceConfig, ok := config.(*BalanceConfig)
if !ok {
// Try to get the configuration from the schema-based system
schema := tasks.GetBalanceTaskConfigSchema()
if schema != nil {
// Apply defaults to ensure we have a complete config
if err := schema.ApplyDefaults(config); err != nil {
return err
}
// Use reflection to convert to BalanceConfig - simplified approach
if bc, ok := config.(*BalanceConfig); ok {
balanceConfig = bc
} else {
glog.Warningf("Config type conversion failed, using current config")
balanceConfig = ui.GetCurrentConfig().(*BalanceConfig)
}
}
return nil // Will be handled by base provider fallback
}
// Apply to detector
if ui.detector != nil {
ui.detector.SetEnabled(balanceConfig.Enabled)
ui.detector.SetThreshold(balanceConfig.ImbalanceThreshold)
ui.detector.SetMinCheckInterval(time.Duration(balanceConfig.ScanIntervalSeconds) * time.Second)
if logic.detector != nil {
logic.detector.SetEnabled(balanceConfig.Enabled)
logic.detector.SetThreshold(balanceConfig.ImbalanceThreshold)
logic.detector.SetMinCheckInterval(time.Duration(balanceConfig.ScanIntervalSeconds) * time.Second)
}
// Apply to scheduler
if ui.scheduler != nil {
ui.scheduler.SetEnabled(balanceConfig.Enabled)
ui.scheduler.SetMaxConcurrent(balanceConfig.MaxConcurrent)
ui.scheduler.SetMinServerCount(balanceConfig.MinServerCount)
if logic.scheduler != nil {
logic.scheduler.SetEnabled(balanceConfig.Enabled)
logic.scheduler.SetMaxConcurrent(balanceConfig.MaxConcurrent)
logic.scheduler.SetMinServerCount(balanceConfig.MinServerCount)
}
glog.V(1).Infof("Applied balance configuration: enabled=%v, threshold=%.1f%%, max_concurrent=%d, min_servers=%d",
@ -123,10 +88,18 @@ func (ui *UIProvider) ApplyConfig(config interface{}) error {
// RegisterUI registers the balance UI provider with the UI registry
func RegisterUI(uiRegistry *types.UIRegistry, detector *BalanceDetector, scheduler *BalanceScheduler) {
uiProvider := NewUIProvider(detector, scheduler)
uiRegistry.RegisterUI(uiProvider)
glog.V(1).Infof("✅ Registered balance task UI provider")
logic := NewBalanceUILogic(detector, scheduler)
tasks.CommonRegisterUI(
types.TaskTypeBalance,
"Volume Balance",
uiRegistry,
detector,
scheduler,
tasks.GetBalanceTaskConfigSchema,
logic.GetCurrentConfig,
logic.ApplyConfig,
)
}
// DefaultBalanceConfig returns default balance configuration

123
weed/worker/tasks/erasure_coding/ui.go

@ -8,40 +8,6 @@ import (
"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 matching the schema
type ErasureCodingConfig struct {
Enabled bool `json:"enabled"`
@ -52,8 +18,22 @@ type ErasureCodingConfig struct {
CollectionFilter string `json:"collection_filter"`
}
// GetCurrentConfig returns the current configuration
func (ui *UIProvider) GetCurrentConfig() interface{} {
// ErasureCodingUILogic contains the business logic for erasure coding UI operations
type ErasureCodingUILogic struct {
detector *EcDetector
scheduler *Scheduler
}
// NewErasureCodingUILogic creates new erasure coding UI logic
func NewErasureCodingUILogic(detector *EcDetector, scheduler *Scheduler) *ErasureCodingUILogic {
return &ErasureCodingUILogic{
detector: detector,
scheduler: scheduler,
}
}
// GetCurrentConfig returns the current erasure coding configuration
func (logic *ErasureCodingUILogic) GetCurrentConfig() interface{} {
config := ErasureCodingConfig{
// Default values from schema (matching task_config_schema.go)
Enabled: true,
@ -65,57 +45,42 @@ func (ui *UIProvider) GetCurrentConfig() interface{} {
}
// Get current values from detector
if ui.detector != nil {
config.Enabled = ui.detector.IsEnabled()
config.QuietForSeconds = ui.detector.GetQuietForSeconds()
config.FullnessRatio = ui.detector.GetFullnessRatio()
config.CollectionFilter = ui.detector.GetCollectionFilter()
config.ScanIntervalSeconds = int(ui.detector.ScanInterval().Seconds())
if logic.detector != nil {
config.Enabled = logic.detector.IsEnabled()
config.QuietForSeconds = logic.detector.GetQuietForSeconds()
config.FullnessRatio = logic.detector.GetFullnessRatio()
config.CollectionFilter = logic.detector.GetCollectionFilter()
config.ScanIntervalSeconds = int(logic.detector.ScanInterval().Seconds())
}
// Get current values from scheduler
if ui.scheduler != nil {
config.MaxConcurrent = ui.scheduler.GetMaxConcurrent()
if logic.scheduler != nil {
config.MaxConcurrent = logic.scheduler.GetMaxConcurrent()
}
return config
}
// ApplyConfig applies the new configuration
func (ui *UIProvider) ApplyConfig(config interface{}) error {
// ApplyConfig applies the erasure coding configuration
func (logic *ErasureCodingUILogic) ApplyConfig(config interface{}) error {
ecConfig, ok := config.(ErasureCodingConfig)
if !ok {
// Try to get the configuration from the schema-based system
schema := tasks.GetErasureCodingTaskConfigSchema()
if schema != nil {
// Apply defaults to ensure we have a complete config
if err := schema.ApplyDefaults(config); err != nil {
return err
}
// Use reflection to convert to ErasureCodingConfig - simplified approach
if ec, ok := config.(ErasureCodingConfig); ok {
ecConfig = ec
} else {
glog.Warningf("Config type conversion failed, using current config")
ecConfig = ui.GetCurrentConfig().(ErasureCodingConfig)
}
}
return nil // Will be handled by base provider fallback
}
// Apply to detector
if ui.detector != nil {
ui.detector.SetEnabled(ecConfig.Enabled)
ui.detector.SetQuietForSeconds(ecConfig.QuietForSeconds)
ui.detector.SetFullnessRatio(ecConfig.FullnessRatio)
ui.detector.SetCollectionFilter(ecConfig.CollectionFilter)
ui.detector.SetScanInterval(time.Duration(ecConfig.ScanIntervalSeconds) * time.Second)
if logic.detector != nil {
logic.detector.SetEnabled(ecConfig.Enabled)
logic.detector.SetQuietForSeconds(ecConfig.QuietForSeconds)
logic.detector.SetFullnessRatio(ecConfig.FullnessRatio)
logic.detector.SetCollectionFilter(ecConfig.CollectionFilter)
logic.detector.SetScanInterval(time.Duration(ecConfig.ScanIntervalSeconds) * time.Second)
}
// Apply to scheduler
if ui.scheduler != nil {
ui.scheduler.SetEnabled(ecConfig.Enabled)
ui.scheduler.SetMaxConcurrent(ecConfig.MaxConcurrent)
if logic.scheduler != nil {
logic.scheduler.SetEnabled(ecConfig.Enabled)
logic.scheduler.SetMaxConcurrent(ecConfig.MaxConcurrent)
}
glog.V(1).Infof("Applied erasure coding configuration: enabled=%v, quiet_for=%v seconds, max_concurrent=%d, fullness_ratio=%f, collection_filter=%s",
@ -126,8 +91,16 @@ func (ui *UIProvider) ApplyConfig(config interface{}) error {
// 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")
logic := NewErasureCodingUILogic(detector, scheduler)
tasks.CommonRegisterUI(
types.TaskTypeErasureCoding,
"Erasure Coding",
uiRegistry,
detector,
scheduler,
tasks.GetErasureCodingTaskConfigSchema,
logic.GetCurrentConfig,
logic.ApplyConfig,
)
}

218
weed/worker/tasks/ui_base.go

@ -0,0 +1,218 @@
package tasks
import (
"reflect"
"github.com/seaweedfs/seaweedfs/weed/glog"
"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() interface{}
applyFunc func(config interface{}) error
}
// NewBaseUIProvider creates a new base UI provider
func NewBaseUIProvider(
taskType types.TaskType,
displayName string,
description string,
icon string,
schemaFunc func() *TaskConfigSchema,
configFunc func() interface{},
applyFunc func(config interface{}) error,
) *BaseUIProvider {
return &BaseUIProvider{
taskType: taskType,
displayName: displayName,
description: description,
icon: icon,
schemaFunc: schemaFunc,
configFunc: configFunc,
applyFunc: applyFunc,
}
}
// 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
func (ui *BaseUIProvider) GetCurrentConfig() interface{} {
return ui.configFunc()
}
// ApplyConfig applies the new configuration with common schema-based handling
func (ui *BaseUIProvider) ApplyConfig(config interface{}) error {
// First try direct application
if err := ui.applyFunc(config); err == nil {
return nil
}
// Fallback: Try to get the configuration from the schema-based system
schema := ui.schemaFunc()
if schema != nil {
// Apply defaults to ensure we have a complete config
if err := schema.ApplyDefaults(config); err != nil {
return err
}
// Try again with defaults applied
if err := ui.applyFunc(config); err == nil {
return nil
}
// Last resort: use current config
glog.Warningf("Config type conversion failed for %s, using current config", ui.taskType)
currentConfig := ui.GetCurrentConfig()
return ui.applyFunc(currentConfig)
}
return nil
}
// 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 !isZeroValue(sourceField) {
if destField.Type() == sourceField.Type() {
destField.Set(sourceField)
}
}
}
}
// isZeroValue checks if a reflect.Value represents a zero value
func isZeroValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.String:
return v.String() == ""
case reflect.Slice, reflect.Map, reflect.Array:
return v.IsNil() || v.Len() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return false
}
// 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() interface{},
applyFunc func(config interface{}) 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,
applyFunc,
)
uiRegistry.RegisterUI(uiProvider)
glog.V(1).Infof("✅ Registered %s task UI provider", taskType)
}

136
weed/worker/tasks/vacuum/ui.go

@ -8,40 +8,6 @@ import (
"github.com/seaweedfs/seaweedfs/weed/worker/types"
)
// UIProvider provides the UI for vacuum task configuration
type UIProvider struct {
detector *VacuumDetector
scheduler *VacuumScheduler
}
// NewUIProvider creates a new vacuum UI provider
func NewUIProvider(detector *VacuumDetector, scheduler *VacuumScheduler) *UIProvider {
return &UIProvider{
detector: detector,
scheduler: scheduler,
}
}
// GetTaskType returns the task type
func (ui *UIProvider) GetTaskType() types.TaskType {
return types.TaskTypeVacuum
}
// GetDisplayName returns the human-readable name
func (ui *UIProvider) GetDisplayName() string {
return "Volume Vacuum"
}
// GetDescription returns a description of what this task does
func (ui *UIProvider) GetDescription() string {
return "Reclaims disk space by removing deleted files from volumes"
}
// GetIcon returns the icon CSS class for this task type
func (ui *UIProvider) GetIcon() string {
return "fas fa-broom text-primary"
}
// VacuumConfig represents the vacuum configuration matching the schema
type VacuumConfig struct {
Enabled bool `json:"enabled"`
@ -52,8 +18,22 @@ type VacuumConfig struct {
MinIntervalSeconds int `json:"min_interval_seconds"`
}
// GetCurrentConfig returns the current configuration
func (ui *UIProvider) GetCurrentConfig() interface{} {
// VacuumUILogic contains the business logic for vacuum UI operations
type VacuumUILogic struct {
detector *VacuumDetector
scheduler *VacuumScheduler
}
// NewVacuumUILogic creates new vacuum UI logic
func NewVacuumUILogic(detector *VacuumDetector, scheduler *VacuumScheduler) *VacuumUILogic {
return &VacuumUILogic{
detector: detector,
scheduler: scheduler,
}
}
// GetCurrentConfig returns the current vacuum configuration
func (logic *VacuumUILogic) GetCurrentConfig() interface{} {
config := &VacuumConfig{
// Default values from schema (matching task_config_schema.go)
Enabled: true,
@ -65,57 +45,42 @@ func (ui *UIProvider) GetCurrentConfig() interface{} {
}
// Get current values from detector
if ui.detector != nil {
config.Enabled = ui.detector.IsEnabled()
config.GarbageThreshold = ui.detector.GetGarbageThreshold()
config.ScanIntervalSeconds = int(ui.detector.ScanInterval().Seconds())
config.MinVolumeAgeSeconds = int(ui.detector.GetMinVolumeAge().Seconds())
if logic.detector != nil {
config.Enabled = logic.detector.IsEnabled()
config.GarbageThreshold = logic.detector.GetGarbageThreshold()
config.ScanIntervalSeconds = int(logic.detector.ScanInterval().Seconds())
config.MinVolumeAgeSeconds = int(logic.detector.GetMinVolumeAge().Seconds())
}
// Get current values from scheduler
if ui.scheduler != nil {
config.MaxConcurrent = ui.scheduler.GetMaxConcurrent()
config.MinIntervalSeconds = int(ui.scheduler.GetMinInterval().Seconds())
if logic.scheduler != nil {
config.MaxConcurrent = logic.scheduler.GetMaxConcurrent()
config.MinIntervalSeconds = int(logic.scheduler.GetMinInterval().Seconds())
}
return config
}
// ApplyConfig applies the new configuration
func (ui *UIProvider) ApplyConfig(config interface{}) error {
// ApplyConfig applies the vacuum configuration
func (logic *VacuumUILogic) ApplyConfig(config interface{}) error {
vacuumConfig, ok := config.(*VacuumConfig)
if !ok {
// Try to get the configuration from the schema-based system
schema := tasks.GetVacuumTaskConfigSchema()
if schema != nil {
// Apply defaults to ensure we have a complete config
if err := schema.ApplyDefaults(config); err != nil {
return err
}
// Use reflection to convert to VacuumConfig - simplified approach
if vc, ok := config.(*VacuumConfig); ok {
vacuumConfig = vc
} else {
glog.Warningf("Config type conversion failed, using current config")
vacuumConfig = ui.GetCurrentConfig().(*VacuumConfig)
}
}
return nil // Will be handled by base provider fallback
}
// Apply to detector
if ui.detector != nil {
ui.detector.SetEnabled(vacuumConfig.Enabled)
ui.detector.SetGarbageThreshold(vacuumConfig.GarbageThreshold)
ui.detector.SetScanInterval(time.Duration(vacuumConfig.ScanIntervalSeconds) * time.Second)
ui.detector.SetMinVolumeAge(time.Duration(vacuumConfig.MinVolumeAgeSeconds) * time.Second)
if logic.detector != nil {
logic.detector.SetEnabled(vacuumConfig.Enabled)
logic.detector.SetGarbageThreshold(vacuumConfig.GarbageThreshold)
logic.detector.SetScanInterval(time.Duration(vacuumConfig.ScanIntervalSeconds) * time.Second)
logic.detector.SetMinVolumeAge(time.Duration(vacuumConfig.MinVolumeAgeSeconds) * time.Second)
}
// Apply to scheduler
if ui.scheduler != nil {
ui.scheduler.SetEnabled(vacuumConfig.Enabled)
ui.scheduler.SetMaxConcurrent(vacuumConfig.MaxConcurrent)
ui.scheduler.SetMinInterval(time.Duration(vacuumConfig.MinIntervalSeconds) * time.Second)
if logic.scheduler != nil {
logic.scheduler.SetEnabled(vacuumConfig.Enabled)
logic.scheduler.SetMaxConcurrent(vacuumConfig.MaxConcurrent)
logic.scheduler.SetMinInterval(time.Duration(vacuumConfig.MinIntervalSeconds) * time.Second)
}
glog.V(1).Infof("Applied vacuum configuration: enabled=%v, threshold=%.1f%%, scan_interval=%ds, max_concurrent=%d",
@ -126,22 +91,21 @@ func (ui *UIProvider) ApplyConfig(config interface{}) error {
// RegisterUI registers the vacuum UI provider with the UI registry
func RegisterUI(uiRegistry *types.UIRegistry, detector *VacuumDetector, scheduler *VacuumScheduler) {
uiProvider := NewUIProvider(detector, scheduler)
uiRegistry.RegisterUI(uiProvider)
glog.V(1).Infof("✅ Registered vacuum task UI provider")
logic := NewVacuumUILogic(detector, scheduler)
tasks.CommonRegisterUI(
types.TaskTypeVacuum,
"Volume Vacuum",
uiRegistry,
detector,
scheduler,
tasks.GetVacuumTaskConfigSchema,
logic.GetCurrentConfig,
logic.ApplyConfig,
)
}
// GetUIProvider returns the UI provider for external use
func GetUIProvider(uiRegistry *types.UIRegistry) *UIProvider {
provider := uiRegistry.GetProvider(types.TaskTypeVacuum)
if provider == nil {
return nil
}
if vacuumProvider, ok := provider.(*UIProvider); ok {
return vacuumProvider
}
return nil
func GetUIProvider(uiRegistry *types.UIRegistry) types.TaskUIProvider {
return uiRegistry.GetProvider(types.TaskTypeVacuum)
}
Loading…
Cancel
Save