58e5e33e18
Document lifecycle concepts, companion packages, and API reference. Add gitignore for coverage artifacts. Co-authored-by: Cursor <cursoragent@cursor.com>
92 lines
2.8 KiB
Markdown
92 lines
2.8 KiB
Markdown
# app
|
|
|
|
app orchestrates modular application setup and teardown for Go services.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
go get gitea.auvem.com/go-toolkit/app
|
|
```
|
|
|
|
## Quick start
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
"gitea.auvem.com/go-toolkit/applog"
|
|
"gitea.auvem.com/go-toolkit/app"
|
|
)
|
|
|
|
func main() {
|
|
lifecycle := app.NewLifecycle(
|
|
applog.AppLogOpts{ConsoleOutput: os.Stderr}.Module(),
|
|
)
|
|
defer func() {
|
|
if err := lifecycle.Teardown(); err != nil {
|
|
fmt.Println("shutdown error:", err)
|
|
}
|
|
}()
|
|
|
|
if err := lifecycle.Setup(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
ctx := lifecycle.Context(context.Background())
|
|
_ = ctx
|
|
lifecycle.Logger().Info("ready")
|
|
}
|
|
```
|
|
|
|
## Concepts
|
|
|
|
- **Module** — a named subsystem with optional `Setup`, `Teardown`, and `Depends`
|
|
- **Lifecycle** — holds modules and runs setup/teardown in dependency order
|
|
- **Setup** — initializes all modules registered via `NewLifecycle`
|
|
- **Require** — adds and initializes modules on demand (typical for CLI subcommands via [appcli](https://gitea.auvem.com/go-toolkit/appcli))
|
|
- **Autoload** — when enabled (default), `Depends` names are set up automatically before the dependent module
|
|
|
|
## Dependencies
|
|
|
|
List dependency module **names** in `ModuleOpts.Depends`. Dependent modules must be registered in the same lifecycle (via `NewLifecycle` or an earlier `Require`). Circular dependencies return an error.
|
|
|
|
## Teardown
|
|
|
|
Always defer `lifecycle.Teardown()`. Teardown runs in **reverse setup order** so dependents shut down before their dependencies.
|
|
|
|
## Context
|
|
|
|
Use `lifecycle.Context(ctx)` so downstream code and `appcli` commands can call `app.LifecycleFromContext(ctx)`.
|
|
|
|
## Companion packages
|
|
|
|
| Package | Role |
|
|
|---------|------|
|
|
| [applog](https://gitea.auvem.com/go-toolkit/applog) | slog + tint logging module |
|
|
| [appcli](https://gitea.auvem.com/go-toolkit/appcli) | urfave/cli v3 integration |
|
|
| [dbx](https://gitea.auvem.com/go-toolkit/dbx) | database module |
|
|
| [migrate](https://gitea.auvem.com/go-toolkit/migrate) | goose migrations module |
|
|
|
|
## API reference
|
|
|
|
| Symbol | Description |
|
|
|--------|-------------|
|
|
| `NewLifecycle(modules...)` | Create lifecycle with optional initial modules |
|
|
| `Lifecycle.Setup()` | Set up all registered modules |
|
|
| `Lifecycle.Teardown()` | Tear down in reverse setup order |
|
|
| `Lifecycle.Require(modules...)` | Set up modules on demand |
|
|
| `Lifecycle.RequireWithOpts(opts, modules...)` | Require with custom logger or unique-name enforcement |
|
|
| `Lifecycle.GetModule(name)` | Look up a registered module |
|
|
| `NewModule(name, opts)` | Define a module |
|
|
| `LifecycleFromContext(ctx)` | Retrieve lifecycle from context |
|
|
|
|
## Error handling
|
|
|
|
- Partial setup failure rolls back already-initialized modules
|
|
- `Teardown` joins errors from all modules but attempts every teardown
|
|
- A second `Setup` or `Teardown` on the same lifecycle returns an error
|