gh-ost/vendor/github.com/siddontang/go-mysql/canal/master.go
2017-02-12 13:13:54 +02:00

90 lines
1.5 KiB
Go

package canal
import (
"bytes"
"os"
"sync"
"time"
"github.com/BurntSushi/toml"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/siddontang/go-mysql/mysql"
"github.com/siddontang/go/ioutil2"
)
type masterInfo struct {
Addr string `toml:"addr"`
Name string `toml:"bin_name"`
Position uint32 `toml:"bin_pos"`
name string
l sync.Mutex
lastSaveTime time.Time
}
func loadMasterInfo(name string) (*masterInfo, error) {
var m masterInfo
m.name = name
f, err := os.Open(name)
if err != nil && !os.IsNotExist(errors.Cause(err)) {
return nil, errors.Trace(err)
} else if os.IsNotExist(errors.Cause(err)) {
return &m, nil
}
defer f.Close()
_, err = toml.DecodeReader(f, &m)
return &m, err
}
func (m *masterInfo) Save(force bool) error {
m.l.Lock()
defer m.l.Unlock()
n := time.Now()
if !force && n.Sub(m.lastSaveTime) < time.Second {
return nil
}
var buf bytes.Buffer
e := toml.NewEncoder(&buf)
e.Encode(m)
var err error
if err = ioutil2.WriteFileAtomic(m.name, buf.Bytes(), 0644); err != nil {
log.Errorf("canal save master info to file %s err %v", m.name, err)
}
m.lastSaveTime = n
return errors.Trace(err)
}
func (m *masterInfo) Update(name string, pos uint32) {
m.l.Lock()
m.Name = name
m.Position = pos
m.l.Unlock()
}
func (m *masterInfo) Pos() mysql.Position {
var pos mysql.Position
m.l.Lock()
pos.Name = m.Name
pos.Pos = m.Position
m.l.Unlock()
return pos
}
func (m *masterInfo) Close() {
m.Save(true)
}