// 推送绩效考核评价消息
func sendPerformanceMsg() {
// 测试环境不执行
if runEnvironment == 20 {
return
}
defer func() {
if err := recover(); err != nil {
sbjlog.ExcLog("60", "sendPerformanceMsg Err:%v\n", err)
}
}()
var err error
sbjlog.Printf("Start 每天早上10点给未填写评价的用户推送评价提醒消息")
var allPersonalAssessList []map[string]interface{} //待同步的数据
var tempList *[]map[string]interface{}
pageIndex, pageSize := 1, 100
sqlWhere := " "
for {
tempList, err = sqlGetAllPagePersonalAssessList(pageIndex, pageSize, sqlWhere) //查询待评价的绩效考核数据
if err != nil {
return
}
allPersonalAssessList = append(allPersonalAssessList, *tempList...) //赋值
if len(*tempList) < pageSize { //查询得到的数据小于100条,说明是最后一页
//跳出循环
break
}
pageIndex++
}
allPersonalAssessListTotal := len(allPersonalAssessList)
sbjlog.Printf("开始 每天早上10点 给未填写评价的用户推送评价提醒消息,一共要同步的数据是 %d 条 ", allPersonalAssessListTotal)
// 获取当前时间戳
tBegin := xtools.GetCurrentMillisecondInt64()
// 计算读取耗时
readUseTimeMs := xtools.GetUseTimeToMillisecondInt64(tBegin)
// 计算线程数量 | 计划每个线程处理 20 个数据,最小 5 个线程,最大 15 个线程
threadNum := CountDealThreadNum(allPersonalAssessListTotal, 20, 5, 15)
// 打印日志
sbjlog.Printf(" sendPerformanceMsg:需要推送 %d 个数据,计划开启 %d 个处理线程,读取耗时 %d ms", allPersonalAssessListTotal, threadNum, readUseTimeMs)
// 检查读取耗时,如果超过 2 秒,推送 debug 给程序负责人、紧急联系人
if readUseTimeMs > 2000 {
sbjlog.SendDebug("sendPerformanceMsg,读取耗时: %d ms", readUseTimeMs)
}
// 获取当前时间戳
tBegin = xtools.GetCurrentMillisecondInt64()
//初始化一个处理结果通道
resultChan := make(chan struct{}, threadNum)
//当前处理的索引位置
indexChan := make(chan int, 1)
indexChan <- 0 //从第一条开始
// 定时器 获取数据,放入通道
for i := 0; i < threadNum; i++ {
// 开启一个线程
go func() {
var index int //当前索引位置
var tempData map[string]interface{}
for {
index = <-indexChan
if index >= allPersonalAssessListTotal {
indexChan <- index //通知其他异步结束
return
}
tempData = allPersonalAssessList[index]
index++
//放回通道 给 下一条线程拿到当前索引
indexChan <- (index)
fmt.Println("处理数据",tempData)
resultChan <- struct{}{} //写入处理结果
}
}()
}
// 收取处理结果
for i := 0; i < allPersonalAssessListTotal; i++ {
<-resultChan
}
// 打印日志
sbjlog.Printf("sendPerformanceMsg,处理线程 %d 个,处理耗时 %d ms", threadNum, xtools.GetUseTimeToMillisecondInt64(tBegin))
sbjlog.Printf("End 每天早上10点给未填写评价的用户推送评价提醒消息")
}
// 计算处理线程数量 | dataLen 数据长度, dealLen 单个线程处理长度, minLen 最小线程数, maxLen 最大线程数
func CountDealThreadNum(dataLen, dealLen, minLen, maxLen int) int {
// 计划线程数
planThreadNum := (dataLen + dealLen - 1) / dealLen
// 判断是否在范围内
switch {
case planThreadNum > maxLen: // 计划 超出 最大长度限制
// 返回最大线程数
return maxLen
case planThreadNum < minLen: // 计划 小于 最小长度限制
if dataLen < minLen { // 数据长度 小于 最小长度限制
// 返回数据长度
return dataLen
}
// 返回最小线程数
return minLen
default:
// 返回计划线程数
return planThreadNum
}
}