AFAIRE
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
4.8 KiB

/*
------------------------------------------------------------------------------------------------------------------------
####### minikit ####### Copyright (c) 2021 losyme ################################################## MIT License #######
------------------------------------------------------------------------------------------------------------------------
*/
package minikit
import (
"forge.chapril.org/losyme/errors"
"forge.chapril.org/losyme/kong/router"
"forge.chapril.org/losyme/util"
"forge.chapril.org/losyme/minikit/internal/cmdline"
"forge.chapril.org/losyme/minikit/internal/config"
"forge.chapril.org/losyme/minikit/internal/crypto"
"forge.chapril.org/losyme/minikit/internal/factory"
"forge.chapril.org/losyme/minikit/internal/logger"
"forge.chapril.org/losyme/minikit/internal/scheduler"
"forge.chapril.org/losyme/minikit/internal/server"
"forge.chapril.org/losyme/minikit/pkg/components"
)
type Kit struct {
factory *factory.Factory
Components *components.Components
}
func New(cfg *Config) *Kit {
cs := &components.Components{Application: cfg.Application}
kit := &Kit{
factory: factory.New(),
Components: cs,
}
for _, component := range cfg.Components {
switch component {
case "cmdline":
kit.AddComponent(
component,
func() error {
_, err := cmdline.Build(cs, cfg.CmdLineInit, cfg.CmdLineArgs)
if err != nil {
return errors.WithMessage(err, "minikit/cmdline") //////////////////////////////////////////////
}
return nil
},
)
case "config":
kit.AddComponent(
component,
func() error {
c, err := config.Build(cs, cfg.ConfigInit)
if err != nil {
return errors.WithMessage(err, "minikit/config") ///////////////////////////////////////////////
}
cs.Config = c
return nil
},
)
case "crypto":
kit.AddComponent(
component,
func() error {
c, err := crypto.Build(cs)
if err != nil {
return errors.WithMessage(err, "minikit/crypto") ///////////////////////////////////////////////
}
cs.Crypto = c
return nil
},
)
case "logger":
kit.AddComponent(
component,
func() error {
c, err := logger.Build(cs)
if err != nil {
return errors.WithMessage(err, "minikit/logger") ///////////////////////////////////////////////
}
cs.Logger = c
return nil
},
"config",
)
case "router":
kit.AddComponent(
component,
func() error {
cs.Router = router.New()
return nil
},
)
case "scheduler":
kit.AddComponent(
component,
func() error {
c, err := scheduler.Build(cs, cfg.SchedulerCb)
if err != nil {
return errors.WithMessage(err, "minikit/scheduler") ////////////////////////////////////////////
}
cs.Scheduler = c
return nil
},
"config",
)
case "server":
kit.AddComponent(
component,
func() error {
c, err := server.Build(cs)
if err != nil {
return errors.WithMessage(err, "minikit/server") ///////////////////////////////////////////////
}
cs.Server = c
return nil
},
"config", "logger", "router",
)
}
}
return kit
}
func (k *Kit) AddComponent(name string, builder func() error, dependancies ...string) {
if dependancies == nil && name != "cmdline" {
// Création d'une fausse dépendance envers "cmdline"
// pour être sûr que celui-ci soit le premier à être construit.
dependancies = []string{"cmdline"}
}
k.factory.AddComponent(name, builder, dependancies...)
}
func (k *Kit) Build() error {
if k.Components.Application == nil {
return errors.New("[minikit] application component cannot be nil") /////////////////////////////////////////////
}
return k.factory.BuildComponents()
}
func (k *Kit) run(fn func() error) error {
if err := k.Build(); err != nil {
return err
}
return fn()
}
func (k *Kit) Run(fn func() error) error {
err := k.run(fn)
if logger := k.Components.Logger; logger != nil {
if err != nil {
logger.Fatal("RUN", "error", err) //////////////////////////////////////////////////////////////////////////
}
logger.Close()
}
return k.Components.Application.OnError(err)
}
func (k *Kit) RunServer(build func() error, atEnd func()) error {
return k.Run(
func() error {
if build != nil {
if err := build(); err != nil {
return err
}
}
server := k.Components.Server
group, endCh := util.WaitAppEnd(
func() {
if atEnd != nil {
atEnd()
}
ctx, cancel := util.CtxWithTimeout(10)
defer cancel()
_ = server.Shutdown(ctx) // AFINIR?
},
)
err := server.ListenAndServe()
close(endCh)
group.Wait()
return err
},
)
}
/*
######################################################################################################## @(°_°)@ #######
*/