实战练习
实现一个协程池
func NewGoroutinePool(ctx context.Context, concurrent int) *GoroutinePool {
newCtx, newCancel := context.WithCancel(ctx)
gp := &GoroutinePool{
ctx: newCtx,
cancel: newCancel,
taskC: make(chan Task, concurrent),
}
for i := 0; i < concurrent; i++ {
go gp.worker()
}
return gp
}
type Task func(ctx context.Context)
type GoroutinePool struct {
ctx context.Context
cancel context.CancelFunc
taskC chan Task
}
func (g *GoroutinePool) worker() {
for {
select {
case <-g.ctx.Done():
return
case task := <-g.taskC:
task(g.ctx)
}
}
}
func (g *GoroutinePool) Close() {
if g.cancel != nil {
g.cancel()
}
}
func (g *GoroutinePool) BlockSubmit(ctx context.Context, task Task) {
select {
case <-g.ctx.Done():
case <-ctx.Done():
case g.taskC <- task:
}
}
实现一个HTTP/DB连接池
考点:设计池化技术时需要注意那些点
- 连接池大小
- 最小空闲连接数
- 连接的空闲超时时间
- 连接的最大生命周期
- 连接的健康检查
- New 方法
- 实现方法:Get、Put