func()

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
}