112 lines
1.3 KiB
Go
112 lines
1.3 KiB
Go
|
package wal
|
||
|
|
||
|
import (
|
||
|
"database/sql"
|
||
|
"sync"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func (w *Writer) start() {
|
||
|
w.lock.Lock()
|
||
|
defer w.lock.Unlock()
|
||
|
|
||
|
if w.running {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
w.insertQ = make(chan insertJob, 1024)
|
||
|
|
||
|
var maxSeqNum uint64
|
||
|
row := w.db.QueryRow(sqlWALMaxSeqNum)
|
||
|
must(row.Scan(&maxSeqNum))
|
||
|
|
||
|
w.doneWG.Add(1)
|
||
|
go w.insertProc(maxSeqNum)
|
||
|
w.running = true
|
||
|
}
|
||
|
|
||
|
func (w *Writer) stop() {
|
||
|
w.lock.Lock()
|
||
|
defer w.lock.Unlock()
|
||
|
|
||
|
if !w.running {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
close(w.insertQ)
|
||
|
w.doneWG.Wait()
|
||
|
w.running = false
|
||
|
}
|
||
|
|
||
|
func (w *Writer) insertProc(maxSeqNum uint64) {
|
||
|
defer w.doneWG.Done()
|
||
|
|
||
|
var (
|
||
|
job insertJob
|
||
|
tx *sql.Tx
|
||
|
insert *sql.Stmt
|
||
|
ok bool
|
||
|
err error
|
||
|
newSeqNum uint64
|
||
|
now int64
|
||
|
wgs = make([]*sync.WaitGroup, 10)
|
||
|
)
|
||
|
|
||
|
var ()
|
||
|
|
||
|
BEGIN:
|
||
|
|
||
|
newSeqNum = maxSeqNum
|
||
|
wgs = wgs[:0]
|
||
|
|
||
|
job, ok = <-w.insertQ
|
||
|
if !ok {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
tx, err = w.db.Begin()
|
||
|
must(err)
|
||
|
|
||
|
insert, err = tx.Prepare(sqlWALInsert)
|
||
|
must(err)
|
||
|
|
||
|
now = time.Now().Unix()
|
||
|
|
||
|
LOOP:
|
||
|
|
||
|
newSeqNum++
|
||
|
_, err = insert.Exec(
|
||
|
newSeqNum,
|
||
|
now,
|
||
|
job.Collection,
|
||
|
job.ID,
|
||
|
job.Store,
|
||
|
job.Data)
|
||
|
|
||
|
must(err)
|
||
|
if job.Ready != nil {
|
||
|
wgs = append(wgs, job.Ready)
|
||
|
}
|
||
|
|
||
|
select {
|
||
|
case job, ok = <-w.insertQ:
|
||
|
if ok {
|
||
|
goto LOOP
|
||
|
}
|
||
|
default:
|
||
|
}
|
||
|
|
||
|
goto COMMIT
|
||
|
|
||
|
COMMIT:
|
||
|
|
||
|
must(tx.Commit())
|
||
|
|
||
|
maxSeqNum = newSeqNum
|
||
|
for i := range wgs {
|
||
|
wgs[i].Done()
|
||
|
}
|
||
|
|
||
|
goto BEGIN
|
||
|
}
|