Documentation
¶
Index ¶
Constants ¶
const ( CatalogueDumpPathEnv = "DXLIB_CATALOGUE_PATH" CatalogueDumpCommitEnv = "DXLIB_CATALOGUE_COMMIT" )
CatalogueDumpPathEnv and CatalogueDumpCommitEnv give the "path" and "commit" members of every catalogue the dump writes: the source the models are declared in, from the repository's root, and the commit that last changed it. The service cannot know either, so the tool that runs the dump sets them; unset, both are written as "".
const CatalogueDumpFileSuffix = ".catalogue.json"
CatalogueDumpFileSuffix is appended to a model's Name to name its catalogue in the dump directory: the "core" model is written to core.catalogue.json.
const OpenAPIDumpEnv = "DXLIB_OPENAPI_DUMP"
OpenAPIDumpEnv names the environment variable that turns Run into an OpenAPI dump. Set to a directory, it makes Run write the OpenAPI document of every API the service defines, and the catalogue of every data model in DXApp.ModelDBs, into that directory and end the process, without serving, connecting to anything, or starting a task:
DXLIB_OPENAPI_DUMP=out/openapi ./my-service
It is how a tool reads a service's API surface and declared data model from what dxlib itself emits, instead of from a per-service program that repeats main's wiring. Every service built on DXApp has it, with no code of its own.
const OpenAPIDumpFileSuffix = ".openapi.json"
OpenAPIDumpFileSuffix is appended to an API's NameId to name its file in the dump directory: the "api" API is written to api.openapi.json.
Variables ¶
var BuildTime string // injectable via -ldflags="-X 'github.com/donnyhardyanto/dxlib/app.BuildTime=...'"
Functions ¶
Types ¶
type DXApp ¶
type DXApp struct {
NameId string
Title string
Description string
Version string
Args DXAppArgs
IsLoop bool
LoopInterval time.Duration
RuntimeErrorGroup *errgroup.Group
RuntimeErrorGroupContext context.Context
LocalData map[string]any
IsRedisExist bool
IsStorageExist bool
IsObjectStorageExist bool
IsAPIExist bool
IsHTTPClientExist bool
IsTaskExist bool
DebugKey string
DebugValue string
OnDefine DXAppEvent
OnDefineConfiguration DXAppEvent
OnDefineSetVariables DXAppEvent
OnDefineAPIEndPoints DXAppEvent
OnAfterConfigurationStartAll DXAppEvent
OnExecute DXAppEvent
OnStartStorageReady DXAppEvent
OnStopping DXAppEvent
InitVault *vault.DXHashicorpVault
EncryptionVault *vault.DXHashicorpVault
// ModelDBs are the data models the service declares, one per database.
// The OpenAPI dump writes each as a catalogue document; see
// runOpenAPIDump. Nothing else reads them.
ModelDBs []*models.ModelDB
}
var App DXApp
func (*DXApp) Run ¶
Run starts the application and returns when it stops. With OpenAPIDumpEnv set it writes the OpenAPI documents and the models' catalogues instead and ends the process; see runOpenAPIDump.
func (*DXApp) RunAndExit ¶
func (a *DXApp) RunAndExit()
RunAndExit runs the application and, if it fails, ends the process with a non-zero status.
It exists because the exit status matters more than it looks, and was being thrown away. Every service in this family ended main with
_ = dxlibApp.App.Run()
which discards the error. A service that could not read its configuration file, or could not reach its database, logged the reason and then exited **0**. Everything that reads an exit status -- a Kubernetes liveness probe, a systemd unit with Restart=on-failure, a supervisor, a CI step, a shell && -- reads 0 as "did its job". So a service that never started looked like one that had started and finished cleanly. That is also how a startup panic in push-notification-server stayed invisible for as long as it did: the build passed, and running it appeared to succeed.
Run already logs the error before returning it, so nothing is logged twice here. Logging in this library is synchronous, so the line explaining the failure is on disk before the process goes.
On success it returns rather than calling os.Exit(0), so any deferred work in the caller still runs; as the last statement of main that ends the process with 0 anyway:
func main() {
dxlibApp.Set(...)
dxlibApp.App.OnDefineConfiguration = defineConfiguration
dxlibApp.App.RunAndExit()
}
A caller that needs to distinguish failure kinds, or to do its own cleanup, should call Run and handle the error -- but must not discard it.
func (*DXApp) SetupNewRelicApplication ¶
func (a *DXApp) SetupNewRelicApplication()
func (*DXApp) SetupOpenTelemetry ¶
func (a *DXApp) SetupOpenTelemetry()
type DXAppArgCommand ¶
type DXAppArgCommand struct {
// contains filtered or unexported fields
}
type DXAppArgCommandFunc ¶
type DXAppArgCommandFunc func(s *DXApp, ac *DXAppArgCommand, T any) (err error)
type DXAppArgOption ¶
type DXAppArgOption struct {
// contains filtered or unexported fields
}
type DXAppArgOptionFunc ¶
type DXAppArgOptionFunc func(s *DXApp, ac *DXAppArgOption, T any) (err error)
type DXAppArgs ¶
type DXAppArgs struct {
Commands map[string]*DXAppArgCommand
Options map[string]*DXAppArgOption
}
type DXAppCallbackFunc ¶
type DXAppCallbackFunc func() (err error)
type DXAppEvent ¶
type DXAppEvent func() (err error)