libatapp

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 11, 2026 License: MIT Imports: 29 Imported by: 0

README

libatapp-go

A Go implementation of the atapp application framework, inspired by the C++ libatapp.

Features

  • Application Lifecycle Management: Complete application lifecycle with Init, Run, Stop, and Reload phases
  • Module System: Plugin-like architecture for extensible functionality
  • Event System: Event-driven architecture with custom event handlers
  • Configuration Management: Command-line flag parsing and configuration file support
  • Signal Handling: Graceful shutdown on OS signals (SIGINT, SIGTERM)
  • Concurrency Safe: Thread-safe operations using mutexes and atomic operations
  • Logging: Built-in logging with configurable levels
  • Performance Optimized: Efficient implementation with minimal allocations

Quick Start

Prepare
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install "github.com/bufbuild/buf/cmd/buf@latest"

# go generate ./...
buf generate
Basic Usage
package main

import (
    "fmt"
    "log"
    atapp "github.com/atframework/libatapp-go"
)

// Custom module example
type MyModule struct {
    name string
}

func (m *MyModule) OnBind(app atapp.AppInstance) error {
    fmt.Printf("Module %s bound to application\n", m.name)
    return nil
}

func (m *MyModule) Setup(app atapp.AppInstance) int {
    fmt.Printf("Module %s setup complete\n", m.name)
    return 0
}

func (m *MyModule) Init(app atapp.AppInstance) int {
    fmt.Printf("Module %s initialized\n", m.name)
    return 0
}

func (m *MyModule) Ready(app atapp.AppInstance) int {
    fmt.Printf("Module %s ready\n", m.name)
    return 0
}

func (m *MyModule) Stop(app atapp.AppInstance) int {
    fmt.Printf("Module %s stopped\n", m.name)
    return 0
}

func (m *MyModule) Cleanup(app atapp.AppInstance) int {
    fmt.Printf("Module %s cleaned up\n", m.name)
    return 0
}

func main() {
    // Create application instance
    app := atapp.CreateAppInstance()
    
    // Add custom module
    module := &MyModule{name: "MyCustomModule"}
    atapp.AtappAddModule[*MyModule](app, module)
    
    // Set custom event handler
    app.SetEventHandler("custom_event", func(app *atapp.AppInstance, args ...interface{}) int {
        fmt.Printf("Custom event triggered with args: %v\n", args)
        return 0
    })
    
    // Initialize and run application
    if ret := app.Init(nil); ret != 0 {
        log.Fatalf("Application initialization failed with code: %d", ret)
    }
    
    // Trigger custom event
    app.TriggerEvent("custom_event", "hello", "world")
    
    // Run application (blocks until shutdown signal)
    ret := app.Run([]string{}, func() int {
        fmt.Println("Application running...")
        return 0
    })
    
    fmt.Printf("Application exited with code: %d\n", ret)
}
Configuration Management
// Set configuration values
app.GetConfig().SetConfFile("config.yaml")
app.GetConfig().SetVersion("1.0.0")
app.GetConfig().SetAppID(12345)
app.GetConfig().SetTypeID(67890)

// Get configuration values
fmt.Printf("App ID: %d\n", app.GetConfig().GetId())
fmt.Printf("Version: %s\n", app.GetConfig().GetVersion())
Command Handling
// Built-in commands
app.ProcessCommand("version")    // Show version info
app.ProcessCommand("help")       // Show help
app.ProcessCommand("stop")       // Graceful shutdown
app.ProcessCommand("reload")     // Reload configuration

Architecture

The framework follows a modular architecture pattern:

  1. AppInstance: Main application container managing lifecycle and modules
  2. AppModuleImpl: Interface for pluggable modules with lifecycle callbacks
  3. AppConfig: Configuration management with flag parsing
  4. Event System: Asynchronous event handling with custom handlers
  5. Signal Processing: OS signal handling for graceful shutdown

Performance

The implementation is optimized for performance:

  • App Creation: ~1150 ns/op with minimal allocations
  • Event Triggering: ~20 ns/op
  • Module Operations: Efficient module management
  • Tick Processing: Low-latency periodic operations

Testing

Run the test suite:

go test -v

Run benchmarks:

go test -bench=. -benchmem

