component.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package mhayaDataConfig
  2. import (
  3. "sync"
  4. cutils "github.com/mhaya/extend/utils"
  5. cfacade "github.com/mhaya/facade"
  6. clog "github.com/mhaya/logger"
  7. cprofile "github.com/mhaya/profile"
  8. )
  9. const (
  10. Name = "data_config_component"
  11. )
  12. type Component struct {
  13. sync.RWMutex
  14. cfacade.Component
  15. dataSource IDataSource
  16. parser IDataParser
  17. configs []IConfig
  18. }
  19. func New() *Component {
  20. return &Component{}
  21. }
  22. // Name unique components name
  23. func (d *Component) Name() string {
  24. return Name
  25. }
  26. func (d *Component) Init() {
  27. // read data_config node in profile-{env}.json
  28. dataConfig := cprofile.GetConfig("data_config")
  29. if dataConfig.LastError() != nil {
  30. clog.Fatalf("`data_config` node in `%s` file not found.", cprofile.Name())
  31. }
  32. // get data source
  33. sourceName := dataConfig.GetString("data_source")
  34. d.dataSource = GetDataSource(sourceName)
  35. if d.dataSource == nil {
  36. clog.Fatalf("[sourceName = %s] data source not found.", sourceName)
  37. }
  38. // get parser
  39. parserName := dataConfig.GetString("parser")
  40. d.parser = GetParser(parserName)
  41. if d.parser == nil {
  42. clog.Fatalf("[parserName = %s] parser not found.", parserName)
  43. }
  44. cutils.Try(func() {
  45. d.dataSource.Init(d)
  46. // init
  47. for _, cfg := range d.configs {
  48. cfg.Init()
  49. }
  50. // read register IConfig
  51. for _, cfg := range d.configs {
  52. data, found := d.GetBytes(cfg.Name())
  53. if !found {
  54. clog.Warnf("[config = %s] load data fail.", cfg.Name())
  55. continue
  56. }
  57. cutils.Try(func() {
  58. d.onLoadConfig(cfg, data, false)
  59. }, func(errString string) {
  60. clog.Errorf("[config = %s] init config error. [error = %s]", cfg.Name(), errString)
  61. })
  62. }
  63. // on after load
  64. for _, cfg := range d.configs {
  65. cfg.OnAfterLoad(false)
  66. }
  67. // on change process
  68. d.dataSource.OnChange(func(configName string, data []byte) {
  69. iConfig := d.GetIConfig(configName)
  70. if iConfig != nil {
  71. d.onLoadConfig(iConfig, data, true)
  72. iConfig.OnAfterLoad(true)
  73. }
  74. })
  75. }, func(errString string) {
  76. clog.Error(errString)
  77. })
  78. }
  79. func (d *Component) onLoadConfig(cfg IConfig, data []byte, reload bool) {
  80. var parseObject interface{}
  81. err := d.parser.Unmarshal(data, &parseObject)
  82. if err != nil {
  83. clog.Warnf("[config = %s] unmarshal error = %v", err, cfg.Name())
  84. return
  85. }
  86. d.Lock()
  87. defer d.Unlock()
  88. // load data
  89. size, err := cfg.OnLoad(parseObject, reload)
  90. if err != nil {
  91. clog.Warnf("[config = %s] execute Load() error = %s", cfg.Name(), err)
  92. return
  93. }
  94. clog.Infof("[config = %s] loaded. [size = %d]", cfg.Name(), size)
  95. }
  96. func (d *Component) OnStop() {
  97. if d.dataSource != nil {
  98. d.dataSource.Stop()
  99. }
  100. }
  101. func (d *Component) Register(configs ...IConfig) {
  102. if len(configs) < 1 {
  103. clog.Warnf("IConfig size is less than 1.")
  104. return
  105. }
  106. for _, cfg := range configs {
  107. if cfg != nil {
  108. d.configs = append(d.configs, cfg)
  109. }
  110. }
  111. }
  112. func (d *Component) GetIConfig(name string) IConfig {
  113. for _, cfg := range d.configs {
  114. if cfg.Name() == name {
  115. return cfg
  116. }
  117. }
  118. return nil
  119. }
  120. func (d *Component) GetBytes(configName string) (data []byte, found bool) {
  121. data, err := d.dataSource.ReadBytes(configName)
  122. if err != nil {
  123. clog.Warn(err)
  124. return nil, false
  125. }
  126. return data, true
  127. }
  128. func (d *Component) GetParser() IDataParser {
  129. return d.parser
  130. }
  131. func (d *Component) GetDataSource() IDataSource {
  132. return d.dataSource
  133. }