在改go-mysql-elasticsearch项目的的代码的时候,golang对不同的goroutine之间的数据传递可以做到很简单,
go知识整理之go channel
这是一个main的主循环
func (r *River) syncLoop() {
//River里封装了所有需要被使用的信息
bulkSize := r.c.BulkSize
if bulkSize == 0 {
bulkSize = 128
}
interval := r.c.FlushBulkTime.Duration
if interval == 0 {
interval = 200 * time.Millisecond
}
ticker := time.NewTicker(interval)
defer ticker.Stop()
defer r.wg.Done()
lastSavedTime := time.Now()
reqs := make([]*elastic.BulkRequest, 0, 1024)
var pos mysql.Position
for {//循环
needFlush := false
needSavePos := false
select {
case v := <-r.syncCh:
//接收已经过处理的mysql事件(instert,update,delete)
switch v := v.(type) {
case posSaver:
now := time.Now()
if v.force || now.Sub(lastSavedTime) > 3*time.Second {
lastSavedTime = now
needFlush = true
needSavePos = true
pos = v.pos
}
case []*elastic.BulkRequest:
reqs = append(reqs, v...)
needFlush = len(reqs) >= bulkSize
}
case <-ticker.C :
needFlush = true
case <-r.ctx.Done():
//退出时会通过chan通知到这里
return
}
if needFlush {
// TODO: retry some times?
if err := r.doBulk(reqs); err != nil {
log.Errorf("do ES bulk err %v, close sync", err)
r.cancel()
return
}
reqs = reqs[0:0]
}
if needSavePos {
if err := r.master.Save(pos); err != nil {
log.Errorf("save sync position %s err %v, close sync", pos, err)
r.cancel()
return
}
}
}
}
通过channel接收事件,再通过当前调用elastic的api把数据批量写入elasticsearch
移动端的主界面实时刷新,还有播放器播放主线程实时刷新,与这种写法共通之处,但是处理异步通信,channel还是很方便的.