/** * will return $max_count of objects using the peer. * The criteria will be used to filter the basic parameter, the function will encapsulate the inner logic of the BatchJob * and the exclusiveness. * * @param Criteria $c */ private static function getExclusive(Criteria $c, kExclusiveLockKey $lockKey, $max_execution_time, $number_of_objects, $jobType, $maxOffset = null) { $schd = BatchJobLockPeer::SCHEDULER_ID; $work = BatchJobLockPeer::WORKER_ID; $btch = BatchJobLockPeer::BATCH_INDEX; $stat = BatchJobLockPeer::STATUS; $atmp = BatchJobLockPeer::EXECUTION_ATTEMPTS; $expr = BatchJobLockPeer::EXPIRATION; $recheck = BatchJobLockPeer::START_AT; $partnerLoadQuota = PartnerLoadPeer::QUOTA; $schd_id = $lockKey->getSchedulerId(); $work_id = $lockKey->getWorkerId(); $btch_id = $lockKey->getBatchIndex(); $now = time(); $now_str = date('Y-m-d H:i:s', $now); $delayedJobTypes = kConf::get('delayed_job_types'); $apiJobType = kPluginableEnumsManager::coreToApi('BatchJobType', $jobType); // added to support nfs delay if (in_array($apiJobType, $delayedJobTypes)) { $interval = kConf::hasParam('nfs_safety_margin_sec') ? kConf::get('nfs_safety_margin_sec') : 5; $c->add(BatchJobLockPeer::CREATED_AT, time() - $interval, Criteria::LESS_THAN); } $c->add(BatchJobLockPeer::JOB_TYPE, $jobType); $c->add(BatchJobLockPeer::DC, kDataCenterMgr::getCurrentDcId()); $c->add(BatchJobLockPeer::BATCH_VERSION, BatchJobLockPeer::getBatchVersion($jobType), Criteria::LESS_EQUAL); $prioritizers_ratio = BatchJobLockPeer::getPrioritizersRatio($jobType); $shouldUseJoin = BatchJobLockPeer::getMaxJobsForPartner($jobType) != self::UNLIMITED_QUOTA; self::addPrioritizersCondition($c, $prioritizers_ratio, $shouldUseJoin); // Query Parts $unClosedStatuses = implode(',', BatchJobPeer::getUnClosedStatusList()); $statusCondition = "{$stat} IN ({$unClosedStatuses})"; $lockExpiredCondition = "{$expr} <= '{$now_str}'"; $pendingJobsCondition = "( {$stat} = " . BatchJob::BATCHJOB_STATUS_PENDING . " OR ( {$stat} = " . BatchJob::BATCHJOB_STATUS_RETRY . " AND {$recheck} <= '{$now_str}' ))"; $unhandledJobCondition = "{$schd} IS NULL AND {$work} IS NULL AND {$btch} IS NULL "; $newJobsCond = "({$pendingJobsCondition} AND ({$unhandledJobCondition}))"; if ($shouldUseJoin) { $partnerLoadCondition = "(({$partnerLoadQuota} > 0) OR ({$partnerLoadQuota} is null))"; $newJobsCond .= " AND {$partnerLoadCondition}"; } $jobAlreadyHandledByWorker = "{$schd} = {$schd_id} AND {$work} = {$work_id} AND {$btch} = {$btch_id}"; $max_exe_attempts = BatchJobLockPeer::getMaxExecutionAttempts($jobType); $jobWasntExecutedTooMany = "{$atmp} <= {$max_exe_attempts} OR {$atmp} IS NULL"; // Generate query $query = "\t{$statusCondition}\n\t\t\t\t\tAND\t(\n\t\t\t\t\t\t{$lockExpiredCondition}\n\t\t\t\t\t\tOR\t({$newJobsCond})\n\t\t\t\t\t\tOR ({$jobAlreadyHandledByWorker})\n\t\t\t\t\t)\n\t\t\t\t\tAND ({$jobWasntExecutedTooMany})"; $c->add($stat, $query, Criteria::CUSTOM); // In case maxOffset isn't null, we want to take the chunk out of a random offset in between. // That's usefull for load handling if ($maxOffset) { $c->setOffset(rand(0, $maxOffset)); } $c->setLimit($number_of_objects); $objects = BatchJobLockPeer::doSelect($c, myDbHelper::getConnection(myDbHelper::DB_HELPER_CONN_PROPEL2)); return self::lockObjects($lockKey, $objects, $max_execution_time); }