并发编程go

package web

import (
	"context"
	"fmt"
	"sync"
	"time"
)

// Hook 是一个钩子函数。注意,
// ctx 是一个有超时机制的 context.Context
// 所以你必须处理超时的问题
type Hook func(ctx context.Context) error

// BuildCloseServerHook 这里其实可以考虑使用 errgroup,
// 但是我们这里不用是希望每个 server 单独关闭
// 互相之间不影响
func BuildCloseServerHook(servers ...Server) Hook {
	return func(ctx context.Context) error {
		// 确保并发任务的同步
		wg := sync.WaitGroup{}
		// 确保所有server的关闭
		doneCh := make(chan struct{})
		// 添加要等待的goroutine个数
		wg.Add(len(servers))

		for _, s := range servers {
			// 我的server都是独立的,所以开协程关闭就行了
			go func(svr Server) {
				err := svr.Shutdown(ctx)
				if err != nil {
					fmt.Printf("server shutdown error: %v \n", err)
				}
				time.Sleep(time.Second)
				// 每关一个server,那么咱就减一
				wg.Done()
			}(s)
		}
		go func() {
			// 阻塞,确保所有协程关闭
			wg.Wait()
			doneCh <- struct{}{}
		}()
		select {
		case <-ctx.Done():
			// 超时
			fmt.Printf("closing servers timeout \n")
			return ErrorHookTimeout
		case <-doneCh:
			// 关闭成功
			fmt.Printf("close all servers \n")
			return nil
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

席万里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值