使用golang实现任务池

使用golang实现任务池

为了减少服务请求过于频繁,使用打包的方式进行数据处理. 并约束服务的时效在规定的范围中,避免数据失效

一.思路分析

1.为了不降低三方请求响应, 设计一个专门接受请求的缓冲池,将用户请求的数据直接放入缓冲池中
2.启用单独的任务分发进程,负责时刻监听请求数据以及定时维护过期请求数据
3.启用单独的过期数据处理进程,对过期数据单独进行处理
4.启用打包处理进程,将数据按照设定打包

二.程序实现

程序使用golang进行开发设计
使用毫秒的处理时间

package pool

import (
	"errors"
	"fmt"
	"time"
)

type PoolHandler struct {
	MaxMillSecond int64 // 最大执行毫秒数
	TaskMax int // 最大任务数
	PoolData *TaskListData // 缓存池数据
	PackData chan []*TaskData // 打包数据
	OverdueData chan []*TaskData // 过期数据
	EarliestExpTime int64 // 最早过期时间
	Lock chan bool // 分发操作锁
	TmpData []*TaskData
}

// 任务列表数据
type TaskListData struct {
	Data []*TaskData
}

type TaskData struct {
	StartTime int64 // 开始时间 毫秒
	Name string
	Sex int
}

// 实例化处理器
func NewPoolHandler(maxMillSecond int64, taskMax int) *PoolHandler {
	obj := &PoolHandler{
		MaxMillSecond: maxMillSecond,
		TaskMax: taskMax,
		PoolData: &TaskListData{},
		PackData: make(chan []*TaskData),
		OverdueData: make(chan []*TaskData),
		Lock: make(chan bool),
	}
	// 任务分化器
	go obj.DispatcherTask()
	// 超时处理
	go obj.OverTaskHandle()
	// 打包处理
	go obj.PackTaskHandle()
	return obj
}

// 任务生成器
func (s *PoolHandler) CreateTask(task *TaskData) (err error) {
	if s == nil {
		return errors.New("没有实例化对象")
	}
	task.StartTime = time.Now().UnixNano() / 1e6
	s.TmpData = append(s.TmpData, task)
	s.PoolData.Data = append(s.PoolData.Data,s.TmpData...)
	s.TmpData = nil
	s.Lock <- true
	return
}

// 任务分发器
func (s *PoolHandler) DispatcherTask() {
	// 定时检查数据是否过期
	go func() {
		timer := time.NewTicker(time.Millisecond * time.Duration(s.MaxMillSecond))
		defer timer.Stop()
		for range timer.C {
			s.Lock <- true
		}
	}()
	// 新数据来时 进行数据处理
	go s.HandleData()
}

// 数据解析
func (s *PoolHandler) HandleData() {
	for range s.Lock {
		// 当前读取数据量
		poolData := s.PoolData.Data
		l := len(poolData)
		// 如果没有数据 直接返回
		if l < 1 {
			continue
		}
		// 记录早过期时间
		if s.EarliestExpTime < 1 {
			s.EarliestExpTime = poolData[0].StartTime
		}
		// 获取当前毫秒
		tNow := time.Now().UnixNano() / 1e6
		// 过期任务存储
		overdueData := make([]*TaskData, 0)
		// 未过期的任务
		packData := make([]*TaskData, 0)
		// 记录最早的创建任务的时间
		for i := 0; i < l; i++ {
			task := poolData[i]
			if tNow - s.MaxMillSecond >= s.EarliestExpTime &&  tNow - task.StartTime > s.MaxMillSecond {
				overdueData = append(overdueData, task)
				continue
			}
			packData = append(packData, task)
		}
		// 分发过期任务
		overLen := len(overdueData)
		if overLen > 0 {
			s.OverdueData <- overdueData
			// 删除已处理的过期信息
			s.PoolData.Data = append(s.PoolData.Data[overLen:])
		}
		// 分发未过期的任务
		currLen := len(packData)
		// 记录最早过期时间
		if currLen > 1 {
			s.EarliestExpTime = packData[0].StartTime
		}
		// 如果处理数据不足 则不进行处理
		if currLen < s.TaskMax {
			continue
		}
		// 任务打包
		if currLen >= s.TaskMax {
			currI := currLen / s.TaskMax
			for i := 0; i < currI; i++ {
				pos := i*s.TaskMax
				s.PackData <- packData[pos:pos+s.TaskMax]
				// 删除已处理的信息
				s.PoolData.Data = append(s.PoolData.Data[s.TaskMax:])
			}
		}
	}
}

// 过期数据处理
func (s *PoolHandler) OverTaskHandle()  {
	for data := range s.OverdueData {
		for _,v := range data {
			fmt.Println("OverTaskHandle:",v.Name)
		}
	}
}

// 未过期打包数据处理
func (s *PoolHandler) PackTaskHandle() {
		for data := range s.PackData {
			for _,v := range data {
				fmt.Println("PackTaskHandle:",v.Name)
			}
		}
}
三.使用方法

建议开启全局参数,保存实例化, 因为内部存在go的协程

	obj := pool.NewPoolHandler(5000, 5)
	for i := 0; i < 10; i++ {
		req := &pool.TaskData{
			Name: "你" + strconv.Itoa(i),
			Sex: 2+i,
		}
		obj.CreateTask(req)
		time.Sleep(time.Second*2)
	}
	for i := 10; i < 27; i++ {
		req := &pool.TaskData{
			Name: "你" + strconv.Itoa(i),
			Sex: 2+i,
		}
		obj.CreateTask(req)
	}
四.输出结果
OverTaskHandle:0
OverTaskHandle:1
OverTaskHandle:2
OverTaskHandle:3
OverTaskHandle:4
OverTaskHandle:5
OverTaskHandle:6
OverTaskHandle:7
PackTaskHandle:8
PackTaskHandle:9
PackTaskHandle:10
PackTaskHandle:11
PackTaskHandle:12
PackTaskHandle:13
PackTaskHandle:14
PackTaskHandle:15
PackTaskHandle:16
PackTaskHandle:17
PackTaskHandle:18
PackTaskHandle:19
PackTaskHandle:20
PackTaskHandle:21
PackTaskHandle:22
OverTaskHandle:23
OverTaskHandle:24
OverTaskHandle:25
OverTaskHandle:26
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值