TODO List (Future Enhancements)

  • ✅ app层管理和module结构 (Completed)
  • 协议和配置管理
    • 服务发现配置
    • 动态日志模块
    • 通信层配置
  • connector抽象和接入层实现
    • libatbus-go connector
    • 本地回环 connector
    • endpoint管理和消息缓存
  • etcd模块
    • 服务发现模块接入
  • 策略路由

License

This project follows the same license as the original libatapp C++ implementation.

Documentation

Index

Constants

View Source
const (
	SPLITCHAR = 1 << iota
	STRINGSYM
	TRANSLATE
	CMDSPLIT
)

定义字符映射常量

Variables

View Source
var (
	Version   = "v0.0.0"
	Commit    = "unknown"
	Branch    = "unknown"
	BuildTime = "unknown"
	ConfigVer = "unknown"
	BuildMode = "DEBUG"
)

编译时注入的顶级变量(用于 ldflags)

Functions

func AtappAddModule

func AtappAddModule[ModuleType AppModuleImpl](app AppImpl, module ModuleType) error

func AtappGetModule

func AtappGetModule[ModuleType AppModuleImpl](app AppImpl) ModuleType

func ExpandExpression

func ExpandExpression(input string) string

ExpandExpression expands environment variable expressions in the input string. Supports $VAR, ${VAR}, ${VAR:-default}, ${VAR:+word}, \$ escape, and nested expressions.

func GetEnvUpperKey

func GetEnvUpperKey(key string) string

func LoadConfigFromEnvironemnt

func LoadConfigFromEnvironemnt(envPrefix string, configPb proto.Message, logger *log.Logger,
	loadOptions *LoadConfigOptions, dumpExistedSet *ConfigExistedIndex, existedSetPrefix string,
) (bool, error)

func LoadConfigFromOriginData

func LoadConfigFromOriginData(originData interface{}, prefixPath string, configPb proto.Message, logger *log.Logger,
	loadOptions *LoadConfigOptions, dumpExistedSet *ConfigExistedIndex, existedSetPrefix string,
) (err error)

func LoadConfigFromOriginDataByPath

func LoadConfigFromOriginDataByPath(logger *log.Logger,
	originData interface{}, target proto.Message,
	configurePrefixPath string, loadEnvironemntPrefix string,
	loadOptions *LoadConfigOptions,
	existedKeys *ConfigExistedIndex, existedSetPrefix string,
) (err error)

配置管理

func LoadConfigFromYaml

func LoadConfigFromYaml(configPath string, prefixPath string, configPb proto.Message, logger *log.Logger,
	loadOptions *LoadConfigOptions, dumpExistedSet *ConfigExistedIndex, existedSetPrefix string,
) (yamlData map[string]interface{}, err error)

func LoadConfigOriginYaml

func LoadConfigOriginYaml(configPath string) (yamlData map[string]interface{}, err error)

func LoadDefaultConfigMessageFields

func LoadDefaultConfigMessageFields(configPb proto.Message, logger *log.Logger,
	dumpExistedSet *ConfigExistedIndex, existedSetPrefix string,
) error

func LoadLogCategoryConfigFromEnvironemnt

func LoadLogCategoryConfigFromEnvironemnt(envPrefix string, logCategoryPb *atframe_protocol.AtappLogCategory, logger *log.Logger,
	dumpExistedSet *ConfigExistedIndex, existedSetPrefix string,
) bool

LoadLogCategoryConfigFromEnvironemnt 从环境变量加载日志配置 支持特殊的 sink 配置格式: <前缀>_<CATEGORY_NAME>_<sink 下标>_<大写字段名>

func ParsePlainMessage

func ParsePlainMessage(yamlData map[string]interface{}, msg proto.Message, logger *log.Logger) error

func PrintBuildInfo

func PrintBuildInfo()

PrintBuildInfo 打印编译信息

func RegisterBuildInfoCommand

func RegisterBuildInfoCommand()

RegisterInfoCommand 处理 --info 标志 这个函数会在应用启动前被调用,处理 --info 标志 仅检查命令行参数中是否有 --info,不使用全局 flag 包避免污染其他参数

func SetBuildInfo

func SetBuildInfo(version, gitCommit, gitBranch, buildTime, cfgVersion, buildMode string)

SetBuildInfo 设置编译信息(由 build 命令注入)

Types

type AppActionData

type AppActionData struct {
	App         AppImpl
	MessageData []byte
	PrivateData interface{}
}

AppAction对象

type AppActionSender

