config_module_callback.go 4.5 KB
Newer Older
Z
zhj-luo 已提交
1 2 3 4 5 6 7 8 9 10 11 12
/*
 * Copyright (c) 2023 OceanBase
 * OCP Express is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

W
wangzelin.wzl 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
package config

import (
	"context"

	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
)

type ModuleType string

var (
	// module config callbacks
	callbacks map[ModuleType]*ConfigCallback
	modules   map[string]ModuleType
)

// init callbacks and register module config callbacks
func init() {
	callbacks = make(map[ModuleType]*ConfigCallback, 8)
	modules = make(map[string]ModuleType, 32)
}

O
ob-robot 已提交
36
// Callback call Callback when receive a request
W
wangzelin.wzl 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
type Callback func(ctx context.Context, nconfig *NotifyModuleConfig) error

// ModuleCallback register a ModuleCallback, Callback will call it
type ModuleCallback func(ctx context.Context, moduleConf interface{}) error

// Creator create a new module config
type Creator func() interface{}

// ConfigCallback module config consumer, call updateConfigCallback to update config,
// call InitConfigCallback to check if config is identical
type ConfigCallback struct {
	moduleType           ModuleType
	creator              Creator
	InitConfigCallback   func(ctx context.Context, module string) error
	NotifyConfigCallback Callback
}

// create instance for module type
func createModuleTypeInstance(module string) (interface{}, error) {
	moduleType, ex := modules[module]
	if !ex {
		return nil, errors.Errorf("module %s's moduleType is not found.", module)
	}
	callback, ex := getModuleTypeCallback(moduleType)
	if !ex {
		return nil, errors.Errorf("module %s moduleType %s callback is not exist!", module, moduleType)
	}

	return callback.creator(), nil
}

func getModuleCallback(module string) (callback *ConfigCallback, exists bool) {
	moduleType, ex := modules[module]
	if !ex {
		log.Errorf("module %s 's module type is not found", module)
		return nil, false
	}
	return getModuleTypeCallback(moduleType)
}

func getModuleTypeCallback(moduleType ModuleType) (callback *ConfigCallback, exists bool) {
	callback, exists = callbacks[moduleType]
	return
}

func RegisterModule(module string, moduleType ModuleType) error {
O
ob-robot 已提交
83 84 85
	existModuleType, ex := modules[module]
	if ex && existModuleType != moduleType {
		return errors.Errorf("module %s 's module type %s is already set as %s", module, moduleType, existModuleType)
W
wangzelin.wzl 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
	}
	modules[module] = moduleType
	log.Debugf("register module %s, moduleType %s", module, moduleType)
	return nil
}

// RegisterConfigCallback registry module config consumer
func RegisterConfigCallback(moduleType ModuleType,
	creator Creator,
	initConfig ModuleCallback,
	receiveUpdatedConfig ModuleCallback) error {

	log.Debugf("register moduleType %s config callback start", moduleType)

	if _, ex := getModuleTypeCallback(moduleType); ex {
O
ob-robot 已提交
101
		return errors.Errorf("moduleType %s callback has been registred!", moduleType)
W
wangzelin.wzl 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115
	}

	initConfigCallback := func(ctx context.Context, module string) error {
		moduleConfigSample, ex := GetModuleConfigs()[module]
		if !ex {
			return errors.Errorf("module %s config sample is not found", module)
		}
		log.WithContext(ctx).Debugf("module %s config sample:%+v", module, moduleConfigSample)
		if moduleConfigSample.Disabled {
			return errors.Errorf("module %s config is disabled.", module)
		}

		moduleConf, err := getFinalModuleConfig(module, moduleConfigSample.Config, nil)
		if err != nil {
O
ob-robot 已提交
116
			return errors.Errorf("get module %s final config err:%s", module, err)
W
wangzelin.wzl 已提交
117 118 119 120
		}

		err = initConfig(ctx, moduleConf)
		if err != nil {
O
ob-robot 已提交
121
			return errors.Errorf("init module %s conf err:%s", module, err)
W
wangzelin.wzl 已提交
122 123 124 125 126 127 128 129
		}
		return nil
	}

	NotifyUpdatedConfigCallback := func(ctx context.Context, econfig *NotifyModuleConfig) error {
		log.WithContext(ctx).Infof("notify module %s config, process:%s", econfig.Module, econfig.Process)
		err := receiveUpdatedConfig(ctx, econfig.Config)
		if err != nil {
O
ob-robot 已提交
130
			return errors.Errorf("notify module %s config, process %s, err:%s", econfig.Module, econfig.Process, err)
W
wangzelin.wzl 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144
		}
		return nil
	}

	callbacks[moduleType] = &ConfigCallback{
		moduleType:           moduleType,
		creator:              creator,
		InitConfigCallback:   initConfigCallback,
		NotifyConfigCallback: NotifyUpdatedConfigCallback,
	}

	log.Debugf("register moduleType %s config callback end", moduleType)
	return nil
}