Files
golib/config/README.md
nabbar 9e8179374b README:
- Add some README file to give missing documentations or update existing documentation file

Package Archive:
- Add some comments to godoc information
- Moving NopWriterCloser interface to ioutils package

Package IOUtils:
- New package NopWriterCloser to implement interfac like NopReader

Package Database:
- KVMap: fix missing function following update of kvdriver

Package Duration:
- Rename BDD testing

Package Context/Gin:
- Moving function New between model & interface file

Package AWS:
- rework Walk function to use more generic with standard walk caller function
- func walk will now no more return and include error (can be catched into the given func)
- func walk will now return a bool to continue or stop the loop
- func walk with many input function will now stop when all given function return false
- func walk will now return error only about main process and not given function

Package errors:
- Add interface error into interface Error

Package IOUtils:
- Moving IOWrapper as subPackage and optimize process + allow thread safe
2025-05-25 06:29:25 +02:00

247 lines
8.3 KiB
Markdown

# golib/config
This package provides a modular configuration management system for Go applications, supporting dynamic components, context management, lifecycle events, logging, monitoring, and shell integration.
## Features
- **Centralized configuration management** using Viper.
- **Dynamic components**: add, remove, start, stop, reload, and manage dependencies.
- **Context management**: cancellation, custom hooks.
- **Lifecycle events**: hooks before/after start, reload, stop.
- **Configurable logging**.
- **Component monitoring**.
- **Integrated shell commands** for component control.
## Installation
Add to your `go.mod`:
```
require github.com/nabbar/golib/config vX.Y.Z
```
## Quick Start
```go
import (
"github.com/nabbar/golib/config"
"github.com/nabbar/golib/version"
)
func main() {
vrs := version.New("1.0.0")
cfg := config.New(vrs)
// Register your components here
// cfg.ComponentSet("myComponent", myComponentInstance)
// Register hooks, logger, etc.
// cfg.RegisterFuncStartBefore(func() error { ...; return nil })
if err := cfg.Start(); err != nil {
panic(err)
}
// ...
cfg.Shutdown(0)
}
```
## Main Interfaces
- **Config**: main interface, see `config/interface.go`.
- **Component**: to implement for each component, see `config/types/component.go`.
## Lifecycle Methods
- `Start() error`: starts all registered components respecting dependencies.
- `Reload() error`: reloads configuration and components.
- `Stop()`: stops all components cleanly.
- `Shutdown(code int)`: stops everything and exits the process.
## Component Management
- `ComponentSet(key, cpt)`: register a component.
- `ComponentGet(key)`: retrieve a component.
- `ComponentDel(key)`: remove a component.
- `ComponentList()`: get all components.
- `ComponentStart()`, `ComponentStop()`, `ComponentReload()`: global actions.
## Event Hooks
Register functions to be called before/after each lifecycle step:
```go
cfg.RegisterFuncStartBefore(func() error { /* ... */ return nil })
cfg.RegisterFuncStopAfter(func() error { /* ... */ return nil })
cfg.RegisterFuncReloadBefore(func() error { /* ... */ return nil })
cfg.RegisterFuncReloadAfter(func() error { /* ... */ return nil })
```
## Context and Cancellation
- `Context()`: returns the config context instance.
- `CancelAdd(func())`: register custom functions to call on context cancel.
- `CancelClean()`: clear all registered cancel functions.
## Shell Commands
Expose commands to list, start, stop, and restart components:
```go
cmds := cfg.GetShellCommand()
// Integrate these into your CLI
```
Available commands:
- `list`: list all components
- `start`: start components (all or by name)
- `stop`: stop components (all or by name)
- `restart`: restart components (all or by name)
## Signal Handling
Handles system signals (SIGINT, SIGTERM, SIGQUIT) for graceful shutdown via `WaitNotify()`.
## Default Configuration Generation
Generate a default configuration (JSON) for all registered components:
```go
r := cfg.DefaultConfig()
// r is an io.Reader containing the default config JSON
```
## Component Interface
To create a component, implement the following interface (see `config/types/component.go`):
```go
type Component interface {
Type() string
Init(key string, ctx libctx.FuncContext, get FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog)
DefaultConfig(indent string) []byte
Dependencies() []string
SetDependencies(d []string) error
RegisterFlag(Command *spfcbr.Command) error
RegisterMonitorPool(p montps.FuncPool)
RegisterFuncStart(before, after FuncCptEvent)
RegisterFuncReload(before, after FuncCptEvent)
IsStarted() bool
IsRunning() bool
Start() error
Reload() error
Stop()
}
```
---
## Creating a Config Component
This guide explains how to implement a new config component for the `golib/config` system. Components are modular units that can be registered, started, stopped, reloaded, and monitored within the configuration framework.
### 1. Component Structure
A component should implement the `Component` interface, which defines lifecycle methods, dependency management, configuration, and monitoring hooks.
**Example structure:**
```go
type componentMyType struct {
x libctx.Config[uint8] // Context and config storage
// Add your own fields here (atomic values, state, etc.)
}
```
### 2. Implementing the Interface
Implement the following methods:
- `Type() string`: Returns the component type name.
- `Init(key, ctx, get, vpr, vrs, log)`: Initializes the component with its key, context, dependency getter, viper, version, and logger.
- `DefaultConfig(indent string) []byte`: Returns the default configuration as JSON (or other format).
- `Dependencies() []string`: Lists required component dependencies.
- `SetDependencies(d []string) error`: Sets dependencies.
- `RegisterFlag(cmd *cobra.Command) error`: Registers CLI flags.
- `RegisterMonitorPool(fct montps.FuncPool)`: Registers a monitor pool for health/metrics.
- `RegisterFuncStart(before, after FuncCptEvent)`: Registers hooks for start events.
- `RegisterFuncReload(before, after FuncCptEvent)`: Registers hooks for reload events.
- `IsStarted() bool`: Returns true if started.
- `IsRunning() bool`: Returns true if running.
- `Start() error`: Starts the component.
- `Reload() error`: Reloads the component.
- `Stop()`: Stops the component.
### 3. Configuration Handling
- Use Viper for configuration loading.
- Implement a method to unmarshal and validate the config section for your component.
- Provide a static default config as a JSON/YAML byte slice.
### 4. Lifecycle Management
- Use atomic values or context for thread-safe state.
- Implement logic for `Start`, `Reload`, and `Stop` to manage resources and state.
- Use hooks (`RegisterFuncStart`, `RegisterFuncReload`) to allow custom logic before/after lifecycle events.
### 5. Dependency Management
- Use `Dependencies()` and `SetDependencies()` to declare and manage required components (e.g., TLS, logger).
- Retrieve dependencies using the provided `FuncCptGet` function.
### 6. Monitoring Integration
- Implement `RegisterMonitorPool` to support health and metrics monitoring.
- Use the monitor pool to register and manage monitor instances for your component.
### 7. Example Skeleton
```go
type componentMyType struct {
x libctx.Config[uint8]
// Add fields as needed
}
func (o *componentMyType) Type() string { return "mytype" }
func (o *componentMyType) Init(key string, ctx libctx.FuncContext, get cfgtps.FuncCptGet, vpr libvpr.FuncViper, vrs libver.Version, log liblog.FuncLog) {
o.x.Store( /* ... */ )
}
func (o *componentMyType) DefaultConfig(indent string) []byte { /* ... */ }
func (o *componentMyType) Dependencies() []string { /* ... */ }
func (o *componentMyType) SetDependencies(d []string) error { /* ... */ }
func (o *componentMyType) RegisterFlag(cmd *cobra.Command) error { /* ... */ }
func (o *componentMyType) RegisterMonitorPool(fct montps.FuncPool) { /* ... */ }
func (o *componentMyType) RegisterFuncStart(before, after cfgtps.FuncCptEvent) { /* ... */ }
func (o *componentMyType) RegisterFuncReload(before, after cfgtps.FuncCptEvent) { /* ... */ }
func (o *componentMyType) IsStarted() bool { /* ... */ }
func (o *componentMyType) IsRunning() bool { /* ... */ }
func (o *componentMyType) Start() error { /* ... */ }
func (o *componentMyType) Reload() error { /* ... */ }
func (o *componentMyType) Stop() { /* ... */ }
```
### 8. Registration
Register your component with the config system:
```go
cfg.ComponentSet("myComponentKey", myComponentInstance)
```
### 9. Error Handling
- Define error codes and messages for your component.
- Return errors using the `liberr.Error` type for consistency.
---
**Note:**
- Use atomic values for thread safety.
- Always validate configuration before starting the component.
- Integrate logging and monitoring as needed.
- Follow the modular and decoupled design to ensure maintainability and testability.
- Consider using context for cancellation and timeouts in long-running operations.
- Ensure proper cleanup in the `Stop` method to release resources gracefully.