github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/cluster/calcium/dissociate.go (about)

     1  package calcium
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/projecteru2/core/log"
     7  	"github.com/projecteru2/core/resource/plugins"
     8  	resourcetypes "github.com/projecteru2/core/resource/types"
     9  	"github.com/projecteru2/core/types"
    10  	"github.com/projecteru2/core/utils"
    11  )
    12  
    13  // DissociateWorkload dissociate workload from eru, return it resource but not modity it
    14  func (c *Calcium) DissociateWorkload(ctx context.Context, IDs []string) (chan *types.DissociateWorkloadMessage, error) {
    15  	logger := log.WithFunc("caliucm.DissociateWorkload").WithField("IDs", IDs)
    16  
    17  	nodeWorkloadGroup, err := c.groupWorkloadsByNode(ctx, IDs)
    18  	if err != nil {
    19  		logger.Error(ctx, err, "failed to group workloads by node")
    20  		return nil, err
    21  	}
    22  
    23  	ch := make(chan *types.DissociateWorkloadMessage)
    24  	_ = c.pool.Invoke(func() {
    25  		defer close(ch)
    26  
    27  		for nodename, workloadIDs := range nodeWorkloadGroup {
    28  			if err := c.withNodePodLocked(ctx, nodename, func(ctx context.Context, node *types.Node) error {
    29  				for _, workloadID := range workloadIDs { //nolint:scopelint
    30  					msg := &types.DissociateWorkloadMessage{WorkloadID: workloadID} //nolint:scopelint
    31  					if err := c.withWorkloadLocked(ctx, workloadID, false, func(ctx context.Context, workload *types.Workload) error {
    32  						return utils.Txn(
    33  							ctx,
    34  							// if
    35  							func(ctx context.Context) (err error) {
    36  								_, _, err = c.rmgr.SetNodeResourceUsage(ctx, node.Name, nil, nil, []resourcetypes.Resources{workload.Resources}, true, plugins.Decr)
    37  								return err
    38  							},
    39  							// then
    40  							func(ctx context.Context) error {
    41  								return c.store.RemoveWorkload(ctx, workload)
    42  							},
    43  							// rollback
    44  							func(ctx context.Context, failedByCond bool) error {
    45  								if failedByCond {
    46  									return nil
    47  								}
    48  								_, _, err = c.rmgr.SetNodeResourceUsage(ctx, node.Name, nil, nil, []resourcetypes.Resources{workload.Resources}, true, plugins.Incr)
    49  								return err
    50  							},
    51  							c.config.GlobalTimeout,
    52  						)
    53  					}); err != nil {
    54  						logger.WithField("id", workloadID).Error(ctx, err, "failed to lock workload")
    55  						msg.Error = err
    56  					}
    57  					ch <- msg
    58  				}
    59  				_ = c.pool.Invoke(func() { c.RemapResourceAndLog(ctx, logger, node) })
    60  				return nil
    61  			}); err != nil {
    62  				logger.WithField("node", nodename).Error(ctx, err, "failed to lock node")
    63  			}
    64  		}
    65  	})
    66  	return ch, nil
    67  }