/** * @param $_project_id */ protected function _tryToCloseProject($_project_id) { $project_totals = array(); $project_totals['project_segments'] = $this->_queueHandler->getRedisClient()->get(RedisKeys::PROJECT_TOT_SEGMENTS . $_project_id); $project_totals['num_analyzed'] = $this->_queueHandler->getRedisClient()->get(RedisKeys::PROJECT_NUM_SEGMENTS_DONE . $_project_id); $project_totals['eq_wc'] = $this->_queueHandler->getRedisClient()->get(RedisKeys::PROJ_EQ_WORD_COUNT . $_project_id) / 1000; $project_totals['st_wc'] = $this->_queueHandler->getRedisClient()->get(RedisKeys::PROJ_ST_WORD_COUNT . $_project_id) / 1000; $this->_doLog("--- (Worker {$this->_workerPid}) : count segments in project {$_project_id} = " . $project_totals['project_segments'] . ""); $this->_doLog("--- (Worker {$this->_workerPid}) : Analyzed segments in project {$_project_id} = " . $project_totals['num_analyzed'] . ""); if (empty($project_totals['project_segments'])) { $this->_doLog("--- (Worker {$this->_workerPid}) : WARNING !!! error while counting segments in projects {$_project_id} skipping and continue "); return; } if ($project_totals['project_segments'] - $project_totals['num_analyzed'] == 0 && $this->_queueHandler->getRedisClient()->setnx(RedisKeys::PROJECT_ENDING_SEMAPHORE . $_project_id, 1)) { $this->_queueHandler->getRedisClient()->expire(RedisKeys::PROJECT_ENDING_SEMAPHORE . $_project_id, 60 * 60 * 24); $_analyzed_report = getProjectSegmentsTranslationSummary($_project_id); $total_segs = array_pop($_analyzed_report); //remove Rollup $this->_doLog("--- (Worker {$this->_workerPid}) : analysis project {$_project_id} finished : change status to DONE"); changeProjectStatus($_project_id, \Constants_ProjectStatus::STATUS_DONE); changeTmWc($_project_id, $project_totals['eq_wc'], $project_totals['st_wc']); /* * Remove this job from the project list */ $this->_queueHandler->getRedisClient()->lrem($this->_mySubscribedQueue->redis_key, 0, $_project_id); $this->_doLog("--- (Worker {$this->_workerPid}) : trying to initialize job total word count."); foreach ($_analyzed_report as $job_info) { $counter = new \WordCount_Counter(); $counter->initializeJobWordCount($job_info['id_job'], $job_info['password']); } } }
/** * @param $pid * * @return int */ protected function _myProcessExists($pid) { return $this->_queueHandler->getRedisClient()->sismember($this->_executionContext->pid_set_name, $pid); }
/** * Process deletion/killing * * <ul> * <li>Kill a specific Process ID from a specific Queue when $pid and $queueInfo are passed</li> * <li>Kill a specific Process ID un unknown Queue when only $pid is passed</li> * <li>Kill a certain number of processes from a queue when $num and $queueInfo are passed</li> * <li>Kill all processes from a queue when only the $queueInfo is passed</li> * <li>Kill a number of elements equally from all queues when only $num is passed</li> * <li>Kill ALL processes when no parameters are sent</li> * </ul> * * @param Context $queueInfo * @param int $pid * @param int $num */ protected function _killPids(Context $queueInfo = null, $pid = 0, $num = 0) { self::_TimeStampMsg("Request to kill some processes."); self::_TimeStampMsg("Pid List: " . @var_export($queueInfo->pid_set_name, true)); self::_TimeStampMsg("Pid: " . @var_export($pid, true)); self::_TimeStampMsg("Num: " . @var_export($num, true)); $numDeleted = 0; if (!empty($pid) && !empty($queueInfo)) { self::_TimeStampMsg("Killing pid {$pid} from " . $queueInfo->pid_set_name); $numDeleted += $this->_queueHandler->getRedisClient()->srem($queueInfo->pid_set_name, $pid); posix_kill($pid, SIGINT); $queueInfo->pid_list_len = $this->_queueHandler->getRedisClient()->decr($queueInfo->queue_name); } elseif (!empty($pid) && empty($queueInfo)) { self::_TimeStampMsg("Killing pid {$pid} from a not defined queue. Seek and destroy."); /** * @var $queue Context */ foreach ($this->_queueContextList->list as $queue) { $deleted = $this->_queueHandler->getRedisClient()->srem($queue->pid_set_name, $pid); if ($deleted) { posix_kill($pid, SIGINT); $queue->pid_list_len = $this->_queueHandler->getRedisClient()->decr($queue->queue_name); self::_TimeStampMsg("Found. Killed pid {$pid} from queue {$queue->queue_name}."); } $numDeleted += $deleted; } } elseif (!empty($num) && !empty($queueInfo)) { self::_TimeStampMsg("Killing {$num} pid from " . $queueInfo->pid_set_name); $queueBefore = $this->_queueHandler->getRedisClient()->scard($queueInfo->pid_set_name); for ($i = 0; $i < $num; $i++) { $pid = $this->_queueHandler->getRedisClient()->spop($queueInfo->pid_set_name); posix_kill($pid, SIGINT); $queueInfo->pid_list_len = $this->_queueHandler->getRedisClient()->decr($queueInfo->queue_name); } $queueAfter = $this->_queueHandler->getRedisClient()->scard($queueInfo->pid_set_name); $numDeleted = $queueBefore - $queueAfter; } elseif (!empty($queueInfo)) { self::_TimeStampMsg("Killing all processes from " . $queueInfo->pid_set_name); $numDeleted = $this->_queueHandler->getRedisClient()->scard($queueInfo->pid_set_name); $pid_list = $this->_queueHandler->getRedisClient()->smembers($queueInfo->pid_set_name); foreach ($pid_list as $pid) { posix_kill($pid, SIGINT); } $this->_queueHandler->getRedisClient()->del($queueInfo->pid_set_name); $this->_queueHandler->getRedisClient()->del($queueInfo->queue_name); $queueInfo->pid_list_len = 0; } elseif (!empty($num)) { self::_TimeStampMsg("Killing {$num} processes balancing all queues."); while (true) { // if all queues are empty or they have less elements than requested $num //we do not want an infinite loop //so, at least one deletion per cycle $deleted = false; foreach ($this->_queueContextList->list as $queue) { //Exit, we reached the right number, exit the while loop if ($numDeleted >= $num) { break 2; //exit the while loop } $_deleted = false; if ($queue->max_executors < $queue->pid_list_len) { //ok, queue can be reduced because it's upper limit exceed the max queue consumers $_deleted = $this->_queueHandler->getRedisClient()->spop($queue->pid_set_name); if ($_deleted) { $queue->pid_list_len = $this->_queueHandler->getRedisClient()->decr($queue->queue_name); posix_kill($_deleted, SIGINT); } } //we do not want an infinite loop //so, at least one deletion per cycle $deleted = $_deleted || $deleted; $numDeleted += (int) (bool) $_deleted; } //no more processes to kill!! Avoid infinite loop if (!$deleted) { break; } } } elseif (empty($queueInfo) && empty($pid) && empty($num)) { self::_TimeStampMsg("Killing ALL processes."); foreach ($this->_queueContextList->list as $queue) { $numDeleted += $this->_queueHandler->getRedisClient()->scard($queue->pid_set_name); $pid_list = $this->_queueHandler->getRedisClient()->smembers($queue->pid_set_name); foreach ($pid_list as $pid) { posix_kill($pid, SIGINT); } $this->_queueHandler->getRedisClient()->del($queue->pid_set_name); $this->_queueHandler->getRedisClient()->set($queue->queue_name, 0); $queue->pid_list_len = 0; } } else { self::_TimeStampMsg("Parameters not valid. Killing *** NONE ***"); } $this->_runningPids -= $numDeleted; self::_TimeStampMsg("Deleted {$numDeleted} processes."); }