type AppActionSender struct {
	// contains filtered or unexported fields
}

type AppConfig

type AppConfig struct {
	// Runtime配置
	HashCode     string
	AppName      string
	BuildVersion string
	AppVersion   string
	ConfigFile   string
	PidFile      string
	ExecutePath  string

	// 日志配置
	StartupLog       []string
	StartupErrorFile string
	CrashOutputFile  string

	// 文件配置
	ConfigPb         *atframe_protocol.AtappConfigure
	ConfigLog        *atframe_protocol.AtappLog
	ConfigOriginData interface{}
}

App 配置

type AppFlag

type AppFlag uint64

App 状态标志

const (
	AppFlagInitializing AppFlag = 1 << iota
	AppFlagInitialized
	AppFlagRunning
	AppFlagStopping
	AppFlagStopped
	AppFlagTimeout
	AppFlagInCallback
	AppFlagInTick
	AppFlagDestroying
)

type AppImpl

type AppImpl interface {
	Run(arguments []string) error

	Init(arguments []string) error
	RunOnce(tickTimer *time.Ticker) error
	Stop() error
	Reload() error

	GetId() uint64
	GetTypeId() uint64
	GetTypeName() string
	GetAppName() string
	GetAppIdentity() string
	GetHashCode() string
	GetAppVersion() string
	GetBuildVersion() string
	GetConfigFile() string

	GetSysNow() time.Time

	AddModule(typeInst lu.TypeID, module AppModuleImpl) error

	GetModule(typeInst lu.TypeID) AppModuleImpl

	// 消息相关
	SendMessage(targetId uint64, msgType int32, data []byte) error
	SendMessageByName(targetName string, msgType int32, data []byte) error

	// 事件相关
	SetEventHandler(eventType string, handler EventHandler)
	TriggerEvent(eventType string, args *AppActionSender) int

	// 自定义Action
	PushAction(callback func(action *AppActionData) error, message_data []byte, private_data interface{}) error

	// 配置相关
	GetConfig() *AppConfig
	LoadConfig(configFile string, configurePrefixPath string, loadEnvironemntPrefix string, existedKeys *ConfigExistedIndex) error
	LoadConfigByPath(target proto.Message,
		configurePrefixPath string, loadEnvironemntPrefix string,
		existedKeys *ConfigExistedIndex, existedSetPrefix string,
	) error
	LoadLogConfigByPath(target *atframe_protocol.AtappLog,
		configurePrefixPath string, loadEnvironemntPrefix string,
		existedKeys *ConfigExistedIndex, existedSetPrefix string,
	) error

	// 状态相关
	IsInited() bool
	IsRunning() bool
	IsClosing() bool
	IsClosed() bool
	CheckFlag(flag AppFlag) bool
	SetFlag(flag AppFlag, value bool) bool

	// 生命周期管理
	GetAppContext() context.Context

	// Logger
	GetDefaultLogger() *log.Logger
	GetLogger(index int) *log.Logger
}

App 应用接口

func CreateAppInstance

func CreateAppInstance() AppImpl

type AppInstance

type AppInstance struct {
	// contains filtered or unexported fields
}

func (*AppInstance) AddModule

func (app *AppInstance) AddModule(typeInst lu.TypeID, module AppModuleImpl) error

func (*AppInstance) CheckFlag

func (app *AppInstance) CheckFlag(flag AppFlag) bool

func (*AppInstance) GetAppContext

func (app *AppInstance) GetAppContext() context.Context

func (*AppInstance) GetAppIdentity

func (app *AppInstance) GetAppIdentity() string

func (*AppInstance) GetAppName

func (app *AppInstance) GetAppName() string

func (*AppInstance) GetAppVersion

func (app *AppInstance) GetAppVersion() string

func (*AppInstance) GetBuildVersion

func (app *AppInstance) GetBuildVersion() string

func (*AppInstance) GetConfig

func (app *AppInstance) GetConfig() *AppConfig

func (*AppInstance) GetConfigFile

func (app *AppInstance) GetConfigFile() string

func (*AppInstance) GetDefaultLogger

func (app *AppInstance) GetDefaultLogger() *log.Logger

func (*AppInstance) GetHashCode

func (app *AppInstance) GetHashCode() string

func (*AppInstance) GetId

func (app *AppInstance) GetId() uint64

Getter methods

func (*AppInstance) GetLogger

