// Code generated by go-omni project. DO NOT EDIT. package main import ( "context" "errors" "example.com/program/internal/config" program "example.com/program/internal/run" "example.com/program/internal/svc" "flag" "fmt" "git.yuntuo.hk/k2safe/go-omni/lifecycle" "git.yuntuo.hk/k2safe/go-omni/logx" "log" "os" "os/signal" "syscall" ) func main() { path := flag.String("config", "etc/config.yaml", "configuration file; empty uses Default()") check := flag.Bool("check-config", false, "validate configuration without initializing dependencies") flag.Parse() if *check { if _, err := config.Load(*path); err != nil { log.Fatal(err) } return } ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() if err := run(ctx, *path); err != nil { log.Fatal(err) } } func run(ctx context.Context, path string) (runErr error) { cfg, err := config.Load(path) if err != nil { return err } logger, err := logx.New(cfg.Log) if err != nil { return err } var deps *svc.ServiceContext defer func() { if p := recover(); p != nil { runErr = fmt.Errorf("program initialization panic: %v", p) } if deps != nil { runErr = deps.Finish(runErr) } // Unjoined work may still use its dependencies and logger. The process exits // unsuccessfully; resource retention never means the work completed. if !errors.Is(runErr, lifecycle.ErrResourcesRetained) { runErr = errors.Join(runErr, logger.Close()) } }() deps, err = svc.New(ctx, logger, cfg) if err != nil { return err } if deps.Context().Err() != nil { return nil } done := make(chan struct{}) // This reserved drain proves Run has actually returned, including its defers. // Runtime bounds the wait even when Run ignores cancellation. deps.OnDrain("go-omni/project/run", func(context.Context) error { <-done; return nil }) logger.InfoContext(deps.Context(), "program.starting") go func() { var result error returned := false defer func() { if p := recover(); p != nil { result = fmt.Errorf("program run panic: %v", p) } else if !returned { result = errors.New("program run exited without returning") } deps.RequestShutdown(result) close(done) }() result = program.Run(deps.Context(), deps) returned = true }() <-deps.Context().Done() return nil }