mirror of
https://github.com/pgsty/minio.git
synced 2026-11-09 17:21:51 +03:00
fix(batch): release terminal markers after startup discovery
Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
@@ -209,6 +209,9 @@ func TestBatchDiscoveryKeepsNewlyFinishedJobsTerminal(t *testing.T) {
|
||||
return errErasureReadQuorum
|
||||
}
|
||||
defer close(results)
|
||||
if owner := pool.jobOwners["new-job"]; owner == nil || owner.state != "terminal" || owner.req != nil || owner.cancel != nil {
|
||||
t.Fatalf("terminal marker lost or retained the job payload: %+v", owner)
|
||||
}
|
||||
results <- itemOrErr[ObjectInfo]{Item: ObjectInfo{Name: "new-job"}}
|
||||
return nil
|
||||
},
|
||||
@@ -229,8 +232,17 @@ func TestBatchDiscoveryKeepsNewlyFinishedJobsTerminal(t *testing.T) {
|
||||
if attempts != 2 || len(pool.jobCh) != 0 {
|
||||
t.Fatalf("discovery re-admitted a failed job: scans=%d queue=%d", attempts, len(pool.jobCh))
|
||||
}
|
||||
if owner := pool.jobOwners["new-job"]; owner.state != "terminal" || owner.req != nil || owner.cancel != nil {
|
||||
t.Fatalf("terminal marker lost or retained the job payload: %+v", owner)
|
||||
if !pool.discoveryDone || len(pool.jobOwners) != 0 {
|
||||
t.Fatal("completed discovery retained terminal job markers")
|
||||
}
|
||||
job := &BatchJobRequest{ID: "after-discovery"}
|
||||
mustIAM(t, pool.queueJob(job))
|
||||
if !pool.beginJob(<-pool.jobCh) {
|
||||
t.Fatal("new submission after discovery has no owner")
|
||||
}
|
||||
pool.finishJob(job, nil)
|
||||
if len(pool.jobOwners) != 0 {
|
||||
t.Fatal("normal completion after discovery leaked an owner")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+10
-8
@@ -2242,14 +2242,15 @@ func (a adminAPIHandlers) CancelBatchJob(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// BatchJobPool batch job pool
|
||||
type BatchJobPool struct {
|
||||
ctx context.Context
|
||||
objLayer ObjectLayer
|
||||
mu sync.Mutex
|
||||
jobCh chan *BatchJobRequest
|
||||
jmu sync.Mutex // protects jobOwners
|
||||
jobOwners map[string]*batchJobOwner
|
||||
workerKillCh chan struct{}
|
||||
workerSize int
|
||||
ctx context.Context
|
||||
objLayer ObjectLayer
|
||||
mu sync.Mutex
|
||||
jobCh chan *BatchJobRequest
|
||||
jmu sync.Mutex // protects jobOwners and discoveryDone
|
||||
jobOwners map[string]*batchJobOwner
|
||||
discoveryDone bool
|
||||
workerKillCh chan struct{}
|
||||
workerSize int
|
||||
}
|
||||
|
||||
var globalBatchJobPool *BatchJobPool
|
||||
@@ -2326,6 +2327,7 @@ func (j *BatchJobPool) cleanupReports(randomWait func() time.Duration) {
|
||||
}
|
||||
|
||||
func (j *BatchJobPool) resume(randomWait func() time.Duration) {
|
||||
defer j.finishDiscovery()
|
||||
timer := time.NewTimer(randomWait())
|
||||
defer timer.Stop()
|
||||
// A retry scans the manifest prefix again, but only unadmitted paths may
|
||||
|
||||
+22
-4
@@ -105,9 +105,9 @@ func validateBatchJobAdminReq(ctx context.Context, w http.ResponseWriter, r *htt
|
||||
}
|
||||
|
||||
// One owner record spans queued, running and paused attempts. The request
|
||||
// pointer is the generation token. Canceled and terminal records are small
|
||||
// tombstones until process shutdown, so a delayed discovery cannot requeue a
|
||||
// job after its owner finished, including a terminal partial failure.
|
||||
// pointer is the generation token. Canceled records fence stale requests until
|
||||
// shutdown. Terminal records fence discovery until the startup scan finishes,
|
||||
// including jobs submitted and terminated while the scan was unavailable.
|
||||
type batchJobOwner struct {
|
||||
req *BatchJobRequest
|
||||
cancel context.CancelFunc
|
||||
@@ -141,7 +141,25 @@ func (j *BatchJobPool) finishJob(job *BatchJobRequest, err error) {
|
||||
return
|
||||
}
|
||||
o.cancel()
|
||||
j.jobOwners[job.ID] = &batchJobOwner{state: "terminal"}
|
||||
if j.discoveryDone {
|
||||
delete(j.jobOwners, job.ID)
|
||||
} else {
|
||||
j.jobOwners[job.ID] = &batchJobOwner{state: "terminal"}
|
||||
}
|
||||
}
|
||||
|
||||
// After the only startup discovery has returned, no loaded manifest remains
|
||||
// to re-admit a terminal job. Release its marker, but keep queued, running,
|
||||
// paused and canceled ownership intact. New submissions use new job IDs.
|
||||
func (j *BatchJobPool) finishDiscovery() {
|
||||
j.jmu.Lock()
|
||||
defer j.jmu.Unlock()
|
||||
j.discoveryDone = true
|
||||
for id, owner := range j.jobOwners {
|
||||
if owner.state == "terminal" {
|
||||
delete(j.jobOwners, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func batchJobRetryDelay(retries uint) time.Duration {
|
||||
|
||||
Reference in New Issue
Block a user