(req *commitReq)
| 178 | } |
| 179 | |
| 180 | func (r *Runtime) followerDoCommit(req *commitReq) { |
| 181 | if req.log == nil { |
| 182 | log.Fatal("NO LOG FOR FOLLOWER COMMIT") |
| 183 | return |
| 184 | } |
| 185 | |
| 186 | waitCommitTask := trace.StartRegion(req.ctx, "waitForLastCommit") |
| 187 | |
| 188 | // check for last commit availability |
| 189 | myLastCommit := atomic.LoadUint64(&r.lastCommit) |
| 190 | if req.lastCommit != myLastCommit { |
| 191 | // TODO(): need counter for retries, infinite commit re-order would cause troubles |
| 192 | go func(req *commitReq) { |
| 193 | _, _ = r.waitForLog(req.ctx, req.lastCommit) |
| 194 | r.commitCh <- req |
| 195 | }(req) |
| 196 | waitCommitTask.End() |
| 197 | return |
| 198 | } |
| 199 | |
| 200 | waitCommitTask.End() |
| 201 | req.tm.Add("queue") |
| 202 | |
| 203 | defer trace.StartRegion(req.ctx, "commitCycle").End() |
| 204 | |
| 205 | var err error |
| 206 | |
| 207 | // write log first |
| 208 | if err = r.writeWAL(req.ctx, req.log); err != nil { |
| 209 | return |
| 210 | } |
| 211 | |
| 212 | req.tm.Add("write_wal") |
| 213 | |
| 214 | // do commit, not wrapping underlying handler commit error |
| 215 | _, storageErr := r.doCommit(req.ctx, req.data, false) |
| 216 | |
| 217 | req.tm.Add("db_write") |
| 218 | |
| 219 | // mark last commit |
| 220 | atomic.StoreUint64(&r.lastCommit, req.log.Index) |
| 221 | |
| 222 | req.result.Set(&commitResult{ |
| 223 | err: err, |
| 224 | storageErr: storageErr, |
| 225 | }) |
| 226 | |
| 227 | return |
| 228 | } |
| 229 | |
| 230 | func (r *Runtime) getPrepareLog(ctx context.Context, l *kt.Log) (lastCommitIndex uint64, pl *kt.Log, err error) { |
| 231 | defer trace.StartRegion(ctx, "getPrepareLog").End() |
no test coverage detected