A Go microservices framework with runtime launcher and services runner
- Logger
- Launcher
- Services
- Services runner
- Service
Enabler
interface - Service
HealthChecker
interface - Metrics
- Health checker
- Ping pong service
- Http transport
- GRPC transport
- GRPC client
- ConnectRPC transport
- ConnectRPC client
- Config loader
Repo with example
var version = "local"
var appName = "mx-example"
logger := logger.New(
logger.WithAppVersion(version),
logger.WithAppName(appName),
)
ln := launcher.New(
launcher.WithName(appName),
launcher.WithLogger(logger),
launcher.WithVersion(version),
launcher.WithContext(context.Background()),
launcher.WithAfterStart(func() error {
logger.Infoln("app", appName, "was started")
return nil
}),
launcher.WithAfterStop(func() error {
logger.Infoln("app", appName, "was stopped")
return nil
}),
)
// init
svc := service.New(
service.WithName("test-service"),
service.WithStart(func(_ context.Context) error {
return nil
}),
service.WithStop(func(_ context.Context) error {
time.Sleep(time.Second * 3)
return nil
}),
)
// register in launcher
ln.ServicesRunner().Register(svc)
// init
pingPongSvc := service.New(service.WithService(pingpong.New(logger)))
// register in launcher
ln.ServicesRunner().Register(pingPongSvc)
You can also register any service that implements the following interface
type IService interface {
Name() string
Start(ctx context.Context) error
Stop(ctx context.Context) error
}
type books struct {
name string
hcInterval time.Duration
}
func New() *books {
return &books{
name: "books-service",
hcInterval: time.Second * 3,
}
}
func (s books) Name() string { return s.name }
func (s books) Healthy(ctx context.Context) error { return nil }
func (s books) Interval() time.Duration { return s.hcInterval }
func (s books) Start(ctx context.Context) error {
<-ctx.Done()
return nil
}
func (s books) Stop(ctx context.Context) error { return nil }
var _ service.HealthChecker = (*books)(nil)
var _ service.IService = (*books)(nil)
func main() {
ln := launcher.New()
// register service in launcher with health checker
ln.ServicesRunner().Register(
service.New(
service.WithService(New()),
),
)
}
if err := ln.Run(); err != nil {
logger.Fatal(err)
}
type Config struct {
ServiceName string `default:"mx-example" validate:"required"`
Prometheus prometheus.Config
Ops ops.Config
Grpc grpc_transport.Config
}
conf := new(Config)
if err := cfg.Load(conf); err != nil {
logger.Fatalf("could not load configuration: %s", err)
}