protected function buildLocksTab($owner_phid) { $locks = DrydockSlotLock::loadLocks($owner_phid); $rows = array(); foreach ($locks as $lock) { $rows[] = array($lock->getID(), $lock->getLockKey()); } $table = id(new AphrontTableView($rows))->setNoDataString(pht('No slot locks held.'))->setHeaders(array(pht('ID'), pht('Lock Key')))->setColumnClasses(array(null, 'wide')); return id(new PHUIPropertyListView())->addRawContent($table); }
protected function getConcurrentResourceLimitSlotLock(DrydockBlueprint $blueprint) { $limit = $this->getConcurrentResourceLimit($blueprint); if ($limit === null) { return; } $blueprint_phid = $blueprint->getPHID(); // TODO: This logic shouldn't do anything awful, but is a little silly. It // would be nice to unify the "huge limit" and "small limit" cases // eventually but it's a little tricky. // If the limit is huge, just pick a random slot. This is just stopping // us from exploding if someone types a billion zillion into the box. if ($limit > 1024) { $slot = mt_rand(0, $limit - 1); return "allocator({$blueprint_phid}).limit({$slot})"; } // For reasonable limits, actually check for an available slot. $locks = DrydockSlotLock::loadLocks($blueprint_phid); $locks = mpull($locks, null, 'getLockKey'); $slots = range(0, $limit - 1); shuffle($slots); foreach ($slots as $slot) { $slot_lock = "allocator({$blueprint_phid}).limit({$slot})"; if (empty($locks[$slot_lock])) { return $slot_lock; } } // If we found no free slot, just return whatever we checked last (which // is just a random slot). There's a small chance we'll get lucky and the // lock will be free by the time we try to take it, but usually we'll just // fail to grab the lock, throw an appropriate lock exception, and get back // on the right path to retry later. return $slot_lock; }