2026-03-11 13:02:37 +00:00
---
title: Lifecycle
2026-03-21 10:05:04 +00:00
description: Startup, shutdown, context ownership, and background task draining.
2026-03-11 13:02:37 +00:00
---
# Lifecycle
2026-03-21 10:05:04 +00:00
CoreGO manages lifecycle through `core.Service` callbacks, not through reflection or implicit interfaces.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## Service Hooks
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
c.Service("cache", core.Service{
OnStart: func() core.Result {
return core.Result{OK: true}
},
OnStop: func() core.Result {
return core.Result{OK: true}
},
})
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
Only services with `OnStart` appear in `Startables()` . Only services with `OnStop` appear in `Stoppables()` .
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## `ServiceStartup`
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
r := c.ServiceStartup(context.Background(), nil)
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
### What It Does
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
1. clears the shutdown flag
2. stores a new cancellable context on `c.Context()`
3. runs each `OnStart`
4. broadcasts `ActionServiceStartup{}`
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
### Failure Behavior
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
- if the input context is already cancelled, startup returns that error
- if any `OnStart` returns `OK:false` , startup stops immediately and returns that result
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## `ServiceShutdown`
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
r := c.ServiceShutdown(context.Background())
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
### What It Does
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
1. sets the shutdown flag
2. cancels `c.Context()`
3. broadcasts `ActionServiceShutdown{}`
4. waits for background tasks created by `PerformAsync`
5. runs each `OnStop`
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
### Failure Behavior
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
- if draining background tasks hits the shutdown context deadline, shutdown returns that context error
- when service stop hooks fail, CoreGO returns the first error it sees
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## Ordering
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
The current implementation builds `Startables()` and `Stoppables()` by iterating over a map-backed registry.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
That means lifecycle order is not guaranteed today.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
If your application needs strict startup or shutdown ordering, orchestrate it explicitly inside a smaller number of service callbacks instead of relying on registry order.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## `c.Context()`
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
`ServiceStartup` creates the context returned by `c.Context()` .
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
Use it for background work that should stop when the application shuts down:
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
c.Service("watcher", core.Service{
OnStart: func() core.Result {
go func(ctx context.Context) {
< -ctx.Done ( )
}(c.Context())
return core.Result{OK: true}
},
2026-03-11 13:02:37 +00:00
})
```
2026-03-21 10:05:04 +00:00
## Built-In Lifecycle Actions
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
You can listen for lifecycle state changes through the action bus.
2026-03-11 13:02:37 +00:00
```go
2026-03-21 10:05:04 +00:00
c.RegisterAction(func(_ *core.Core, msg core.Message) core.Result {
switch msg.(type) {
case core.ActionServiceStartup:
core.Info("core startup completed")
case core.ActionServiceShutdown:
core.Info("core shutdown started")
}
return core.Result{OK: true}
})
2026-03-11 13:02:37 +00:00
```
2026-03-21 10:05:04 +00:00
## Background Task Draining
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
`ServiceShutdown` waits for the internal task waitgroup to finish before calling stop hooks.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
This is what makes `PerformAsync` safe for long-running work that should complete before teardown.
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
## `OnReload`
2026-03-11 13:02:37 +00:00
2026-03-21 10:05:04 +00:00
`Service` includes an `OnReload` callback field, but CoreGO does not currently expose a top-level lifecycle runner for reload operations.