Files
gf/os/gcfg/gcfg_adapter_file_content.go
Lance Add ac3efe5a00 feat(os/gcfg): Add file watcher with custom callback support (#4446)
为`gcfg`添加配置文件变更自定义回调,实现了`WatcherAdapter`接口,以下是`AdapterFile`的用法
test.yaml
```
b: "b"

```
```
package main

import (
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gcfg"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	ctx := gctx.New()
	file, _ := gcfg.NewAdapterFile("test.yaml")
	file.Data(ctx)
	file.AddWatcher("test", func() {
		value := file.MustGet(ctx, "b")
		fmt.Println(value.String())
	})
	server := g.Server()
	server.Run()
}
```
使用`g`和默认配置文件
```
	file := g.Cfg().GetAdapter().(*gcfg.AdapterFile)
	file.AddWatcher("test", func() {

	})
	file := g.Cfg().GetAdapter().(*gcfg.AdapterFile)
	file.RemoveWatcher("test")
```

注意:由于`gf`的`AdapterFile`使用的监听到文件变化删除缓存下一次重新初始化的懒加载方案,所有除了默认加载的`config.xxx`文件外,自定义的配置文件像`test.yaml`之类的都需要在`AddWatcher`前主动读取一次数据进行初始化监听(
`g.Cfg("test").Data(ctx)`)

---------

Co-authored-by: hailaz <739476267@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hunk Zhu <hunk@joy999.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-15 16:59:52 +08:00

91 lines
3.1 KiB
Go

// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gcfg
import (
"context"
"github.com/gogf/gf/v2/internal/intlog"
)
// SetContent sets customized configuration content for specified `file`.
// The `file` is unnecessary param, default is DefaultConfigFile.
func (a *AdapterFile) SetContent(content string, fileNameOrPath ...string) {
var usedFileNameOrPath = DefaultConfigFileName
if len(fileNameOrPath) > 0 {
usedFileNameOrPath = fileNameOrPath[0]
}
// Clear file cache for instances which cached `name`.
localInstances.LockFunc(func(m map[string]any) {
if customConfigContentMap.Contains(usedFileNameOrPath) {
for _, v := range m {
if configInstance, ok := v.(*Config); ok {
if fileConfig, ok := configInstance.GetAdapter().(*AdapterFile); ok {
fileConfig.jsonMap.Remove(usedFileNameOrPath)
}
}
}
}
customConfigContentMap.Set(usedFileNameOrPath, content)
})
adapterCtx := NewAdapterFileCtx().WithFileName(usedFileNameOrPath).WithOperation(OperationSet).WithContent(content)
a.notifyWatchers(adapterCtx.Ctx)
}
// GetContent returns customized configuration content for specified `file`.
// The `file` is unnecessary param, default is DefaultConfigFile.
func (a *AdapterFile) GetContent(fileNameOrPath ...string) string {
var usedFileNameOrPath = DefaultConfigFileName
if len(fileNameOrPath) > 0 {
usedFileNameOrPath = fileNameOrPath[0]
}
return customConfigContentMap.Get(usedFileNameOrPath)
}
// RemoveContent removes the global configuration with specified `file`.
// If `name` is not passed, it removes configuration of the default group name.
func (a *AdapterFile) RemoveContent(fileNameOrPath ...string) {
var usedFileNameOrPath = DefaultConfigFileName
if len(fileNameOrPath) > 0 {
usedFileNameOrPath = fileNameOrPath[0]
}
// Clear file cache for instances which cached `name`.
localInstances.LockFunc(func(m map[string]any) {
if customConfigContentMap.Contains(usedFileNameOrPath) {
for _, v := range m {
if configInstance, ok := v.(*Config); ok {
if fileConfig, ok := configInstance.GetAdapter().(*AdapterFile); ok {
fileConfig.jsonMap.Remove(usedFileNameOrPath)
}
}
}
customConfigContentMap.Remove(usedFileNameOrPath)
}
})
adapterCtx := NewAdapterFileCtx().WithFileName(usedFileNameOrPath).WithOperation(OperationRemove)
a.notifyWatchers(adapterCtx.Ctx)
intlog.Printf(context.TODO(), `RemoveContent: %s`, usedFileNameOrPath)
}
// ClearContent removes all global configuration contents.
func (a *AdapterFile) ClearContent() {
customConfigContentMap.Clear()
// Clear cache for all instances.
localInstances.LockFunc(func(m map[string]any) {
for _, v := range m {
if configInstance, ok := v.(*Config); ok {
if fileConfig, ok := configInstance.GetAdapter().(*AdapterFile); ok {
fileConfig.jsonMap.Clear()
}
}
}
})
adapterCtx := NewAdapterFileCtx().WithOperation(OperationClear)
a.notifyWatchers(adapterCtx.Ctx)
intlog.Print(context.TODO(), `RemoveConfig`)
}