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  }