Skip to content

Commit 88a8e0a

Browse files
authored
Merge pull request #3144 from dperny/fix-volume-scheduling
Free unused volumes in more cases
2 parents 467b19e + 570d132 commit 88a8e0a

3 files changed

Lines changed: 37 additions & 20 deletions

File tree

manager/scheduler/scheduler.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,18 @@ func (s *Scheduler) tick(ctx context.Context) {
488488
}
489489

490490
func (s *Scheduler) applySchedulingDecisions(ctx context.Context, schedulingDecisions map[string]schedulingDecision) (successful, failed []schedulingDecision) {
491+
// applySchedulingDecisions is the only place where we make store
492+
// transactions in the scheduler. the scheduler is responsible for freeing
493+
// volumes that are no longer in use. this means that volumes should be
494+
// freed in this function. sometimes, there are no scheduling decisions to
495+
// be made, so we return early in the if statement below.
496+
//
497+
// however, in all cases, any activity that results in a tick could result
498+
// in needing volumes to be freed, even if nothing new is scheduled. this
499+
// freeing of volumes should always happen *after* all of the scheduling
500+
// decisions have been committed, hence the defer.
501+
defer s.store.Batch(s.volumes.freeVolumes)
502+
491503
if len(schedulingDecisions) == 0 {
492504
return
493505
}
@@ -619,9 +631,7 @@ func (s *Scheduler) applySchedulingDecisions(ctx context.Context, schedulingDeci
619631
}
620632
// finally, every time we make new scheduling decisions, take the
621633
// opportunity to release volumes.
622-
return batch.Update(func(tx store.Tx) error {
623-
return s.volumes.freeVolumes(tx)
624-
})
634+
return nil
625635
})
626636

627637
if err != nil {

manager/scheduler/volumes.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -183,24 +183,33 @@ func (vs *volumeSet) releaseVolume(volumeID, taskID string) {
183183
//
184184
// TODO(dperny): this is messy and has a lot of overhead. it should be reworked
185185
// to something more streamlined.
186-
func (vs *volumeSet) freeVolumes(tx store.Tx) error {
186+
func (vs *volumeSet) freeVolumes(batch *store.Batch) error {
187187
for volumeID, info := range vs.volumes {
188-
v := store.GetVolume(tx, volumeID)
189-
if v == nil {
190-
continue
191-
}
188+
if err := batch.Update(func(tx store.Tx) error {
189+
v := store.GetVolume(tx, volumeID)
190+
if v == nil {
191+
return nil
192+
}
192193

193-
changed := false
194-
for _, status := range v.PublishStatus {
195-
if info.nodes[status.NodeID] == 0 && status.State == api.VolumePublishStatus_PUBLISHED {
196-
status.State = api.VolumePublishStatus_PENDING_NODE_UNPUBLISH
197-
changed = true
194+
// when we are freeing a volume, we may update more than one of the
195+
// volume's PublishStatuses. this means we can't simply put the
196+
// Update call inside of the if statement; we need to know if we've
197+
// changed anything once we've checked *all* of the statuses.
198+
changed := false
199+
for _, status := range v.PublishStatus {
200+
if info.nodes[status.NodeID] == 0 && status.State == api.VolumePublishStatus_PUBLISHED {
201+
status.State = api.VolumePublishStatus_PENDING_NODE_UNPUBLISH
202+
changed = true
203+
}
198204
}
199-
}
200-
if changed {
201-
if err := store.UpdateVolume(tx, v); err != nil {
202-
return err
205+
if changed {
206+
if err := store.UpdateVolume(tx, v); err != nil {
207+
return err
208+
}
203209
}
210+
return nil
211+
}); err != nil {
212+
return err
204213
}
205214
}
206215
return nil

manager/scheduler/volumes_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,9 +652,7 @@ var _ = Describe("volumeSet", func() {
652652
vs.releaseVolume(volumes[0].ID, tasks[0].ID)
653653
vs.releaseVolume(allVolume.ID, tasks[0].ID)
654654

655-
err := s.Update(func(tx store.Tx) error {
656-
return vs.freeVolumes(tx)
657-
})
655+
err := s.Batch(vs.freeVolumes)
658656
Expect(err).ToNot(HaveOccurred())
659657

660658
var freshVolumes []*api.Volume

0 commit comments

Comments
 (0)