<?php
 namespace App\Core\IpAllocator\Strategies; use App\Core\IpAllocator\AllocatorInterface; use App\Core\IpAllocator\Exceptions\PoolExhaustedException; use App\Models\IpAddress; use App\Models\IpPool; use Illuminate\Support\Facades\DB; class RandomAllocator implements AllocatorInterface { public function allocate(IpPool $pool): IpAddress { return DB::transaction(function () use ($pool) { $count = $pool->ipAddresses()->where('status', 'free')->count(); if ($count === 0) { throw PoolExhaustedException::for($pool->id, $pool->name); } $offset = random_int(0, $count - 1); $ip = $pool->ipAddresses() ->where('status', 'free') ->skip($offset) ->lockForUpdate() ->first(); $ip->update([ 'status' => 'used', 'assigned_at' => now(), ]); return $ip->fresh(); }); } public function key(): string { return 'random'; } } 