Golang

nsq源码(1) nsqlookupd 优雅退出

2019-01-21  本文已影响3人  Linrundong

利用SVC框架启动,当收到退出信号时,先等待任务处理完毕调用Stop方法等待业务处理完毕再退出

启动流程

// nsqlookupd.main()
func main() {
    prg := &program{}
    if err := svc.Run(prg, syscall.SIGINT, syscall.SIGTERM); err != nil {
        log.Fatal(err)
    }
    
    // 初始化
    if err = prg.Init(service); err != nil {
        return err
    }
    
    // 启动业务进程
    // Start()内部会在创建两个监听端口的协程
    err := prg.Start()
    if err != nil {
        return err
    }
    
    // 阻塞等待退出信号
    signalChan := make(chan os.Signal, 1)
    svg.signalNotify(signalChan, ws.signals...)
    <-signalChan
    
    // 退出
    err = prg.Stop()
}

使用sync.WaitGroup加锁开启协程

type WaitGroupWrapper struct {
    sync.WaitGroup
}

func (w *WaitGroupWrapper) Wrap(cb func()) {
    w.Add(1)
    go func() {
        cb()
        w.Done()
    }()
}

Main线程

graph TD
A[Init] --> B[读取配置]
subgraph Start
B --> C[创建TCP监听goroutine]
C --> D[创建HTTP监听goroutine]
end
D -- 阻塞读取signalChan --> Stop

优雅退出

func (p *program) Stop() error {
    if l.tcpListener != nil {
        l.tcpListener.Close()
    }

    if l.httpListener != nil {
        l.httpListener.Close()
    }
    l.waitGroup.Wait()
}

上一篇 下一篇

猜你喜欢

热点阅读