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 }