public function getFreeAddress() : Address
{
if ($this->addressRepository->countBy([]) == 0) {
$this->generateAndPersistNewAddresses(10);
}
$this->entityManager->beginTransaction();
$addressMaxAge = new \DateTime($this->addressLockTime);
$qb = $this->addressRepository->createQueryBuilder('address');
$qb->addSelect('count(address) as free')->where('address.lastUsed IS NULL')->orWhere('address.lastUsed < :maxAge')->setParameter('maxAge', $addressMaxAge)->setMaxResults(1);
/** @var Address $address */
$result = $qb->getQuery()->getSingleResult();
$address = $result[0];
$free = $result['free'];
$address->useAddress();
$this->entityManager->flush($address);
$qb = $this->entityManager->createQueryBuilder();
$qb->select('COUNT(address) AS total')->from(Address::getClassName(), 'address');
$total = $qb->getQuery()->getSingleScalarResult();
$occupied = $total - $free;
if ($occupied / $total >= $this->occupiedAddressesTreshold) {
$this->generateAndPersistNewAddresses(round($total * $this->increaseRatio));
}
$this->entityManager->commit();
return $address;
}