in pkg/pool/pool.go [236:286]
func (p *pool) AssignResource(requesterID string) (resourceID string, shouldReconcile bool, err error) {
p.lock.Lock()
defer p.lock.Unlock()
if _, isAlreadyAssigned := p.usedResources[requesterID]; isAlreadyAssigned {
return "", false, ErrResourceAlreadyAssigned
}
if len(p.usedResources) == p.capacity {
return "", false, ErrPoolAtMaxCapacity
}
// Caller must retry at max by 30 seconds [Max time resource will sit in the cool down queue]
if len(p.usedResources)+len(p.coolDownQueue) == p.capacity {
return "", false, ErrResourceAreBeingCooledDown
}
// Caller can retry in 600 ms [Average time to create and attach a new ENI] or less
if len(p.usedResources)+len(p.coolDownQueue)+p.pendingCreate+p.pendingDelete == p.capacity {
return "", false, ErrResourcesAreBeingCreated
}
if len(p.warmResources) == 0 {
// If prefix is not available in subnet, caller can retry in 2 min [Action required from user to change subnet]
if p.isPDPool && !p.prefixAvailable {
return "", false, ErrInsufficientCidrBlocks
}
// Caller can retry in 600 ms [Average time to assign a new secondary IP or prefix] or less
// Different from above check because here we want to perform reconciliation
return "", true, ErrWarmPoolEmpty
}
// Allocate the resource
resource := Resource{}
if p.isPDPool {
resource = p.assignResourceFromMinGroup()
} else {
resource = p.assignResourceFromAnyGroup()
}
if resource.ResourceID == "" || resource.GroupID == "" {
return "", true, ErrWarmPoolEmpty
}
// Add the resource in the used resource key-value pair
p.usedResources[requesterID] = resource
p.log.V(1).Info("assigned resource",
"resource id", resource.ResourceID, "requester id", requesterID)
return resource.ResourceID, true, nil
}