Skip to main content
Version: 2.8.x(Latest)

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 NameSupports Watcher Callback
AdapterFileSupported
AdapterContentSupported
polarisSupported
nacosSupported
apolloSupported
consulSupported
kubecmSupported

Core Concepts

  1. WatcherAdapter interface: Defines methods for adding, removing, and retrieving watchers
  2. WatcherRegistry: Watcher registration manager that provides a unified watcher management implementation
  3. context passing: Passes detailed configuration change information through context

Main Features

  1. File Monitoring: Automatically monitors configuration file changes (write, create, delete, rename, permission change)
  2. Manual Trigger: Supports manually triggering watcher callbacks (such as Set operations)
  3. Concurrency Safe: All operations are concurrency safe
  4. Panic Protection: Each watcher execution runs in an independent goroutine with 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: Namespace
  • ContextKeyGroup: Group
  • ContextKeyDataId: Data ID
  • gcfg.ContextKeyOperation: Operation type (inherited from gcfg)
  • gcfg.ContextKeyContent: Content being set (inherited from gcfg)

Methods:

  • WithOperation(): Set operation type
  • WithNamespace(): Set namespace
  • WithGroup(): Set group
  • WithDataId(): Set data ID
  • WithContent(): Set content
  • GetNamespace(): Get namespace
  • GetGroup(): Get group
  • GetDataId(): Get data ID
  • GetContent(): Get content
  • GetOperation(): Get operation type

Practical Application Scenarios

  1. Dynamic Configuration Updates: When configuration files are modified, applications can automatically reload configurations
  2. Logging: Record configuration change history
  3. Notification Mechanism: Notify other components when configuration changes
  4. Cache Clearing: Clear related caches when configuration changes