4cd218f6585a0ebd3e5a6587aaaa03a8f4324f10
Guard against double setup when autoload runs dependencies early, tear down in reverse setup order, roll back on partial failure, and detect circular Depends chains. Co-authored-by: Cursor <cursoragent@cursor.com>
app
app is a simple and lightweight app lifecycle management library.
Example
Keep your main.go as simple as possible, all it's responsible for is creating the lifecycle, defining a default logger, and orchestrating setup and teardown.
main.go
package main
import (
"context"
"fmt"
"log/slog"
"gitea.auvem.com/go-toolkit/app"
)
func main() {
// Create a new lifecycle, defaulting to no printed logs
lifecycle := app.NewLifecycle().WithLogger(slog.New(slog.DiscardHandler))
defer func() {
if err := lifecycle.Teardown(); err != nil {
fmt.Println("Error during shutdown", err)
}
}()
// Encodes the lifecycle into a context to be used downstream
ctx := lifecycle.Context(context.Background())
// Off to you, call your entrypoint here.
Hello(ctx)
}
Now, let's define a basic logging module and handle loading that module.
logger.go
package main
import (
"log/slog"
"gitea.auvem.com/go-toolkit/app"
)
func ModuleLog(setDefault bool) *app.Module {
return app.NewModule("logger", app.ModuleOpts{
Setup: func(m *app.Module) error {
handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{})
if setDefault {
slog.SetDefault(handler)
}
m.Lifecycle().WithLogger(handler)
}
})
}
Logging can, however, be somewhat of a complex operation in itself, so I'd highly recommend checking out my applog project, which features tight integration with this app.
Finally, lets put our new lifecycle (and logger) to work!
hello.go
package main
import (
"context"
"gitea.auvem.com/go-toolkit/app"
)
func Hello(ctx context.Context) {
app := app.LifecycleFromContext(ctx)
if app == nil {
panic("hello must run within an app lifecycle")
}
lifecycle.Require(ModuleLog(true))
app.Logger().Info("Hello world!", "foo", "bar")
}
Description
app helps streamline core setup and teardown functions, defining dependency graphs for each module.
Languages
Go
100%