func (app *AppInstance) GetLogger(index int) *log.Logger

func (*AppInstance) GetModule

func (app *AppInstance) GetModule(typeInst lu.TypeID) AppModuleImpl

func (*AppInstance) GetSysNow

func (app *AppInstance) GetSysNow() time.Time

func (*AppInstance) GetTypeId

func (app *AppInstance) GetTypeId() uint64

func (*AppInstance) GetTypeName

func (app *AppInstance) GetTypeName() string

func (*AppInstance) Init

func (app *AppInstance) Init(arguments []string) error

func (*AppInstance) InitLog

func (app *AppInstance) InitLog(config *atframe_protocol.AtappLog) (*AppLog, error)

func (*AppInstance) IsClosed

func (app *AppInstance) IsClosed() bool

func (*AppInstance) IsClosing

func (app *AppInstance) IsClosing() bool

func (*AppInstance) IsInited

func (app *AppInstance) IsInited() bool

func (*AppInstance) IsRunning

func (app *AppInstance) IsRunning() bool

func (*AppInstance) LoadConfig

func (app *AppInstance) LoadConfig(configFile string, configurePrefixPath string,
	loadEnvironemntPrefix string, existedKeys *ConfigExistedIndex,
) (err error)

配置管理

func (*AppInstance) LoadConfigByPath

func (app *AppInstance) LoadConfigByPath(target proto.Message,
	configurePrefixPath string, loadEnvironemntPrefix string,
	existedKeys *ConfigExistedIndex, existedSetPrefix string,
) error

func (*AppInstance) LoadLogConfigByPath

func (app *AppInstance) LoadLogConfigByPath(target *atframe_protocol.AtappLog,
	configurePrefixPath string, loadEnvironemntPrefix string,
	existedKeys *ConfigExistedIndex, existedSetPrefix string,
) error

func (*AppInstance) LoadOriginConfigData

func (app *AppInstance) LoadOriginConfigData(configFile string) (err error)

func (*AppInstance) MakeAction

func (app *AppInstance) MakeAction(callback func(action *AppActionData) error, message_data []byte, private_data interface{}) *AppActionSender

func (*AppInstance) PushAction

func (app *AppInstance) PushAction(callback func(action *AppActionData) error, message_data []byte, private_data interface{}) error

辅助方法:写入PID文件

func (*AppInstance) Reload

func (app *AppInstance) Reload() error

func (*AppInstance) Run

func (app *AppInstance) Run(arguments []string) error

func (*AppInstance) RunCommand

func (app *AppInstance) RunCommand(arguments []string) error

func (*AppInstance) RunOnce

func (app *AppInstance) RunOnce(tickTimer *time.Ticker) error

func (*AppInstance) SendMessage

func (app *AppInstance) SendMessage(targetId uint64, msgType int32, data []byte) error

消息相关

func (*AppInstance) SendMessageByName

func (app *AppInstance) SendMessageByName(targetName string, msgType int32, data []byte) error

func (*AppInstance) SetEventHandler

func (app *AppInstance) SetEventHandler(eventType string, handler EventHandler)

事件相关

func (*AppInstance) SetFlag

func (app *AppInstance) SetFlag(flag AppFlag, value bool) bool

func (*AppInstance) Stop

func (app *AppInstance) Stop() error

func (*AppInstance) TriggerEvent

func (app *AppInstance) TriggerEvent(eventType string, args *AppActionSender) int

type AppLog

type AppLog struct {
	// contains filtered or unexported fields
}

type AppMode

type AppMode int

App 应用模式

const (
	AppModeCustom AppMode = iota
	AppModeStart
	AppModeStop
	AppModeReload
	AppModeInfo
	AppModeHelp
)

type AppModuleBase

type AppModuleBase struct {
	// contains filtered or unexported fields
}

func CreateAppModuleBase

func CreateAppModuleBase(owner AppImpl) AppModuleBase

func (*AppModuleBase) Active

func (m *AppModuleBase) Active()

func (*AppModuleBase) Cleanup

func (m *AppModuleBase) Cleanup()

func (*AppModuleBase) Disable

func (m *AppModuleBase) Disable()

func (*AppModuleBase) Enable

func (m *AppModuleBase) Enable()

func (*AppModuleBase) GetApp

func (m *AppModuleBase) GetApp() AppImpl

func (*AppModuleBase) GetSysNow

