1 Star 0 Fork 0

scgg/GPool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
loaderController.go 4.05 KB
一键复制 编辑 原始数据 按行查看 历史
scgg 提交于 2021-12-22 17:24 . 负载生成器
package GPool
import (
"context"
"fmt"
"log"
"sync/atomic"
"time"
)
// 日志记录器
var logger = log.Default()
// 载荷发生器的状态
const (
STATUS_ORIGINAL uint32 = 0 // 原始状态
STATUS_STARTING uint32 = 1 // 正在启动
STATUS_STARTED uint32 = 2 // 已启动
STATUS_STOPPING uint32 = 3 // 正在停止
STATUS_STOPPED uint32 = 4 // 已停止
)
// Caller 调用器接口,为用户提供个性化支持
type Caller interface {
BuildReq() RawReq // 构建请求
Call(req []byte, timeoutNS time.Duration) ([]byte, error) // 调用载荷发生器
CheckResp(rawReq RawReq, rawResp RawResp) *CallResult // 检查响应
}
// Generator 载荷发生器接口
type Generator interface {
Start() bool // 启动载荷发生器,启动成功返回true
Stop() bool // 停止载荷发生器,停止成功返回true
Status() uint32 // 获取状态
CallCount() int64 // 获取调用计数,每次启动会重置该计数
}
type myGenerator struct {
caller Caller // 调用器
status uint32 // 载荷发生器的状态
timeoutNS time.Duration // 响应超时时间,单位为: ns(纳秒)
lps uint32 // 每秒载荷量
durationNS time.Duration // 负载持续时间,单位为: ns(纳秒)
resultCh chan *CallResult // 负载的输出结果列表(调用结果通道)
concurrency uint32 // 载荷并发量
tickets GoTickets // goroutine池,大小由concurrency决定
ctx context.Context // 上下文
cancelFunc context.CancelFunc // 取消函数
}
type CallResult struct {
ID int64 // 载荷编号
Req RawReq // 原生请求
Resp RawResp // 原生响应
Code RetCode // 响应代码
Msg string // 结果成因简述
Elapse time.Duration // 耗时
}
// RawReq 原生请求
type RawReq struct {
ID int64 // 载荷编号
Req []byte // 请求数据
}
// RawResp 原生响应
type RawResp struct {
ID int64
Resp []byte
Err error // 载荷处理过程中的错误
Elapse time.Duration // 载荷处理耗时
}
func NewGenerator(caller Caller, timeoutNS time.Duration, lps uint32, durationNS time.Duration, resultCh chan *CallResult) (Generator, error) {
gen := &myGenerator{
caller: caller,
status: STATUS_ORIGINAL,
timeoutNS: timeoutNS,
lps: lps,
durationNS: durationNS,
resultCh: resultCh,
}
return gen, nil
}
// -------------------- 票池 -------------------
// GoTickets goroutine票池的接口
type GoTickets interface {
Take() // 获得一张票
Return() // 归还一张票
Active() bool // 票池是否被激活
Total() uint32 // 总的票数
Remainder() uint32 // 剩余票数
}
type myGoTickets struct {
total uint32 // 票的总数
ticketCh chan struct{} // 票的容器
active bool // 票池是否已被激活
}
func NewGoTickets(total uint32) (GoTickets, error) {
gt := myGoTickets{}
if !gt.init(total) {
return nil, fmt.Errorf("goroutine ticket pool init failed (total = %d)\n", total)
}
return &gt, nil
}
func (gt *myGoTickets) init(total uint32) bool {
if gt.active {
return false
}
if total == 0 {
return false
}
ch := make(chan struct{}, total)
n := int(total)
for i := 0; i < n; i++ {
ch <- struct{}{}
}
gt.ticketCh = ch
gt.total = total
gt.active = true
return true
}
func (gt *myGoTickets) Take() {
<- gt.ticketCh
atomic.AddUint32(&gt.total, -1)
}
func (gt *myGoTickets) Return() {
gt.ticketCh <- struct{}{}
atomic.AddUint32(&gt.total, 1)
}
func (gt *myGoTickets) Active() bool {
return gt.active
}
func (gt *myGoTickets) Total() uint32 {
return gt.total
}
func (gt *myGoTickets) Remainder() uint32 {
return uint32(int(gt.total) - len(gt.ticketCh))
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/scgg/gpool.git
[email protected]:scgg/gpool.git
scgg
gpool
GPool
master

搜索帮助