🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

Commit f3756a1

Browse files
committed
get-batch: abort vs active assembly (part four)
* restore abort wait on active asm() before cleaning pending WIs * add bounded DemandBase quiesce * reject late assembly when x-moss is aborted/done * hide internal inc/dec-pending from external call sites --- * part four, prev. commit: 9ad57d3 Signed-off-by: Alex Aizman <alex.aizman@gmail.com>
1 parent 9ad57d3 commit f3756a1

2 files changed

Lines changed: 37 additions & 27 deletions

File tree

‎ais/ml.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,8 @@ func (ctx *mossCtx) phase1(w http.ResponseWriter, r *http.Request, config *cmn.C
471471
}
472472

473473
// to have a fresh full idle window for the eventual phase2 GET
474-
xmoss.IncPending()
475-
xmoss.DecPending()
474+
xmoss.DemandBase.IncPending()
475+
xmoss.DemandBase.DecPending()
476476

477477
// return xid (proxy will send it to phase 3 senders)
478478
w.Header().Set(apc.HdrXactionID, xid)
@@ -519,7 +519,7 @@ func (ctx *mossCtx) phase3(w http.ResponseWriter, r *http.Request, config *cmn.C
519519
}
520520

521521
ctx.smap = smap
522-
xmoss.IncPending()
522+
xmoss.DemandBase.IncPending()
523523
go ctx._startSend(xmoss, tsi)
524524
}
525525

@@ -529,7 +529,7 @@ func (ctx *mossCtx) _startSend(xmoss *xs.XactMoss, tsi *meta.Snode) {
529529
xmoss.AddErr(fmt.Errorf("send wid=%s: %v", ctx.wid, err), 4, cos.ModXs)
530530
}
531531
}
532-
xmoss.DecPending()
532+
xmoss.DemandBase.DecPending()
533533
}
534534

535535
func _checkMossEmpty(req *apc.MossReq) (err error) {

‎xact/xs/moss.go‎

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ type (
208208
pending sync.Map // [wid => *basewi]
209209
abortedWIDs sync.Map // wid => error from DT
210210
xact.DemandBase
211-
activeWG sync.WaitGroup // when pending
211+
activeWG sync.WaitGroup // active asm()
212212
lastLog atomic.Int64 // last log timestamp (sparse)
213213
advNextCheck atomic.Int64
214214
pendingCnt atomic.Int64
@@ -350,12 +350,12 @@ func (r *XactMoss) housekeep(now int64) time.Duration {
350350

351351
func (*XactMoss) Run(*sync.WaitGroup) { debug.Assert(false) }
352352

353-
func (r *XactMoss) IncPending() {
353+
func (r *XactMoss) incPending() {
354354
r.DemandBase.IncPending()
355355
r.activeWG.Add(1)
356356
}
357357

358-
func (r *XactMoss) DecPending() {
358+
func (r *XactMoss) decPending() {
359359
r.DemandBase.DecPending()
360360
r.activeWG.Done()
361361
}
@@ -371,23 +371,8 @@ func (r *XactMoss) Abort(err error) bool {
371371

372372
nlog.Infoln(r.Name(), "aborting:", err)
373373

374-
// best-effort wait for pending WIs to drain; never block indefinitely
375-
const (
376-
pollIval = 100 * time.Millisecond
377-
)
378-
{
379-
var (
380-
total time.Duration
381-
maxWait = max(cmn.Rom.MaxKeepalive(), 8*time.Second)
382-
)
383-
for r.pendingCnt.Load() > 0 && total < maxWait {
384-
time.Sleep(pollIval)
385-
total += pollIval
386-
}
387-
if r.pendingCnt.Load() > 0 {
388-
nlog.Warningln(r.Name(), "abort: still", r.pendingCnt.Load(), "pending after", maxWait, "- proceeding anyway")
389-
}
390-
}
374+
r.activeWG.Wait()
375+
r._abortQuiesce()
391376

392377
r.pending.Range(r.cleanup)
393378
r.pending.Clear()
@@ -401,6 +386,22 @@ func (r *XactMoss) Abort(err error) bool {
401386
return true
402387
}
403388

389+
// best-effort (and extremely unlikely): quiesce prior to cleanups
390+
func (r *XactMoss) _abortQuiesce() {
391+
const pollIval = cos.PollSleepShort // 100ms
392+
var (
393+
total time.Duration
394+
maxWait = max(cmn.Rom.MaxKeepalive(), 8*time.Second)
395+
)
396+
for r.Pending() > 0 && total < maxWait {
397+
time.Sleep(pollIval)
398+
total += pollIval
399+
}
400+
if p := r.Pending(); p > 0 {
401+
nlog.Warningln(r.Name(), "abort: still", p, "demand-pending after", maxWait, "- proceeding anyway")
402+
}
403+
}
404+
404405
// (Abort, fini) => pending (sync.Map's) callback to cleanup all pending work items
405406
func (*XactMoss) cleanup(_, value any) bool {
406407
wi := value.(*basewi)
@@ -674,11 +675,20 @@ func (r *XactMoss) Assemble(req *apc.MossReq, w http.ResponseWriter, wid string)
674675
return err
675676
}
676677

678+
if r.IsAborted() || r.IsDone() {
679+
wi.owned.CAS(wiownASM, wiownNone) // Abort/fini owns final cleanup
680+
return nil
681+
}
682+
677683
// asm() path owns wi; DecPending below
678-
debug.Assert(wid == wi.wid)
679-
r.IncPending()
680-
defer r.DecPending()
684+
r.incPending()
685+
defer r.decPending()
686+
if r.IsAborted() || r.IsDone() {
687+
wi.owned.CAS(wiownASM, wiownNone) // ditto
688+
return nil
689+
}
681690

691+
debug.Assert(wid == wi.wid)
682692
err := r.asm(req, w, wi)
683693
if err != nil {
684694
if r.shouldAbortWI(wi) {

0 commit comments

Comments
 (0)