golang Time Scheduler for Game [一款go语言写的粗粒度高性能时间调度器]
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
cmd
.gitignore
.travis.yml
LICENSE
README.md
debug.test
timerCaller.go
timerExecute.go
timerParser.go
timerScheduler.go
timer_test.go

README.md

Go Report Card Build Status


grapeTimer 时间调度器

一款粗粒度的时间调度器,可以帮你通过一些字符串快速并简单的创建时间任务。

用于游戏服务端的优化设计,大量并行的时间调度方式。

目前可支持任意类型的函数(无返回值)以及任意参数数量和参数类型。

grapeTimer填坑完毕的库,已做测试。

简单介绍:

  • 通过命令格式创建time.Time
  • 简洁的Api格式,轻度且可拆分的函数库
  • 快速创建调度器
  • 可控的调度器时间粒度
  • 高性能的并发调度
  • 支持任意类型函数的任意参数[自动推导参数以及类型]
  • 时间周期,次数多模式可控[支持每天、每周、每月]
  • 可以获取下一次执行时间的字符串[支持自定义格式]
  • 可选择对调度器保存或内存执行
  • 生成可保存的调度器字符串并反向分析他生成调度器[保存到Json再通过Json创建Timer]
  • 不依赖第三方库

简单测试

100W个TIMER压入4秒钟,每个执行1S的话,完成执行大概不到4S,基本上达到性能需求。 如果超过100W个并发TIMER,建议切分服务,所有执行采用异步行为。

安装方法

go get -u github.com/koangel/grapeTimer

基本用法

// 初始化一个1秒钟粒度的调度器,ars代表是否自动设置运行为并行模式
grapeTimer.InitGrapeScheduler(1*time.Second, true)
// 启动一个单次执行的调度器,1秒时间,基本tick单位为毫秒
Id := grapeTimer.NewTickerOnce(1000, exec100,"exec100 this arg1",2000,float32(200.5))
// 启动一个单次执行的调度器,1秒时间,基本tick单位为毫秒 (需要返回参数的代码)
Id := grapeTimer.NewTickerOnce(1000, exec100Result,"exec100 this arg1",2000,float32(200.5),func(v float32){
	fmt.Println("i'm call back:", v)
})
// 启动一个1秒为周期的 循环timer 循环100次 -1为永久循环
Id = grapeTimer.NewTickerLoop(1000,100, exec100Loop,"exec100Loop this arg1",2000,float32(200.5))
// 启动一个每日规则的定时器,参数为args data
Id = grapeTimer.NewTimeDataOnce("Day 13:59:59", exeDayTime,"exeDayTime this arg1",2000,float32(200.5))
// 启动一个每日循环规则的定时器,参数为args data 循环100次 -1为永久循环
Id = grapeTimer.NewTimeDataLoop("Day 13:59:59",100, exeDayTime,"exeDayTime this arg1",2000,float32(200.5))
// 通过json启动一个定时器
Id = grapeTimer.NewFromJson(jsonBody,"exec100Loop this arg1",2000,float32(200.5))

函数可以为任意类型的任意参数数量的函数,会自动保存参数以及数值,CALLBACK线程安全:

func exec100(arg1 string, arg2 int, arg3 float32) {
	fmt.Println(arg1, arg2, arg3)
}

// 需要返回参数
func exec100Result(arg1 string, arg2 int, arg3 float32,rscall func(v float32)) {
	fmt.Println(arg1, arg2, arg3)

	rscall(arg3)
}


func exec100Loop(arg1 string, arg2 int, arg3 float32) {
	fmt.Println(arg1, arg2, arg3)
}

func exeDayTime(arg1 string, arg2 int, arg3 float32) {
	fmt.Println(arg1, arg2, arg3)
}

停止计时器

// 将自动返回的ID作为参数传入可停止持续循环的TIMER
grapeTimer.StopTimer(Id)

参数设置

// 设置启用日志调试模式,建议正式版本关闭他
grapeTimer.CDebugMode = true
// 调用分析器使用的时区,可以个根据不同国家地区设置 
grapeTimer.LocationFormat = "Asia/Shanghai"
// 开启异步调度模式,在此模式下 timer执行时会建立一个go,不会阻塞其他timer执行调度,建议开启
grapeTimer.UseAsyncExec = true

获取下一次执行的时间

// 将自动返回的ID作为参数传入可停止持续循环的TIMER
 nextTimeStr := grapeTimer.String(Id) // 标准格式获取
 nextTimeStr = grapeTimer.Format("2006-01-02 15:04:05") // 通过自定义格式化获取
 allTimer := grapeTimer.List() // 全部Id对应日期的下一次执行时间

保存调度器

nextJson := grapeTimer.ToJson(Id) // 获取单个调度器保存到JSON格式下
allJson := grapeTimer.SaveAll()

生成调度器字符串

Id = grapeTimer.NewFromJson(jsonBody,"exec100Loop this arg1",2000,float32(200.5))

可用格式说明

调度器有轻度的日期模式分析体系,可提供每日,每周,每月的时间日期生成方式,具体格式如下:

关键字 格式 说明
Day Day 00:00:00 生成每日的日期时间
Week Week 1 00:00:00 生成每周的日期时间, 0~6 分别代表周日到周六
Month Month 1 00:00:00 生成每月该日期的时间,建议不要使用20日之后的日期

以上日期如果超过时间自动生成下一个时间,每月时间使用时,如本月不存在该日期,则直接返回错误。

代码示例:

	vtime, err := grapeTimer.Parser("Day 13:59:59") // 返回值为标准的*time.Time
	if err != nil {
		// 处理错误...
	}

        vtime, err = grapeTimer.Parser("Week 6 23:59:59")
	if err != nil {
		// 处理错误...
	}

	vtime, err = grapeTimer.Parser("Month 26 13:59:59")
	if err != nil {
		// 处理错误...
	}

代码输出:

2017-05-24 13:59:59 +0800 CST