教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 sync.WaitGroup chan 组合并发控制

sync.WaitGroup chan 组合并发控制

发布时间:2021-04-16   编辑:jiaochengji.com
教程集为您提供sync.WaitGroup chan 组合并发控制等资源,欢迎您收藏本站,我们将为您提供最新的sync.WaitGroup chan 组合并发控制资源
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
	}
}

 

到此这篇关于“sync.WaitGroup chan 组合并发控制”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
sync.WaitGroup chan 组合并发控制
Go语言并发模型:以并行处理MD5为例
Go并发模式:管道和取消
Go语言基础(3)
2020-10-19Go语言goroutine和channel
golang 常见面试基础(1)
如何在golang中关闭bufio.reader_golang 并发编程
22Go常见的并发模式和并发模型
golang同步机制之通道
Golang并发编程中控制主goroutine退出实现的例子

[关闭]
~ ~