AlexStocks commented on issue #3042:
URL: https://github.com/apache/dubbo-go/issues/3042#issuecomment-3352363385

   你这段代码的最后一行:
   
   ```go
   select {}
   ```
   
   的确是一个 **阻塞主 goroutine** 的“土办法”。它会让当前 goroutine 永远卡住,CPU 占用很低,但从工程角度看有几个问题:
   
   1. **可读性差** —— 别人看代码会疑惑:为什么这里空的 `select {}`?
   2. **不可控** —— 没有退出机制,服务关闭或收到信号时无法优雅退出。
   3. **不利于维护** —— 很难扩展,比如需要监听系统信号、控制 shutdown 时,得另写一套逻辑。
   
   ---
   
   ### 常见的改进方式
   
   #### 1. 使用 `context` 控制生命周期(推荐)
   
   ```go
   ctx, cancel := context.WithCancel(context.Background())
   defer cancel()
   
   // 监听信号,优雅退出
   go func() {
       sigCh := make(chan os.Signal, 1)
       signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
       <-sigCh
       cancel()
   }()
   
   <-ctx.Done()
   return nil
   ```
   
   这样,服务会在收到中断信号时自动退出。
   
   ---
   
   #### 2. 使用 `sync.WaitGroup` 等待后台 goroutine
   
   如果 `exportServices()` / `RegisterServiceInstance()` 启动了 goroutine,可以用 
`sync.WaitGroup` 来等待它们完成,而不是简单 `select {}`:
   
   ```go
   var wg sync.WaitGroup
   wg.Add(1)
   
   go func() {
       defer wg.Done()
       // 运行你的服务逻辑
   }()
   
   wg.Wait()
   ```
   
   ---
   
   #### 3. 明确暴露 `Serve` 的退出通道
   
   你可以在 `Server` 结构里定义一个退出通道,让 `Serve` 阻塞在这里,外部可控:
   
   ```go
   type Server struct {
       stop chan struct{}
   }
   
   func (s *Server) Serve() error {
       s.stop = make(chan struct{})
       // ... init & export
   
       <-s.stop
       return nil
   }
   
   func (s *Server) Stop() {
       close(s.stop)
   }
   ```
   
   ---
   
   ✅ 总结:
   `select {}` 虽然能用,但不够优雅。更好的做法是结合 `context` 或退出通道,让 `Serve()` 可以 **优雅退出**。
   
   要不要我帮你改写一份 **优雅退出的 Serve() 版本**,带 `context` + 信号处理?
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to