#### sync.WaitGroup + chan 组合并发控制 ####

8 篇文章 0 订阅
func (s *WordLibService) CheckWordLib(ctx context.Context, wls []*message.WordLib) error {
	sw := sync.WaitGroup{}
	checkResChan := make(chan error, 50)
	waitGroupChan := make(chan struct{}, 1)

	// 检查词组上限
	sw.Add(1)
	go func() {
		if len(wls) > 1000 {
			checkResChan <- &common.InternalError{
				HttpCode: http.StatusOK,
				ErrCode:  common.RequestError,
				ErrMsg:   "表格词组上限为1000个,请修改后重新上传",
			}
		}

		sw.Done()
	}()

	// 检查词组名长度 超过20个【字母、数字、汉字、标点、空格】
	sw.Add(1)
	go func() {
		arrForGroupName := make([]string, 0)
		for _, wl := range wls {
			if common.CountString(wl.Name) > 20 {
				arrForGroupName = append(arrForGroupName, wl.Name)
			}
		}
		if len(arrForGroupName) != 0 {
			if len(arrForGroupName) <= 10 {
				checkResChan <- &common.InternalError{
					HttpCode: http.StatusOK,
					ErrCode:  common.RequestError,
					ErrMsg:   fmt.Sprintf("%v分组的分组名称超过20个字符,请修改后重新上传", arrForGroupName),
				}
			} else {
				checkResChan <- &common.InternalError{
					HttpCode: http.StatusOK,
					ErrCode:  common.RequestError,
					ErrMsg:   fmt.Sprintf("%v等%v个分组的分组名称超过20个字符,请修改后重新上传", arrForGroupName[:10], len(arrForGroupName)),
				}
			}
		}

		sw.Done()
	}()

	// 检查词组名重复
	sw.Add(1)
	go func() {
		wlDupMap := make(map[string]bool, 0)
		wlDupArrMap := make(map[string]bool, 0)
		wlDupArr := make([]string, 0)
		for _, wl := range wls {
			if _, ok := wlDupMap[wl.Name]; !ok {
				wlDupMap[wl.Name] = true
			} else {
				if _, wlDupArrMapOK := wlDupArrMap[wl.Name]; !wlDupArrMapOK {
					wlDupArrMap[wl.Name] = true
					wlDupArr = append(wlDupArr, wl.Name)
				}
			}
		}
		if len(wlDupArr) != 0 {
			if len(wlDupArr) <= 10 {
				checkResChan <- &common.InternalError{
					HttpCode: http.StatusOK,
					ErrCode:  common.RequestError,
					ErrMsg:   fmt.Sprintf("%v分组存在重复分组,请修改后重新上传", wlDupArr),
				}
			} else {
				checkResChan <- &common.InternalError{
					HttpCode: http.StatusOK,
					ErrCode:  common.RequestError,
					ErrMsg:   fmt.Sprintf("%v等%v个分组存在重复分组,请修改后重新上传", wlDupArr[:10], len(wlDupArr)),
				}
			}
		}

		sw.Done()
	}()

	// 检查词条名重复
	sw.Add(1)
	go func() {
		wlItemDupMap := make(map[string]bool, 0)
		wlItemDupArrMap := make(map[string]bool, 0)
		wlItemDupArr := make([]string, 0)
		for _, wl := range wls {
			for _, wItem := range wl.Words {
				if _, ok := wlItemDupMap[wItem]; !ok {
					wlItemDupMap[wItem] = true
				} else {
					if _, wlItemDupArrMapOK := wlItemDupArrMap[wl.Name]; !wlItemDupArrMapOK {
						wlItemDupArrMap[wl.Name] = true
						wlItemDupArr = append(wlItemDupArr, wl.Name)
					}
				}
			}
		}
		if len(wlItemDupArr) != 0 {
			if len(wlItemDupArr) <= 10 {
				checkResChan <- &common.InternalError{
					HttpCode: http.StatusOK,
					ErrCode:  common.RequestError,
					ErrMsg:   fmt.Sprintf("%v分组内存在重复词条,请修改后重新上传", wlItemDupArr),
				}
			} else {
				checkResChan <- &common.InternalError{
					HttpCode: http.StatusOK,
					ErrCode:  common.RequestError,
					ErrMsg:   fmt.Sprintf("%v等%v个分组内存在重复词条,请修改后重新上传", wlItemDupArr[:10], len(wlItemDupArr)),
				}
			}
		}

		sw.Done()
	}()

	// 检查词条数量、词条长度
	sw.Add(1)
	go func() {
		wordsLenMinErrDetails := make([]string, 0)
		wordsLenMaxErrDetails := make([]string, 0)
		wordsItemLenErrDetails := make([]string, 0)
		var wordsLenMinErrFlag, wordsLenMaxErrFlag, wordsItemLenErrFlag bool
		for _, wl := range wls {
			// 字段检验 词条数量至少1个
			if len(wl.Words) < 1 {
				wordsLenMinErrDetails = append(wordsLenMinErrDetails, wl.Name)
				wordsLenMinErrFlag = true
			}
			if !wordsLenMinErrFlag {
				// 字段检验 词条数量超出
				if len(wl.Words) > 100 {
					wordsLenMaxErrDetails = append(wordsLenMaxErrDetails, wl.Name)
					wordsLenMaxErrFlag = true
				}
				if !wordsLenMaxErrFlag {
					// 字段检验 词条超过30个【字母、数字、汉字、标点、空格】
					for _, w := range wl.Words {
						if common.CountString(w) > 30 {
							wordsItemLenErrDetails = append(wordsItemLenErrDetails, w)
							wordsItemLenErrFlag = true
						}
					}
				}
			}
		}
		if wordsLenMinErrFlag {
			checkResChan <- &common.InternalError{
				HttpCode: http.StatusOK,
				ErrCode:  common.RequestError,
				ErrMsg: func() string {
					var outMinFlag bool
					var msgBuf bytes.Buffer
					for i, v := range wordsLenMinErrDetails {
						if i > 10 {
							outMinFlag = true
							break
						}
						msgBuf.WriteString(fmt.Sprintf("%v, ", v))
					}
					if msgBuf.Len() > 1 {
						msgBuf.Truncate(msgBuf.Len() - 2)
					}
					if !outMinFlag {
						return fmt.Sprintf("%v分组中词条数量不足1个,请修改后重新上传", msgBuf.String())
					} else {
						return fmt.Sprintf("%v等%v个分组中词条数量不足1个,请修改后重新上传", msgBuf.String(), len(wordsLenMinErrDetails))
					}
				}(),
			}
		}
		if wordsLenMaxErrFlag {
			checkResChan <- &common.InternalError{
				HttpCode: http.StatusOK,
				ErrCode:  common.RequestError,
				ErrMsg: func() string {
					var outMaxFlag bool
					var msgBuf bytes.Buffer
					for i, v := range wordsLenMaxErrDetails {
						if i > 10 {
							outMaxFlag = true
							break
						}
						msgBuf.WriteString(fmt.Sprintf("%v, ", v))
					}
					if msgBuf.Len() > 1 {
						msgBuf.Truncate(msgBuf.Len() - 2)
					}
					if !outMaxFlag {
						return fmt.Sprintf("%v分组中词条数量超过100个,请修改后重新上传", msgBuf.String())
					} else {
						return fmt.Sprintf("%v等%v个分组中词条数量超过100个,请修改后重新上传", msgBuf.String(), len(wordsLenMaxErrDetails))
					}
				}(),
			}
		}
		if wordsItemLenErrFlag {
			checkResChan <- &common.InternalError{
				HttpCode: http.StatusOK,
				ErrCode:  common.RequestError,
				ErrMsg: func() string {
					var outMaxFlag bool
					var msgBuf bytes.Buffer
					for i, v := range wordsItemLenErrDetails {
						if i > 10 {
							outMaxFlag = true
							break
						}
						msgBuf.WriteString(fmt.Sprintf("%v, ", v))
					}
					if msgBuf.Len() > 1 {
						msgBuf.Truncate(msgBuf.Len() - 2)
					}
					if !outMaxFlag {
						return fmt.Sprintf("%v词条超过30个字符,请修改后重新上传", msgBuf.String())
					} else {
						return fmt.Sprintf("%v等%v个词条超过30个字符,请修改后重新上传", msgBuf.String(), len(wordsItemLenErrDetails))
					}
				}(),
			}
		}

		sw.Done()
	}()

	go func() {
		sw.Wait()
		waitGroupChan <- struct{}{}
	}()

	select {
	case <-ctx.Done():
		logger.GetLogger().Errorf("[service] CheckWordLib cancelled")
		return nil
	case <-time.After(5 * time.Second):
		logger.GetLogger().Errorf("[service] CheckWordLib timeout")
		return &common.InternalError{
			HttpCode: http.StatusOK,
			ErrCode:  common.RequestError,
			ErrMsg:   "单次上传词组过多,请拆分后重新上传",
		}
	case checkRes := <-checkResChan:
		return checkRes
	case <-waitGroupChan:
		return nil
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值