package goroutine

import (
	"log"
	"sync"
)

// 定义命令接口，所有命令需要实现这个接口
type AsyncCommand interface {
	Execute()
}

// 定义结构体来管理更新排名分数的逻辑
type AsyncCommandInvoke struct {
	wg      sync.WaitGroup
	CmdChan chan AsyncCommand
}

func NewAsyncCommandInvoke(chanSize int) *AsyncCommandInvoke {
	aci := new(AsyncCommandInvoke)
	aci.CmdChan = make(chan AsyncCommand, chanSize)
	return aci
}

// 启动并发执行更新排名分数命令的方法
func (aci *AsyncCommandInvoke) StartExecuting() {
	safeDo := func(cmd AsyncCommand) {
		defer func() {
			if err := recover(); err != nil {
				log.Printf("AsyncCommandInvoke StartExecuting recover error: %v", err)
			}
		}()
		cmd.Execute()
	}

	aci.wg.Add(1)
	go func() {
		defer aci.wg.Done()
		for command := range aci.CmdChan {
			safeDo(command)
		}
	}()
}

// 停止执行更新排名分数命令（通过关闭通道来触发）
func (aci *AsyncCommandInvoke) StopExecuting() {
	close(aci.CmdChan)
	aci.wg.Wait() // 等待所有goroutine完成
}

func (aci *AsyncCommandInvoke) AndCmd(ac AsyncCommand) {
	aci.CmdChan <- ac
}
