예제 #1
0
void JobAf::v_action( Action & i_action)
{
	// If action has blocks ids array - action to for blocks
	if( i_action.data->HasMember("block_ids") || i_action.data->HasMember("block_mask"))
	{
		std::vector<int32_t> block_ids;

		// Try to get block ids from array:
		const JSON & j_block_ids = (*i_action.data)["block_ids"];
		if( j_block_ids.IsArray())
			af::jr_int32vec("block_ids", block_ids, *i_action.data);

		// -1 id is specified = all blocks
		if(( block_ids.size() == 1 ) && ( block_ids[0] == -1 ))
		{
			block_ids.clear();
			for( int b = 0; b < m_blocks_num; b++)
				block_ids.push_back( m_blocks[b]->m_data->getBlockNum());
		}

		// Try to fill ids from mask:
		const JSON & j_block_mask = (*i_action.data)["block_mask"];
		if( j_block_mask.IsString())
		{
			std::string mask;
			af::jr_string("block_mask", mask, *i_action.data);
			af::RegExp re;
			std::string re_err;
			if( false == re.setPattern( mask, &re_err))
			{
				appendLog("Invalid block mask = " + mask + " from " + i_action.author);
				return;
			}
			for( int b = 0; b < m_blocks_num; b++)
				if( re.match( m_blocks[b]->m_data->getName()))
					block_ids.push_back( m_blocks[b]->m_data->getBlockNum());
		}

		if( block_ids.empty())
		{
			appendLog("\"block_ids\" array does not contain any integers or invalid \"block_mask\" from " + i_action.author);
			return;
		}

		bool job_progress_changed = false;
		for( int b = 0; b < block_ids.size(); b++)
		{
			if(( block_ids[b] >= getBlocksNum()) || ( block_ids[b] < 0 ))
			{
				appendLog("Invalid block number = " + af::itos(block_ids[b]) + " " + i_action.author);
				continue;
			}
			if( m_blocks[block_ids[b]]->action( i_action))
				job_progress_changed = true;
		}

		if( job_progress_changed )
			i_action.monitors->addJobEvent( af::Monitor::EVT_jobs_change, getId(), getUid());

		if( i_action.log.size() )
			store();

		return;
	}

	const JSON & operation = (*i_action.data)["operation"];
	if( operation.IsObject())
	{
		std::string type;
		af::jr_string("type", type, operation);
		if( type == "delete")
		{
			if( m_id == AFJOB::SYSJOB_ID )
			{
				appendLog("System job can't be deleted by " + i_action.author);
				return;
			}
			appendLog("Deleted by " + i_action.author);
			m_user->appendLog( "Job \"" + m_name + "\" deleted by " + i_action.author);
			deleteNode( i_action.renders, i_action.monitors);
			i_action.monitors->addJobEvent( af::Monitor::EVT_jobs_del, getId(), getUid());
			return;
		}
		else if( type == "start")
		{
			m_state = m_state & (~AFJOB::STATE_OFFLINE_MASK);
		}
		else if( type == "pause")
		{
			m_state = m_state | AFJOB::STATE_OFFLINE_MASK;
		}
		else if( type == "stop")
		{
		   restartAllTasks("Job stopped by " + i_action.author, i_action.renders, i_action.monitors, AFJOB::STATE_RUNNING_MASK);
		   m_state = m_state | AFJOB::STATE_OFFLINE_MASK;
		}
		else if( type == "restart_running")
		{
			restartAllTasks("Job restarted running by " + i_action.author,  i_action.renders, i_action.monitors, AFJOB::STATE_RUNNING_MASK);
		}
		else if( type == "restart_skipped")
		{
			restartAllTasks("Job restarted skipped by " + i_action.author,  i_action.renders, i_action.monitors, AFJOB::STATE_SKIPPED_MASK);
		}
		else if( type == "restart_done")
		{
			restartAllTasks("Job restarted done by " + i_action.author,  i_action.renders, i_action.monitors, AFJOB::STATE_DONE_MASK);
		}
		else if( type == "reset_error_hosts")
		{
			for( int b = 0; b < m_blocks_num; b++)
				m_blocks[b]->action( i_action);
		}
		else if( type == "restart")
		{
			//printf("Msg::TJobRestart:\n");
			restartAllTasks("Job restarted by " + i_action.author,  i_action.renders, i_action.monitors);
			//printf("Msg::TJobRestart: tasks restarted.\n");
			checkDepends();
			m_time_started = 0;
		}
		else if( type == "restart_errors")
		{
			restartAllTasks("Job errors restarted by " + i_action.author,  i_action.renders, i_action.monitors, AFJOB::STATE_ERROR_MASK);
		}
		else if( type == "restart_pause")
		{
			restartAllTasks("Job restarted ( and paused ) by " + i_action.author,  i_action.renders, i_action.monitors);
			checkDepends();
			m_state = m_state | AFJOB::STATE_OFFLINE_MASK;
			m_time_started = 0;
		}
		else
		{
			appendLog("Unknown operation \"" + type + "\" by " + i_action.author);
			return;
		}
		appendLog("Operation \"" + type + "\" by " + i_action.author);
		i_action.monitors->addJobEvent( af::Monitor::EVT_jobs_change, getId(), getUid());
		store();
		return;
	}

	// Store user name before parameters read, to check whether it changed
	const std::string user_name = m_user_name;

	const JSON & params = (*i_action.data)["params"];
	if( params.IsObject())
		jsonRead( params, &i_action.log);

	if( m_user_name != user_name )
	{
		// User name was changed
		UserAf * user = i_action.users->getUser( m_user_name);
		if( user == NULL )
		{
			return;
		}
		
		i_action.monitors->addEvent(    af::Monitor::EVT_users_change, m_user->getId());
		i_action.monitors->addJobEvent( af::Monitor::EVT_jobs_del, getId(), m_user->getId());
		
		m_user->removeJob( this);
		user->addJob( this);
		
		i_action.monitors->addEvent(    af::Monitor::EVT_users_change, m_user->getId());
		i_action.monitors->addJobEvent( af::Monitor::EVT_jobs_add, getId(), m_user->getId());
		
		store();

		return;
	}

	if( i_action.log.size() )
	{
		store();
		i_action.monitors->addJobEvent( af::Monitor::EVT_jobs_change, getId(), getUid());
	}
}
예제 #2
0
bool JobContainer::registerJob( JobAf *job, std::string & o_err, UserContainer *users, MonitorContainer * monitoring)
{
	if( job == NULL )
	{
		AF_ERR << "JobContainer::registerJob: Can't allocate memory for a new job.";
		return false;
	}

	if( users == NULL )
	{
		AF_ERR << "JobContainer::registerJob: Users container is not set.";
		delete job;
		return false;
	}

	// Job from store is already checked for validness
	if(( job->isFromStore() == false ) && (job->isValidConstructed() == false ))
	{
		o_err = "Invalid job.";
		delete job;
		return false;
	}

	UserAf *user;

	{  // Register new user if job has a new user name.
		AfContainerLock jLock( this, AfContainerLock::WRITELOCK);
		AfContainerLock uLock( users, AfContainerLock::WRITELOCK  );

		if( monitoring) AfContainerLock mLock( monitoring, AfContainerLock::WRITELOCK  );

		AF_DEBUG << "JobContainer::registerJob: Checking job user: "******"JobContainer::registerJob: Can't register new user.";
			return false;
		}

		// Add job node to container.
		if( add( job) == false )
		{
			delete job;
			o_err = "JobContainer::registerJob: Can't add job to container.";
			return false;
		}
		AF_DEBUG << "JobContainer::registerJob: locking job.";
		job->lock();

		AF_DEBUG << "JobContainer::registerJob: locking user.";
		user->lock();
		user->addJob( job);
		if( monitoring )
		{
			AF_DEBUG << "JobContainer::registerJob: monitor new job events.";
			monitoring->addJobEvent( af::Monitor::EVT_jobs_add, job->getId(), user->getId());
			monitoring->addEvent( af::Monitor::EVT_users_change, user->getId());
		}
	}

	// initialize job ( create tasks output root_dir, execute "pre"commands if any)
	AF_DEBUG << "JobContainer::registerJob: initiaizing new job with user.";
	if( job->initialize() == false)
	{
		AF_DEBUG << "JobContainer::registerJob: Job initialization failed.";

		if( monitoring )
		{
			AfContainerLock mLock( monitoring,  AfContainerLock::WRITELOCK  );

			monitoring->addJobEvent( af::Monitor::EVT_jobs_del, job->getId(), user->getId());
			monitoring->addEvent( af::Monitor::EVT_users_change, user->getId());
		}

		{   // Set job to zombie:
			AfContainerLock jLock( this, AfContainerLock::WRITELOCK);
			AfContainerLock uLock( users, AfContainerLock::WRITELOCK);
			user->unLock();
			job->deleteNode( NULL, NULL);
		}

		return false;
	}

	if( monitoring )
	{
		AfContainerLock mLock( monitoring,  AfContainerLock::WRITELOCK  );

		AF_DEBUG << "JobContainer::registerJob: monitor unlock job and user events.";
		monitoring->addJobEvent( af::Monitor::EVT_jobs_change, job->getId(), user->getId());
		monitoring->addEvent( af::Monitor::EVT_users_change, user->getId());
	}

	AF_DEBUG << "JobContainer::registerJob: unlocking user and job.";

	{
		AfContainerLock jLock( this,  AfContainerLock::WRITELOCK);
		AfContainerLock uLock( users, AfContainerLock::WRITELOCK);
		user->unLock();
		job->unLock();
	}

	AFCommon::QueueLog("Job registered: " + job->v_generateInfoString());

	return true;
}