Documentation
¶
Overview ¶
Package integration adapts caller-owned startup and shutdown hooks into the service lifecycle without owning their implementations or providers.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidConfig = errors.New("invalid service integration configuration")
ErrInvalidConfig identifies invalid integration configuration.
Functions ¶
func New ¶
New adapts hooks into one ordered service component. A hook error is returned unchanged for errors.Is and errors.As policy and is not logged automatically.
Example ¶
package main
import (
"context"
"fmt"
"github.com/faustbrian/go-service/integration"
)
func main() {
component, err := integration.New("configuration", integration.Hooks{
Start: func(context.Context) error {
fmt.Println("load and validate configuration")
return nil
},
})
if err != nil {
panic(err)
}
if err := component.Start(context.Background()); err != nil {
panic(err)
}
}
Output: load and validate configuration
Example (QueueAndScheduler) ¶
package main
import (
"context"
"fmt"
"time"
"github.com/faustbrian/go-service"
"github.com/faustbrian/go-service/integration"
)
func main() {
queue, err := integration.New("queue", integration.Hooks{
Start: func(context.Context) error {
fmt.Println("start queue")
return nil
},
Stop: func(context.Context) error {
fmt.Println("release queue")
return nil
},
})
if err != nil {
panic(err)
}
scheduler, err := integration.New("scheduler", integration.Hooks{
Start: func(context.Context) error {
fmt.Println("start scheduler")
return nil
},
Stop: func(context.Context) error {
fmt.Println("drain scheduler")
return nil
},
})
if err != nil {
panic(err)
}
runtime, err := service.New(service.Config{
Components: []service.Component{queue, scheduler},
})
if err != nil {
panic(err)
}
if err := runtime.Start(context.Background()); err != nil {
panic(err)
}
if err := runtime.Go("scheduler", func(ctx context.Context) error {
<-ctx.Done()
return nil
}); err != nil {
panic(err)
}
shutdownContext, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := runtime.Shutdown(shutdownContext); err != nil {
panic(err)
}
}
Output: start queue start scheduler drain scheduler release queue
Types ¶
type ConfigError ¶
type ConfigError struct {
// Field identifies the rejected configuration path.
Field string
// Reason describes why Field was rejected.
Reason string
}
ConfigError identifies one invalid integration field.
func (*ConfigError) Unwrap ¶
func (err *ConfigError) Unwrap() error
Unwrap makes ConfigError inspectable with errors.Is.
type Hooks ¶
type Hooks struct {
// CloseAdmission synchronously stops new work before accepted work drains.
// It must be idempotent and return promptly. Nil is a valid no-op.
CloseAdmission func() error
// Start performs caller-owned startup work. Nil is a valid no-op.
Start Hook
// Stop reverses a successful Start. Nil is a valid no-op.
Stop Hook
}
Hooks contains optional caller-owned startup and shutdown functions.
type Option ¶
type Option func(*config) error
Option configures an integration component.
func WithSlog ¶
WithSlog reports hook lifecycle status through a caller-owned logger. The logger handler is never closed, replaced, or otherwise owned by this package.
Example ¶
package main
import (
"context"
"fmt"
"log/slog"
"os"
"time"
"github.com/faustbrian/go-service/integration"
)
func main() {
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
ReplaceAttr: func(_ []string, attribute slog.Attr) slog.Attr {
if attribute.Key == slog.TimeKey {
return slog.Attr{}
}
return attribute
},
}))
component, err := integration.New(
"telemetry",
integration.Hooks{
Start: func(context.Context) error {
fmt.Println("register caller-owned provider")
return nil
},
},
integration.WithSlog(logger, slog.Duration("timeout", time.Second)),
)
if err != nil {
panic(err)
}
if err := component.Start(context.Background()); err != nil {
panic(err)
}
}
Output: level=INFO msg="integration starting" component=telemetry timeout=1s register caller-owned provider level=INFO msg="integration started" component=telemetry timeout=1s