func()

in pkg/boot/module.go [65:124]


func (m *ModuleStarter) Run(ctx context.Context, startUpSuccessCallback func(*module.Manager)) error {
	// resolve module dependencies
	if err := m.ResolveDependency(); err != nil {
		return err
	}

	if len(m.orderedModules) == 0 {
		return fmt.Errorf("no module is active")
	}

	shutdownChannel := make(chan error)
	m.moduleManager = module.NewManager(m.orderedModules, func(err error) {
		shutdownChannel <- err
	})

	// startup modules
	defer m.shutdownModules(ctx)
	for _, module := range m.orderedModules {
		moduleName := module.Name()
		// start module
		log.Debugf("starting module %s", moduleName)
		if err := module.Start(ctx, m.moduleManager); err != nil {
			return fmt.Errorf("start module %s failure: %v", moduleName, err)
		}

		log.Infof("module %s start successful", moduleName)

		// append to started modules
		m.startedModules = append(m.startedModules, module)
	}

	// notify all modules setup success
	for _, mod := range m.startedModules {
		mod.NotifyStartSuccess()
	}
	if startUpSuccessCallback != nil {
		startUpSuccessCallback(m.moduleManager)
	}

	// register terminal
	signals := make(chan os.Signal, 1)
	signal.Notify(signals, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		select {
		case <-signals:
			log.Infof("detect shutdown signal")
			break
		case <-ctx.Done():
			log.Infof("detect background context have been down, error by: %v", ctx.Err())
			break
		case err := <-shutdownChannel:
			log.Warnf("detect module shutdown notify: %v", err)
		}
		wg.Done()
	}()
	wg.Wait()
	return nil
}