Introduction
Starting from version v2.9.5, the gcfg component introduces the WatcherAdapter interface. WatcherAdapter is an interface in the gcfg package for implementing configuration file change monitoring functionality. When configuration files are modified, created, deleted, or have permission changes, registered watchers will be notified.
The configuration watching feature of GoFrame provides applications with the ability to dynamically respond to configuration changes, allowing the system to adjust its behavior in real-time without restarting. Through the flexible watcher mechanism and rich context information, developers can easily build adaptive applications.
Interface Definition
https://github.com/gogf/gf/blob/master/os/gcfg/gcfg_adaper.go
// WatcherAdapter is the interface for configuration watcher.
type WatcherAdapter interface {
// AddWatcher adds a watcher function for specified `pattern` and `resource`.
AddWatcher(name string, fn func(ctx context.Context))
// RemoveWatcher removes the watcher function for specified `pattern` and `resource`.
RemoveWatcher(name string)
// GetWatcherNames returns all watcher names.
GetWatcherNames() []string
}
Adapter Support Status:
| Adapter Name | Supports Watcher Callback |
|---|---|
AdapterFile | Supported |
AdapterContent | Supported |
polaris | Supported |
nacos | Supported |
apollo | Supported |
consul | Supported |
kubecm | Supported |
Core Concepts
WatcherAdapterinterface: Defines methods for adding, removing, and retrieving watchersWatcherRegistry: Watcher registration manager that provides a unified watcher management implementationcontextpassing: Passes detailed configuration change information throughcontext
Main Features
File Monitoring: Automatically monitors configuration file changes (write, create, delete, rename, permission change)Manual Trigger: Supports manually triggering watcher callbacks (such asSetoperations)Concurrency Safe: All operations are concurrency safePanic Protection: Each watcher execution runs in an independentgoroutinewith panic recovery mechanism
Usage
Let me demonstrate how to use the WatcherAdapter functionality through example code:
1. Using Watcher with File Adapter
// Create configuration adapter
c, err := gcfg.NewAdapterFile("config.toml")
if err != nil {
panic(err)
}
// Add watcher
c.AddWatcher("my-watcher", func(ctx context.Context) {
// Get file operation context information
fileCtx := gcfg.GetAdapterFileCtx(ctx)
fmt.Printf("Operation Type: %s\n", fileCtx.GetOperation())
fmt.Printf("File Name: %s\n", fileCtx.GetFileName())
fmt.Printf("File Path: %s\n", fileCtx.GetFilePath())
// Handle different operation types
switch fileCtx.GetOperation() {
case gcfg.OperationWrite:
fmt.Println("Configuration file was modified")
case gcfg.OperationSet:
fmt.Printf("Configuration key %s was set to %v\n", fileCtx.GetKey(), fileCtx.GetValue())
}
})
// Modifying configuration will trigger the watcher
c.Set("key", "new-value")
2. Using Watcher with Content Adapter
// Create content adapter
content := `{"key": "value"}`
adapter, err := gcfg.NewAdapterContent(content)
if err != nil {
panic(err)
}
// Add watcher
adapter.AddWatcher("content-watcher", func(ctx context.Context) {
contentCtx := gcfg.GetAdapterContentCtx(ctx)
fmt.Printf("Content Operation: %s\n", contentCtx.GetOperation())
})
// Setting new content will trigger the watcher
adapter.SetContent(`{"key": "new-value"}`)
3. Using with gcfg.Config Instance
// Create configuration instance
config := g.Cfg()
// Add watcher to the configuration instance's adapter
if adapter, ok := config.GetAdapter().(gcfg.WatcherAdapter); ok {
adapter.AddWatcher("config-watcher", func(ctx context.Context) {
fmt.Println("Configuration has changed")
})
}
Watcher Context Information
Depending on the adapter type, different information can be obtained through the corresponding context. Please refer to the xxxAdapterCtx implementation of different adapter types for details.
For example, with nacos, you can get *NacosAdapterCtx through adapterCtx := nacos.GetAdapterCtx(ctx)
Located at: contrib/config/nacos/nacos_adapter_ctx.go
Context key constants:
ContextKeyNamespace: NamespaceContextKeyGroup: GroupContextKeyDataId: Data IDgcfg.ContextKeyOperation: Operation type (inherited from gcfg)gcfg.ContextKeyContent: Content being set (inherited from gcfg)
Methods:
WithOperation(): Set operation typeWithNamespace(): Set namespaceWithGroup(): Set groupWithDataId(): Set data IDWithContent(): Set contentGetNamespace(): Get namespaceGetGroup(): Get groupGetDataId(): Get data IDGetContent(): Get contentGetOperation(): Get operation type
Practical Application Scenarios
Dynamic Configuration Updates: When configuration files are modified, applications can automatically reload configurationsLogging: Record configuration change historyNotification Mechanism: Notify other components when configuration changesCache Clearing: Clear related caches when configuration changes