github.com/uchennaokeke444/nomad@v0.11.8/nomad/csi_batch.go (about) 1 package nomad 2 3 import ( 4 log "github.com/hashicorp/go-hclog" 5 multierror "github.com/hashicorp/go-multierror" 6 "github.com/hashicorp/nomad/nomad/structs" 7 ) 8 9 // csiBatchRelease is a helper for any time we need to release a bunch 10 // of volume claims at once. It de-duplicates the volumes and batches 11 // the raft messages into manageable chunks. Intended for use by RPCs 12 // that have already been forwarded to the leader. 13 type csiBatchRelease struct { 14 srv *Server 15 logger log.Logger 16 17 maxBatchSize int 18 seen map[string]struct{} 19 batches []*structs.CSIVolumeClaimBatchRequest 20 } 21 22 func newCSIBatchRelease(srv *Server, logger log.Logger, max int) *csiBatchRelease { 23 return &csiBatchRelease{ 24 srv: srv, 25 logger: logger, 26 maxBatchSize: max, 27 seen: map[string]struct{}{}, 28 batches: []*structs.CSIVolumeClaimBatchRequest{{}}, 29 } 30 } 31 32 // add the volume ID + namespace to the deduplicated batches 33 func (c *csiBatchRelease) add(vol, namespace string) { 34 id := vol + "\x00" + namespace 35 36 // ignore duplicates 37 _, seen := c.seen[id] 38 if seen { 39 return 40 } 41 c.seen[id] = struct{}{} 42 43 req := structs.CSIVolumeClaimRequest{ 44 VolumeID: vol, 45 Claim: structs.CSIVolumeClaimRelease, 46 } 47 req.Namespace = namespace 48 req.Region = c.srv.config.Region 49 50 for _, batch := range c.batches { 51 // otherwise append to the first non-full batch 52 if len(batch.Claims) < c.maxBatchSize { 53 batch.Claims = append(batch.Claims, req) 54 return 55 } 56 } 57 // no non-full batch found, make a new one 58 newBatch := &structs.CSIVolumeClaimBatchRequest{ 59 Claims: []structs.CSIVolumeClaimRequest{req}} 60 c.batches = append(c.batches, newBatch) 61 } 62 63 // apply flushes the batches to raft 64 func (c *csiBatchRelease) apply() error { 65 var result *multierror.Error 66 for _, batch := range c.batches { 67 if len(batch.Claims) > 0 { 68 _, _, err := c.srv.raftApply(structs.CSIVolumeClaimBatchRequestType, batch) 69 if err != nil { 70 c.logger.Error("csi raft apply failed", "error", err, "method", "claim") 71 result = multierror.Append(result, err) 72 } 73 } 74 } 75 return result.ErrorOrNil() 76 }