func (m *AppModuleBase) GetSysNow() time.Time

func (*AppModuleBase) IsActived

func (m *AppModuleBase) IsActived() bool

func (*AppModuleBase) IsEnabled

func (m *AppModuleBase) IsEnabled() bool

func (*AppModuleBase) OnBind

func (m *AppModuleBase) OnBind()

func (*AppModuleBase) OnUnbind

func (m *AppModuleBase) OnUnbind()

func (*AppModuleBase) Ready

func (m *AppModuleBase) Ready()

func (*AppModuleBase) Reload

func (m *AppModuleBase) Reload() error

func (*AppModuleBase) Setup

func (m *AppModuleBase) Setup(_initCtx context.Context) error

func (*AppModuleBase) SetupLog

func (m *AppModuleBase) SetupLog(_initCtx context.Context) error

func (*AppModuleBase) Stop

func (m *AppModuleBase) Stop() (bool, error)

func (*AppModuleBase) Tick

func (m *AppModuleBase) Tick(_initCtx context.Context) bool

func (*AppModuleBase) Timeout

func (m *AppModuleBase) Timeout()

func (*AppModuleBase) Unactive

func (m *AppModuleBase) Unactive()

type AppModuleImpl

type AppModuleImpl interface {
	GetApp() AppImpl

	Name() string

	// Call this callback when a module is added into atapp for the first time
	OnBind()

	// Call this callback when a module is removed from atapp
	OnUnbind()

	// This callback is called after load configure and before initialization(include log)
	Setup(parent context.Context) error

	// This function will be called after reload and before init
	SetupLog(parent context.Context) error

	// This callback is called to initialize a module
	Init(parent context.Context) error

	// This callback is called after all modules are initialized successfully and the atapp is ready to run
	Ready()

	// This callback is called after configure is reloaded
	Reload() error

	// This callback may be called more than once, when the first return false, or this module will be disabled.
	Stop() (bool, error)

	// This callback only will be call once after all module stopped
	Cleanup()

	// This callback be called if the module can not be stopped even in a long time.
	// After this event, all module and atapp will be forced stopped.
	Timeout()

	// This function will be called in every tick if it's actived. return true when busy.
	Tick(parent context.Context) bool

	IsActived() bool
	Active()
	Unactive()

	IsEnabled() bool
	Enable()
	Disable()
}

App 应用接口

type BuildInfo

type BuildInfo struct {
	Version       string // 版本号
	GitCommit     string // Git 提交哈希
	GitBranch     string // Git 分支
	BuildTime     string // 构建时间
	ConfigVersion string // 构建配置
	BuildMode     string // DEBUG 或 Release
}

BuildInfo 存储编译注入的信息

func GetBuildInfo

func GetBuildInfo() BuildInfo

GetBuildInfo 获取编译信息

func (BuildInfo) ToString

func (b BuildInfo) ToString() string

type CommandHandler

type CommandHandler func(*AppInstance, string, []string) error

命令处理相关

type CommandManager

type CommandManager struct {
	// contains filtered or unexported fields
}

func NewCommandManager

func NewCommandManager() *CommandManager

func (*CommandManager) ExecuteCommand

func (cm *CommandManager) ExecuteCommand(app *AppInstance, command string, args []string) error

func (*CommandManager) ListCommands

func (cm *CommandManager) ListCommands() []string

func (*CommandManager) RegisterCommand

func (cm *CommandManager) RegisterCommand(name string, handler CommandHandler)

type ConfigExistedIndex

type ConfigExistedIndex struct {
	ExistedSet  map[string]struct{}
	MapKeyIndex map[string]int
}

func CreateConfigExistedIndex

func CreateConfigExistedIndex() *ConfigExistedIndex

func (*ConfigExistedIndex) MutableExistedSet

func (i *ConfigExistedIndex) MutableExistedSet() map[string]struct{}

func (*ConfigExistedIndex) MutableMapKeyIndex

func (i *ConfigExistedIndex) MutableMapKeyIndex() map[string]int

type EventHandler

type EventHandler func(*AppInstance, *AppActionSender) int

事件处理函数类型

type LoadConfigOptions

type LoadConfigOptions struct {
	ReorderListIndexByField string
}

type Message

type Message struct {
	Type       int32
	Sequence   uint64
	Data       []byte
	Metadata   map[string]string
	SourceId   uint64
	SourceName string
}

消息类型

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL