// Do 执行子组件
// ctx 业务上下文
// currentConponent 当前组件
// wg 父组件的waitgroup对象
func (bc *BaseConcurrencyComponent) Do(ctx *Context, currentConponent Component, wg *sync.WaitGroup) (err error) {
defer wg.Done()
// 初始化并发子组件channel
if bc.logicResChan == nil {
bc.logicResChan = make(chan interface{}, 1)
}
go currentConponent.BusinessLogicDo(bc.logicResChan)
select {
// 等待业务执行结果
case <-bc.logicResChan:
// 业务执行结果
fmt.Println(runFuncName(), "bc.BusinessLogicDo wait.done...")
break
// 超时等待
case <-ctx.TimeoutCtx.Done():
// 超时退出
fmt.Println(runFuncName(), "bc.BusinessLogicDo timeout...")
bc.Err = ErrConcurrencyComponentTimeout
break
}
// 执行子组件
err = currentConponent.ChildsDo(ctx)
return
}
这个组件的并发设计中,子任务的执行是同时起生产者和消费者的,在消费者超时退出后,生产者(urrentConponent.BusinessLogicDo(bc.logicResChan))如果此时才获取到结果发送到消费者将会阻塞,这样会造成多go程阻塞,go程积压造成内存爆表。
我模仿写了一个伪代码:
func run(wg *sync.WaitGroup) {
defer wg.Done()
ch := make(chan string)
wg.Add(1)
go func() {
time.Sleep(9 * time.Second)
// 阻塞后死锁
ch <- "work1"
}()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
select {
case res := <-ch:
fmt.Println("接收到任务", res)
case <-ctx.Done():
fmt.Println("ctx err : ", ctx.Err())
return
}
}
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go run(&wg)
wg.Wait()
}
运行结果是go程阻塞死锁 :
ctx err : context deadline exceeded
fatal error: all goroutines are asleep - deadlock!
// Do 执行子组件
// ctx 业务上下文
// currentConponent 当前组件
// wg 父组件的waitgroup对象
func (bc *BaseConcurrencyComponent) Do(ctx *Context, currentConponent Component, wg *sync.WaitGroup) (err error) {
defer wg.Done()
// 初始化并发子组件channel
if bc.logicResChan == nil {
bc.logicResChan = make(chan interface{}, 1)
}
}
这个组件的并发设计中,子任务的执行是同时起生产者和消费者的,在消费者超时退出后,生产者(urrentConponent.BusinessLogicDo(bc.logicResChan))如果此时才获取到结果发送到消费者将会阻塞,这样会造成多go程阻塞,go程积压造成内存爆表。
我模仿写了一个伪代码:
func run(wg *sync.WaitGroup) {
defer wg.Done()
ch := make(chan string)
}
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go run(&wg)
wg.Wait()
}
运行结果是go程阻塞死锁 :
ctx err : context deadline exceeded
fatal error: all goroutines are asleep - deadlock!