package main import ( "fmt" "os" "os/signal" "sort" "strings" "syscall" ads "bsm/full/module/base/ads/cmd/main" cloud "bsm/full/module/base/cloud/cmd/main" cms "bsm/full/module/base/cms/cmd/main" feedback "bsm/full/module/base/feedback/cmd/main" fts "bsm/full/module/base/fts/cmd/main" initial "bsm/full/module/base/initial/cmd/main" logs "bsm/full/module/base/logs/cmd/main" mgt "bsm/full/module/base/mgt/cmd/main" passport "bsm/full/module/base/passport/cmd/main" sender "bsm/full/module/base/sender/cmd/main" address "bsm/full/module/ec/address/cmd/main" delivery "bsm/full/module/ec/delivery/cmd" mall "bsm/full/module/ec/mall/cmd/main" market "bsm/full/module/ec/market/cmd/main" order "bsm/full/module/ec/order/cmd/main" wallet "bsm/full/module/finance/wallet/cmd/main" ) type component struct { name string run func() } var components = []component{ {"ads", ads.Run}, {"cloud", cloud.Run}, {"cms", cms.Run}, {"feedback", feedback.Run}, {"fts", fts.Run}, {"initial", initial.Run}, {"logs", logs.Run}, {"mgt", mgt.Run}, {"passport", passport.Run}, {"sender", sender.Run}, {"address", address.Run}, {"delivery", delivery.Run}, {"mall", mall.Run}, {"market", market.Run}, {"order", order.Run}, {"wallet", wallet.Run}, } func main() { selected, err := selectComponents(os.Getenv("BSM_SERVICES")) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(2) } failures := make(chan error, len(selected)) for _, item := range selected { item := item go func() { defer func() { if value := recover(); value != nil { failures <- fmt.Errorf("component %s panicked: %v", item.name, value) } }() fmt.Printf("starting component %s\n", item.name) item.run() failures <- fmt.Errorf("component %s stopped unexpectedly", item.name) }() } stop := make(chan os.Signal, 1) signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) select { case sig := <-stop: fmt.Printf("received %s, stopping monolith\n", sig) case err := <-failures: fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func selectComponents(raw string) ([]component, error) { if strings.TrimSpace(raw) == "" || strings.EqualFold(strings.TrimSpace(raw), "all") { return components, nil } wanted := make(map[string]struct{}) for _, name := range strings.Split(raw, ",") { name = strings.ToLower(strings.TrimSpace(name)) if name != "" { wanted[name] = struct{}{} } } selected := make([]component, 0, len(wanted)) for _, item := range components { if _, ok := wanted[item.name]; ok { selected = append(selected, item) delete(wanted, item.name) } } if len(wanted) != 0 { unknown := make([]string, 0, len(wanted)) for name := range wanted { unknown = append(unknown, name) } sort.Strings(unknown) return nil, fmt.Errorf("unknown BSM_SERVICES: %s", strings.Join(unknown, ", ")) } if len(selected) == 0 { return nil, fmt.Errorf("BSM_SERVICES did not select any component") } return selected, nil }