Golang Woker池和Job队列模板

Golang Worker池Job队列

这个模板是考虑用作字段校验的,之前是通过维护两个channel woker和result来实现监听的字段校验,但是这种方式是需要先全部校验完才能去遍历结果,而且我这里还需要根据数据的总长度来申请channel的缓存大小,这个方式非常不好,所以后续更改为这个模板通过控制Goroutine复用来限制并行的数量。后续还考虑过将所有的接口的封装成这种形式,但是这样无疑会降低接口的并发量,和同事讨论觉得这种形式还是存在一些业务场景的。

package Plug

import (
	"fmt"
	"gorm.io/gorm"
	"strings"
	"sync"
)
// Job接口  Do表示业务逻辑,所有实现Do()方法的结构体都可以当作一个Job类型
type Job interface {
	Do()
}


type JobChan chan Job

type  WorkerChan chan JobChan

var (
	// 全局的Job队列
	JobQueue   JobChan

	// 全局的Worker池
	WorkerPool WorkerChan

	// 全局任务分发器
	Dis      Dispatcher
)
// Worker
type Worker struct {
	JobChannel JobChan
	quit chan bool
}
// 分发器
type  Dispatcher struct {
	Workers   []*Worker
	quit chan bool
}

var MaxWorkerPoolSize = 5

// 初始化模板
func init()(){
	// Job队列长度为10
	JobQueue = make(JobChan,10)
	// Worker Pool的容量为MaxWorkerPoolSize
	WorkerPool = make(WorkerChan,MaxWorkerPoolSize)
	// 任务分发器
	Dis = Dispatcher{}
	go Dis.Run()
}

// Worker 启动监听
func (w *Worker) Start() {
	go func() {
		for {
			// Worker 放入 WorkerPool中
			WorkerPool <- w.JobChannel
			select {
			// 监听取到任务,并执行业务逻辑
			case job := <-w.JobChannel:
				job.Do()
			case <-w.quit:
				return
			}
		}
	}()
}

func (w Worker) Stop() {
	go func() {
		w.quit <- true
	}()
}

func NewWorker()(*Worker){
	return &Worker{JobChannel: make(JobChan,1)}
}
// 启动分发器
func (d *Dispatcher) Run() {
	// 循环创建一定数量的Worker
	for i := 0; i < MaxWorkerPoolSize; i++ {
		worker := NewWorker()
		d.Workers = append(d.Workers, worker)
		// 启动Worker监听
		worker.Start()
	}
	for {
		select {
		// 从Job队列中取得任务
		case job := <-JobQueue:
			go func(job Job) {
				// 从WorkerPool中取出一个JobChan
				jobChan := <-WorkerPool
				// 把任务放到JobChan中,监听的Worker取到任务会开始Do()
				jobChan <- job
			}(job)
		// stop dispatcher
		case <-d.quit:
			return
		}
	}
}

func (d *Dispatcher) Stop() {
	go func() {
		for i := range d.Workers{
			d.Workers[i].Stop()
		}
		d.quit <- true
	}()
}


type dealRuleJobData struct {
	error   error
	wg 		*sync.WaitGroup
}

func(jd *dealRuleJobData)Do(){

	defer jd.wg.Done()
	
	// 业务逻辑
	
	jd.error = nil
	return

}

这个模板的之前浏览到一篇博客后借鉴的,暂时找不到了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值