1 回答
TA贡献1802条经验 获得超10个赞
我提出的解决方案如下:
type job struct {
query string
idle time.Time
}
...
var reference time.Time
start := time.Now()
for {
q := p.GetNext()
if q == (query.Query{}) {
s.Stop()
break
}
db.logger.Tracef("query: %s", q.Query)
r.queries++
s.Suffix = " queries replayed: " + strconv.Itoa(r.queries)
// We need a reference time
if firstPass {
firstPass = false
reference = q.Time
}
var j job
delta := q.Time.Sub(reference)
j.idle = start.Add(delta)
j.query = q.Query
db.logger.Tracef("next sleeping time: %s", j.idle)
jobs <- j
}
...
func (db database) worker(jobs chan job, errors chan error, wg *sync.WaitGroup) {
defer wg.Done()
for {
j, ok := <-jobs
if !ok {
db.logger.Trace("channel closed, worker exiting")
return
}
sleep := time.Until(j.idle)
if sleep > 0 {
time.Sleep(sleep)
}
rows, err := db.drv.Query(j.query)
if err != nil {
errors <- err
db.logger.Debugf("failed to execute query:\n%s\nerror: %s", j.query, err)
}
if rows != nil {
rows.Close()
}
}
}
解释:
我们将程序的开头保存在一个变量中(此处 )。接下来,我们设置一个引用时间(in ),这是慢速查询日志文件的第一个时间戳。它永远不会改变。startreference
然后,在每个新查询中,我们计算 与当前查询时间戳 之间的持续时间。让我们将其存储在 .referenceq.Timedelta
我们添加到时间线中,并且有一个时间戳(而不是像过去那样在慢速查询日志文件中)。我们将此时间戳发送到我们创建的新结构中查询旁边的工作线程,该结构名为 。deltastartjob
当工作人员通过通道收到作业时,他会计算等待的时间,直到他可以执行查询。如果它<= 0,它将立即执行查询,否则他将等待。
- 1 回答
- 0 关注
- 107 浏览
添加回答
举报
