Beispiel #1
0
UserAf * UserContainer::getUser( const std::string & i_name )
{
    UserContainerIt usersIt( ms_users);
    for(UserAf * user = usersIt.user(); user != NULL; usersIt.next(), user = usersIt.user())
    {
        if( user->getName() == i_name )
            return user;
    }
    return NULL;
}
Beispiel #2
0
RenderAf * BranchSrv::v_solve(std::list<RenderAf*> & i_renders_list, MonitorContainer * i_monitoring, BranchSrv * i_branch)
{
	std::list<AfNodeSolve*> solve_list;

	if (m_branches_num)
	{
		// Iterate child branches
		AfListIt it(&m_branches_list);
		for (AfNodeSolve * node = it.node(); node != NULL; it.next(), node = it.node())
		{
			if (false == node->canRun())
				continue;

			node->calcNeed(m_solving_flags);

			solve_list.push_back(node);
		}
	}

	if (isSolveJobs() && m_jobs_num)
	{
		// Iterate child jobs
		AfListIt it(&m_jobs_list);
		for (AfNodeSolve * node = it.node(); node != NULL; it.next(), node = it.node())
		{
			if (false == node->canRun())
				continue;

			node->calcNeed(m_solving_flags);

			solve_list.push_back(node);
		}
	}
	else if(m_users.size())
	{
		std::map<UserAf*,BranchSrvUserData*>::iterator it = m_users.begin();
		for(; it != m_users.end(); it++)
		{
			UserAf * user = (*it).first;
			if (false == user->canRun())
				continue;

			if (isSolveCapacity())
				user->calcNeed(-1,(*it).second->running_capacity_total);
			else
				user->calcNeed(-1,(*it).second->running_tasks_num);

			solve_list.push_back(user);
		}
	}

	Solver::SortList(solve_list, m_solving_flags);

	return Solver::SolveList(solve_list, i_renders_list, this);
}
Beispiel #3
0
af::Msg* UserContainer::generateJobsList( int id)
{
   UserContainerIt usersIt( this);
   UserAf* user = usersIt.getUser( id);
   if( user == NULL) return NULL;

   MCAfNodes mcjobs;
   user->jobsinfo( mcjobs);

   return new af::Msg( af::Msg::TJobsList, &mcjobs);
}
Beispiel #4
0
UserAf* UserContainer::addUser( const std::string & username, const std::string & hostname, MonitorContainer * monitoring)
{
   {
      UserContainerIt usersIt( this);
      for(UserAf *user = usersIt.user(); user != NULL; usersIt.next(), user = usersIt.user())
      {
         if( username == user->getName())
         {
            if( user->getHostName() != hostname)
            {
               user->setHostName( hostname);
               if( monitoring) monitoring->addEvent( af::Msg::TMonitorUsersChanged, user->getId());
            }
            return user;
         }
      }
   }

   UserAf *user = new UserAf( username, hostname);
   if( addUser(user) == 0)
   {
      AFERROR("UserContainer::addUser: Can't add user to container.\n");
      delete user;
      return NULL;
   }

   if( monitoring) monitoring->addEvent( af::Msg::TMonitorUsersAdd, user->getId());

   AFCommon::QueueLog("User registered: " + user->v_generateInfoString( false));
   return user;
}
Beispiel #5
0
UserAf* UserContainer::addUser( const std::string & i_usernmae, const std::string & i_hostname, MonitorContainer * i_monitoring)
{
	{
		UserContainerIt usersIt( this);
		for(UserAf *user = usersIt.user(); user != NULL; usersIt.next(), user = usersIt.user())
		{
			if( i_usernmae == user->getName())
			{
				if( user->getHostName() != i_hostname)
				{
					user->setHostName( i_hostname);
					if( i_monitoring) i_monitoring->addEvent( af::Monitor::EVT_users_change, user->getId());
				}
				return user;
			}
		}
	}

	UserAf *user = new UserAf( i_usernmae, i_hostname);
	if( addUser(user) == 0)
	{
		AFERROR("UserContainer::addUser: Can't add user to container.\n");
		delete user;
		return NULL;
	}

	if( i_monitoring) i_monitoring->addEvent( af::Monitor::EVT_users_add, user->getId());

	AFCommon::QueueLog("New job user registered: " + user->v_generateInfoString( false));
	return user;
}
Beispiel #6
0
af::Msg* UserContainer::generateJobsList( const std::vector<int32_t> & ids,
	const std::string & i_type_name, bool json)
{
	UserContainerIt usersIt( this);
	MCAfNodes mcjobs;
	std::ostringstream stream;
	bool has_jobs = false;

	if( json )
	{
		stream << "{\"" << i_type_name << "\":[\n";
	}

	for( int i = 0; i < ids.size(); i++)
	{
		UserAf* user = usersIt.getUser( ids[i]);
		if( user == NULL) continue;
		if( json )
		{
			if(( i != 0 ) && ( has_jobs ))
				stream << ",\n";
			has_jobs = user->getJobs( stream);
		}
		else
			user->jobsinfo( mcjobs);
	}

	if( json )
	{
		stream << "\n]}";
		return af::jsonMsg( stream);
	}

	af::Msg * msg = new af::Msg();
	msg->set( af::Msg::TJobsList, &mcjobs);
	return msg;
}
Beispiel #7
0
af::Msg * UserContainer::addUser( UserAf * i_user, MonitorContainer * i_monitoring)
{
	UserContainerIt usersIt( this);
	for(UserAf *user = usersIt.user(); user != NULL; usersIt.next(), user = usersIt.user())
	{
		if( user->getName() == i_user->getName())
		{
			AFERRAR("UserContainer::addUser: User \"%s\" already exists.", i_user->getName().c_str());
			delete i_user;
			std::ostringstream str;
			str << "{\"error\":\"exists\"";
			str << ",\n\"user\":\n";
			user->v_jsonWrite( str, /*type no matter*/ 0);
			str << "\n}";
			return af::jsonMsg( str);
		}
	}

	if( addUser( i_user) == 0)
	{
		AFERRAR("UserContainer::addUser: Can't add user \"%s\" node to container.", i_user->getName().c_str());
		delete i_user;
		return af::jsonMsgError("Unable to add node to container.");
	}

//AFCommon::QueueDBAddItem( i_user);
	i_user->store();
	if( i_monitoring) i_monitoring->addEvent( af::Monitor::EVT_users_add, i_user->getId());

	AFCommon::QueueLog("User registered: " + i_user->v_generateInfoString( false));

	std::ostringstream str;
	str << "{\"user\":\n";
	i_user->v_jsonWrite( str, /*type no matter*/ 0);
	str << "\n}";
	return af::jsonMsg( str);
}
Beispiel #8
0
void UserContainer::setPermanent( const af::MCGeneral & usr, bool permanent, MonitorContainer * monitoring)
{
   std::string username( usr.getName());
   std::string hostname( usr.getHostName());

   //
   // Try to find user with provided name in container to edit permanent property
   //
   UserContainerIt usersIt( this);
   for(UserAf *user = usersIt.user(); user != NULL; usersIt.next(), user = usersIt.user())
   {
      if( username == user->getName())
      {
         bool changed = false;
         if( user->getHostName() != hostname )
         {
            user->setHostName( hostname);
            changed = true;
         }

         // set permanent property if it differ
         if( user->isPermanent() != permanent)
         {
            changed = true;
            user->setPermanent( permanent);
            if( permanent) AFCommon::QueueDBAddItem( user);
            else AFCommon::QueueDBDelItem( user);
         }

         if( changed && monitoring)
         {
            monitoring->addEvent( af::Msg::TMonitorUsersChanged, user->getId());
         }

         // return if user exists in container
         return;
      }
   }
   //
   //    User with provided name does not exist container
   //
   if( permanent == false)
   {
      // Error: user to unset permanent does not exist
      AFERRAR("UserContainer::setPermanent: No user \"%s\" founded.\n", username.c_str());
      return;
   }
   //
   //    Create a new permanent user and put him to database
   //
   UserAf *user = new UserAf( username, hostname);
   if( addUser( user) == 0)
   {
      delete user;
      AFERRAR("UserContainer::setPermanent: Can't add user \"%s\" node to container.", username.c_str());
      return;
   }
   user->setPermanent( true);
   AFCommon::QueueDBAddItem( user);
   if( monitoring) monitoring->addEvent( af::Msg::TMonitorUsersAdd, user->getId());
   return;
}
Beispiel #9
0
void UserContainer::logAction( const Action & i_action, const std::string & i_node_name)
{
	UserAf * user = getUser( i_action.user_name);
	if( user )
		user->logAction( i_action, i_node_name);
}
Beispiel #10
0
void UserContainer::updateTimeActivity( const std::string & i_name)
{
	UserAf * user = getUser( i_name);
	if( user )
		user->updateTimeActivity();
}
af::Msg* threadProcessMsgCase( ThreadArgs * i_args, af::Msg * i_msg)
{
    //i_msg->stdOut();
    //printf("IM=%d LM=%d MM=%d\n", i_msg->getMagicNumber(), af::Msg::Magic, af::Environment::getMagicMode());
    af::Msg * o_msg_response = NULL;

    switch( i_msg->type())
    {
    case af::Msg::TVersionMismatch:
    {
        AFCommon::QueueLogError( i_msg->v_generateInfoString( false));
        o_msg_response = new af::Msg( af::Msg::TVersionMismatch, 1);
        break;
    }
    case af::Msg::TMagicMismatch:
    {
        std::string err = "Magick number mismatch: recieved ";
        err += af::itos( i_msg->getMagicNumber()) + " != " + af::itos( af::Msg::Magic) += " local.";
        AFCommon::QueueLogError( err);
        o_msg_response = new af::Msg( af::Msg::TMagicMismatch, 1);
        break;
    }
    case af::Msg::TMagicNumber:
    {
        std::string msg = "Magick Number " + af::itos( af::Msg::Magic)
                          + " changed to " + af::itos( i_msg->int32());
        AFCommon::QueueLog( msg);
        o_msg_response = new af::Msg();
        o_msg_response->setString( msg);
        af::Msg::Magic = i_msg->int32();
        break;
    }
    case af::Msg::TInvalid:
    {
        AFCommon::QueueLogError( std::string("Invalid message recieved: ") + i_msg->v_generateInfoString( false));
        break;
    }
    case af::Msg::TNULL:
    case af::Msg::TDATA:
    case af::Msg::TTESTDATA:
    case af::Msg::TStringList:
    {
        i_msg->stdOutData();
        break;
    }
    case af::Msg::THTTP:
    case af::Msg::TJSON:
    {
        return threadProcessJSON( i_args, i_msg);
    }
    case af::Msg::TString:
    {
        std::string str = i_msg->getString();
        if( str.empty()) break;

        AFCommon::QueueLog( str);
        AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK);
        i_args->monitors->sendMessage( str);
        break;
    }
    case af::Msg::TStatRequest:
    {
        o_msg_response = new af::Msg;
        af::statwrite( o_msg_response);
        break;
    }
    case af::Msg::TConfirm:
    {
        printf("Thread process message: Msg::TConfirm: %d\n", i_msg->int32());
        i_args->msgQueue->pushMsg( new af::Msg( af::Msg::TConfirm, 1));
        o_msg_response = new af::Msg( af::Msg::TConfirm, 1 - i_msg->int32());
        break;
    }
    case af::Msg::TConfigLoad:
    {
        AfContainerLock jlock( i_args->jobs,	 AfContainerLock::WRITELOCK);
        AfContainerLock rlock( i_args->renders, AfContainerLock::WRITELOCK);
        AfContainerLock tlock( i_args->talks,	AfContainerLock::WRITELOCK);
        AfContainerLock ulock( i_args->users,	AfContainerLock::WRITELOCK);
        printf("\n	========= RELOADING CONFIG =========\n\n");
        std::string message;
        if( af::Environment::reload())
        {
            message = "Reloaded successfully.";
            printf("\n	========= CONFIG RELOADED SUCCESSFULLY =========\n\n");
        }
        else
        {
            message = "Failed, see server logs fo details.";
            printf("\n	========= CONFIG RELOADING FAILED =========\n\n");
        }
        o_msg_response = new af::Msg();
        o_msg_response->setString( message);
        break;
    }
    case af::Msg::TFarmLoad:
    {
        AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK);
        AfContainerLock rlock( i_args->renders,  AfContainerLock::WRITELOCK);

        printf("\n	========= RELOADING FARM =========\n\n");
        std::string message;
        if( af::loadFarm( true))
        {
            RenderContainerIt rendersIt( i_args->renders);
            for( RenderAf *render = rendersIt.render(); render != NULL; rendersIt.next(), render = rendersIt.render())
            {
                render->getFarmHost();
                i_args->monitors->addEvent( af::Msg::TMonitorRendersChanged, render->getId());
            }
            message = "Reloaded successfully.";
            printf("\n	========= FARM RELOADED SUCCESSFULLY =========\n\n");
        }
        else
        {
            message = "Failed, see server logs fo details. Check farm with \"afcmd fcheck\" at first.";
            printf("\n	========= FARM RELOADING FAILED =========\n\n");
        }
        o_msg_response = new af::Msg();
        o_msg_response->setString( message);
        break;
    }

// ---------------------------------- Monitor ---------------------------------//
    case af::Msg::TMonitorRegister:
    {
        AfContainerLock lock( i_args->monitors, AfContainerLock::WRITELOCK);

        MonitorAf * newMonitor = new MonitorAf( i_msg);
        newMonitor->setAddressIP( i_msg->getAddress());
        o_msg_response = i_args->monitors->addMonitor( newMonitor);
        break;
    }
    case af::Msg::TMonitorUpdateId:
    {
        AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK);

        if( i_args->monitors->updateId( i_msg->int32()))
        {
            o_msg_response = new af::Msg( af::Msg::TMonitorId, i_msg->int32());
        }
        else
        {
            o_msg_response = new af::Msg( af::Msg::TMonitorId, 0);
        }
        break;
    }
    case af::Msg::TMonitorsListRequest:
    {
        AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK);

        o_msg_response = i_args->monitors->generateList( af::Msg::TMonitorsList);
        break;
    }
    case af::Msg::TMonitorsListRequestIds:
    {
        AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK);

        af::MCGeneral ids( i_msg);
        o_msg_response = i_args->monitors->generateList( af::Msg::TMonitorsList, ids);
        break;
    }
    case af::Msg::TMonitorLogRequestId:
    {
        AfContainerLock lock( i_args->monitors,  AfContainerLock::READLOCK);

        MonitorContainerIt it( i_args->monitors);
        MonitorAf* node = it.getMonitor( i_msg->int32());
        if( node == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg();
        o_msg_response->setStringList( node->getLog());
        break;
    }

// ---------------------------------- Talk ---------------------------------//
    case af::Msg::TTalkRegister:
    {
        AfContainerLock mlock( i_args->monitors, AfContainerLock::WRITELOCK);
        AfContainerLock tlock( i_args->talks,	 AfContainerLock::WRITELOCK);

        TalkAf * newTalk = new TalkAf( i_msg);
        newTalk->setAddressIP( i_msg->getAddress());
        o_msg_response = i_args->talks->addTalk( newTalk, i_args->monitors);
        break;
    }
    case af::Msg::TTalksListRequest:
    {
        AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK);

        o_msg_response = i_args->talks->generateList( af::Msg::TTalksList);
        break;
    }
    case af::Msg::TTalksListRequestIds:
    {
        AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK);

        af::MCGeneral ids( i_msg);
        o_msg_response = i_args->talks->generateList( af::Msg::TTalksList, ids);
        break;
    }
    case af::Msg::TTalkUpdateId:
    {
        AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK);

        if( i_args->talks->updateId( i_msg->int32()))
        {
            o_msg_response = i_args->talks->generateList( af::Msg::TTalksList);
        }
        else
        {
            o_msg_response = new af::Msg( af::Msg::TTalkId, 0);
        }
        break;
    }
    case af::Msg::TTalkDistributeData:
    {
        AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK);

        i_args->talks->distributeData( i_msg);
        break;
    }

// ---------------------------------- Render -------------------------------//
    case af::Msg::TRenderRegister:
    {
//printf("case af::Msg::TRenderRegister:\n");
        AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK);
        AfContainerLock rLock( i_args->renders,  AfContainerLock::WRITELOCK);

        RenderAf * newRender = new RenderAf( i_msg);
        newRender->setAddressIP( i_msg->getAddress());
        o_msg_response = i_args->renders->addRender( newRender, i_args->monitors);
        break;
    }
    case af::Msg::TRenderUpdate:
    {
//printf("case af::Msg::TRenderUpdate:\n");
        AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK);

        af::Render render_up( i_msg);
//printf("Msg::TRenderUpdate: %s - %s\n", render_up.getName().toUtf8().data(), time2Qstr( time(NULL)).toUtf8().data());
        RenderContainerIt rendersIt( i_args->renders);
        RenderAf* render = rendersIt.getRender( render_up.getId());

        int id = 0;
        // If there is not such render, a zero id will be send.
        // It is a signal for client to register again (may be server was restarted).
        if((render != NULL) && ( render->update( &render_up)))
        {
            id = render->getId();
        }
        o_msg_response = new af::Msg( af::Msg::TRenderId, id);
        break;
    }
    case af::Msg::TRendersListRequest:
    {
        AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK);

        o_msg_response = i_args->renders->generateList( af::Msg::TRendersList);
        break;
    }
    case af::Msg::TRendersListRequestIds:
    {
        AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK);

        af::MCGeneral ids( i_msg);
        o_msg_response = i_args->renders->generateList( af::Msg::TRendersList, ids);
        break;
    }
    case af::Msg::TRendersResourcesRequestIds:
    {
        AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK);

        af::MCGeneral ids( i_msg);
        o_msg_response = i_args->renders->generateList( af::Msg::TRendersResources, ids);
        break;
    }
    case af::Msg::TRenderLogRequestId:
    {
        AfContainerLock lock( i_args->renders,  AfContainerLock::READLOCK);

        RenderContainerIt rendersIt( i_args->renders);
        RenderAf* render = rendersIt.getRender( i_msg->int32());
        if( render == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg;
        o_msg_response->setStringList( render->getLog());
        break;
    }
    case af::Msg::TRenderTasksLogRequestId:
    {
        AfContainerLock lock( i_args->renders,  AfContainerLock::READLOCK);

        RenderContainerIt rendersIt( i_args->renders);
        RenderAf* render = rendersIt.getRender( i_msg->int32());
        if( render == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg;
        if( render->getTasksLog().empty())
        {
            o_msg_response->setString("No tasks execution log.");
        }
        else
        {
            o_msg_response->setStringList( render->getTasksLog());
        }
        break;
    }
    case af::Msg::TRenderInfoRequestId:
    {
        AfContainerLock lock( i_args->renders,  AfContainerLock::READLOCK);

        RenderContainerIt rendersIt( i_args->renders);
        RenderAf* render = rendersIt.getRender( i_msg->int32());
        if( render == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = render->writeFullInfo();
        break;
    }

// ---------------------------------- Users -------------------------------//
    case af::Msg::TUserIdRequest:
    {
        AfContainerLock lock( i_args->users, AfContainerLock::READLOCK);

        af::MsgClassUserHost usr( i_msg);
        std::string name = usr.getUserName();
        int id = 0;
        UserContainerIt usersIt( i_args->users);
        for( af::User *user = usersIt.user(); user != NULL; usersIt.next(), user = usersIt.user())
        {
            if( user->getName() == name)
            {
                id = user->getId();
            }
        }
        o_msg_response = new af::Msg( af::Msg::TUserId, id);
        break;
    }
    case af::Msg::TUsersListRequest:
    {
        AfContainerLock lock( i_args->users, AfContainerLock::READLOCK);

        o_msg_response = i_args->users->generateList( af::Msg::TUsersList);
        break;
    }
    case af::Msg::TUsersListRequestIds:
    {
        AfContainerLock lock( i_args->users, AfContainerLock::READLOCK);

        af::MCGeneral ids( i_msg);
        o_msg_response = i_args->users->generateList( af::Msg::TUsersList, ids);
        break;
    }
    case af::Msg::TUserLogRequestId:
    {
        AfContainerLock lock( i_args->users,  AfContainerLock::READLOCK);

        UserContainerIt usersIt( i_args->users);
        UserAf* user = usersIt.getUser( i_msg->int32());
        if( user == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg();
        o_msg_response->setStringList( user->getLog());
        break;
    }
    case af::Msg::TUserJobsOrderRequestId:
    {
        AfContainerLock lock( i_args->users,  AfContainerLock::READLOCK);

        UserContainerIt usersIt( i_args->users);
        UserAf* user = usersIt.getUser( i_msg->int32());
        if( user == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        af::MCGeneral ids;
        ids.setId( user->getId());
        ids.setList( user->generateJobsIds());
        o_msg_response = new af::Msg( af::Msg::TUserJobsOrder, &ids);
        break;
    }

// ------------------------------------- Job -------------------------------//
    case af::Msg::TJobRequestId:
    {
        AfContainerLock lock( i_args->jobs,  AfContainerLock::READLOCK);

        JobContainerIt jobsIt( i_args->jobs);
        JobAf* job = jobsIt.getJob( i_msg->int32());
        if( job == NULL )
        {
            o_msg_response = new af::Msg( af::Msg::TJobRequestId, 0);
            break;
        }
        o_msg_response = new af::Msg( af::Msg::TJob, job);
        break;
    }
    case af::Msg::TJobLogRequestId:
    {
        AfContainerLock lock( i_args->jobs,  AfContainerLock::READLOCK);

        JobContainerIt jobsIt( i_args->jobs);
        JobAf* job = jobsIt.getJob( i_msg->int32());
        if( job == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg();
        o_msg_response->setStringList( job->getLog());
        break;
    }
    case af::Msg::TJobErrorHostsRequestId:
    {
        AfContainerLock lock( i_args->jobs,  AfContainerLock::READLOCK);

        JobContainerIt jobsIt( i_args->jobs);
        JobAf* job = jobsIt.getJob( i_msg->int32());
        if( job == NULL )
        {   // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg();
        o_msg_response->setString( job->v_getErrorHostsListString());
        break;
    }
    case af::Msg::TJobProgressRequestId:
    {
        AfContainerLock lock( i_args->jobs,  AfContainerLock::READLOCK);

        JobContainerIt jobsIt( i_args->jobs);
        JobAf* job = jobsIt.getJob( i_msg->int32());
        if( job == NULL )
        {
            // FIXME: Send back the same message on error - is it good?
            o_msg_response = new af::Msg( af::Msg::TJobProgressRequestId, 0);
            break;
        }
        o_msg_response = new af::Msg;
        job->writeProgress( *o_msg_response);
        break;
    }
    case af::Msg::TJobsListRequest:
    {
        AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK);

        o_msg_response = i_args->jobs->generateList( af::Msg::TJobsList);
        break;
    }
    case af::Msg::TJobsListRequestIds:
    {
        AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK);

        af::MCGeneral ids( i_msg);
        o_msg_response = i_args->jobs->generateList( af::Msg::TJobsList, ids);
        break;
    }
    case af::Msg::TJobsListRequestUserId:
    {
        AfContainerLock jLock( i_args->jobs,  AfContainerLock::READLOCK);
        AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK);

        o_msg_response = i_args->users->generateJobsList( i_msg->int32());
        if( o_msg_response == NULL )
        {
            o_msg_response = new af::Msg( af::Msg::TUserId, 0);
        }
        break;
    }
    case af::Msg::TJobsListRequestUsersIds:
    {
        AfContainerLock jLock( i_args->jobs,  AfContainerLock::READLOCK);
        AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK);

        af::MCGeneral mcids( i_msg);
        std::string type_name;
        o_msg_response = i_args->users->generateJobsList( mcids.getList(), type_name);
        break;
    }
    case af::Msg::TTaskRequest:
    {
        AfContainerLock lock( i_args->jobs,  AfContainerLock::READLOCK);

        af::MCTaskPos mctaskpos( i_msg);
        JobContainerIt jobsIt( i_args->jobs);
        JobAf* job = jobsIt.getJob( mctaskpos.getJobId());
        if( job == NULL )
        {
            o_msg_response = new af::Msg();
            std::ostringstream stream;
            stream << "Msg::TTaskRequest: No job with id=" << mctaskpos.getJobId();
            o_msg_response->setString( stream.str());
            break;
        }
        af::TaskExec * task = job->generateTask( mctaskpos.getNumBlock(), mctaskpos.getNumTask());
        if( task )
        {
            o_msg_response = new af::Msg( af::Msg::TTask, task);
            delete task;
        }
        else
        {
            o_msg_response = new af::Msg();
            std::ostringstream stream;
            stream << "Msg::TTaskRequest: No such task[" << mctaskpos.getJobId() << "][" << mctaskpos.getNumBlock() << "][" << mctaskpos.getNumTask() << "]";
            o_msg_response->setString( stream.str());
        }
        break;
    }
    case af::Msg::TTaskLogRequest:
    {
        AfContainerLock lock( i_args->jobs,  AfContainerLock::READLOCK);

        af::MCTaskPos mctaskpos( i_msg);
        JobContainerIt jobsIt( i_args->jobs);
        JobAf* job = jobsIt.getJob( mctaskpos.getJobId());
        if( job == NULL )
        {
            o_msg_response = new af::Msg();
            std::ostringstream stream;
            stream << "Msg::TTaskLogRequest: No job with id=" << mctaskpos.getJobId();
            o_msg_response->setString( stream.str());
            break;
        }
        const std::list<std::string> * list = &(job->getTaskLog( mctaskpos.getNumBlock(), mctaskpos.getNumTask()));
        if( list == NULL )
        {
            // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg();
        if( list->size() == 0)
        {
            std::list<std::string> list;
            list.push_back("Task log is empty.");
            o_msg_response->setStringList( list);
        }
        else
        {
            o_msg_response->setStringList( *list);
        }
        break;
    }
    case af::Msg::TTaskErrorHostsRequest:
    {
        AfContainerLock lock( i_args->jobs,  AfContainerLock::READLOCK);

        af::MCTaskPos mctaskpos( i_msg);
        JobContainerIt jobsIt( i_args->jobs);
        JobAf* job = jobsIt.getJob( mctaskpos.getJobId());
        if( job == NULL )
        {
            // FIXME: Better to return some message in any case.
            break;
        }
        o_msg_response = new af::Msg();
        o_msg_response->setString( job->v_getErrorHostsListString( mctaskpos.getNumBlock(), mctaskpos.getNumTask()));
        break;
    }
    case af::Msg::TTaskOutputRequest:
    {
        af::Msg * msg_request_render = NULL;
        std::string filename, error;
        af::MCTaskPos tp( i_msg);
//printf("ThreadReadMsg::msgCase: case af::Msg::TJobTaskOutputRequest: job=%d, block=%d, task=%d, number=%d\n", tp.getJobId(), tp.getNumBlock(), tp.getNumTask(), tp.getNumber());
        {
            AfContainerLock jLock( i_args->jobs,	 AfContainerLock::READLOCK);
            AfContainerLock rLock( i_args->renders, AfContainerLock::READLOCK);

            JobContainerIt jobsIt( i_args->jobs);
            JobAf* job = jobsIt.getJob( tp.getJobId());
            if( job == NULL )
            {
                o_msg_response = af::msgString("Error: Job is NULL.");
                AFCommon::QueueLogError("Jobs is NULL");
                break;
            }

            // Trying to set message to request output from running remote host.
            msg_request_render = job->v_getTaskStdOut( tp.getNumBlock(), tp.getNumTask(), tp.getNumber(),
                                 i_args->renders, filename, error);

            if( error.size())
            {
                if( msg_request_render )
                    delete msg_request_render;
                o_msg_response = af::msgString( error);
                AFCommon::QueueLogError( error);
                break;
            }
        }
        if( filename.size())
        {
            //
            //	 Retrieving output from file
            //
            int readsize = -1;
            char * data = af::fileRead( filename, readsize, af::Msg::SizeDataMax, &error);
            if( data )
            {
                o_msg_response = new af::Msg();
                o_msg_response->setData( readsize, data);
                delete [] data;
            }
            else if( error.size())
            {
                error = std::string("Getting task output: ") + error;
                AFCommon::QueueLogError( error);
                o_msg_response = af::msgString( error);
            }
        }
        else if( msg_request_render)
        {
            //
            //	 Retrieving output from render
            //
            msg_request_render->setReceiving();
            bool ok;
            o_msg_response = af::msgsend( msg_request_render, ok, af::VerboseOn);
            if( o_msg_response == NULL )
            {
                error = "Retrieving output from render failed. See server logs for details.";
                o_msg_response = af::msgString( error);
                AFCommon::QueueLogError( error);
            }
            delete msg_request_render;
        }
        else
        {
            if( error.size())
            {
                o_msg_response = af::msgString( error);
                AFCommon::QueueLogError("TTaskOutputRequest: Neiter message nor filename\n" + error);
            }
            else
                AFCommon::QueueLogError("TTaskOutputRequest: Neiter message nor filename.");
        }
        break;
    }
    case af::Msg::TJobsWeightRequest:
    {
        AfContainerLock jLock( i_args->jobs,	 AfContainerLock::READLOCK);

        af::MCJobsWeight jobsWeight;
        i_args->jobs->getWeight( jobsWeight);
        o_msg_response = new af::Msg( af::Msg::TJobsWeight, &jobsWeight);
        break;
    }
    // Cases for run cycle thread:
    case af::Msg::TTaskUpdateState:
    {
        af::MCTaskUp taskup( i_msg);
        af::MCTaskPos taskpos( taskup.getNumJob(), taskup.getNumBlock(), taskup.getNumTask(), taskup.getNumber());
        o_msg_response = new af::Msg( af::Msg::TRenderCloseTask, &taskpos);
    }
    case af::Msg::TTaskUpdatePercent:
    case af::Msg::TTaskListenOutput:
    case af::Msg::TRenderDeregister:
    case af::Msg::TTalkDeregister:
    /*	{
    		// Check magic number mismatch mode:
    		// All message types above are not allowed in "GetOnly" mode.
    		if( i_msg->isMagicInvalid() && ( af::Environment::getMagicMode() <= af::MMM_GetOnly ))
    		{
    			std::string err = "Magic Mismatch Mode: \"";
    			err += af::Environment::getMagicModeName();
    			err += "\"";
    			err += "\nMessage type not allowed: \"";
    			err += af::Msg::TNAMES[i_msg->type()];
    			err += "\"";
    			AFCommon::QueueLogError( err);
    			delete i_msg;
    			return o_msg_response;
    		}
    		// Only Monitor message types are allowed in "GetOnly" mode.
    	}*/
    case af::Msg::TMonitorSubscribe:
    case af::Msg::TMonitorUnsubscribe:
    case af::Msg::TMonitorDeregister:
    case af::Msg::TMonitorUsersJobs:
    case af::Msg::TMonitorJobsIdsAdd:
    case af::Msg::TMonitorJobsIdsSet:
    case af::Msg::TMonitorJobsIdsDel:
    case af::Msg::TMonitorMessage:
    {
        // Push message for run cycle thread.
        i_args->msgQueue->pushMsg( i_msg);
        // Need to return here to not to delete input message (i_msg) later.
        return o_msg_response;
        //  ( o_msg_response is NULL in all cases except Msg::TTaskUpdateState,
        //	 in that case render should recieve an answer to close task
        //	 and finish sending any updates for the task )
    }
    // -------------------------------------------------------------------------//
    default:
    {
        AFCommon::QueueLogError( std::string("Unknown message recieved: ") + i_msg->v_generateInfoString( false));
        break;
    }
    }

    // Deleting input message as it not needed any more.
    delete i_msg;

    // Returning an answer
    return o_msg_response;
}
Beispiel #12
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());
	}
}
Beispiel #13
0
af::Msg * threadProcessJSON( ThreadArgs * i_args, af::Msg * i_msg)
{
	rapidjson::Document document;
	std::string error;
	char * data = af::jsonParseMsg( document, i_msg, &error);
	if( data == NULL )
	{
		AFCommon::QueueLogError( error);
		delete i_msg;
		return NULL;
	}

	af::Msg * o_msg_response = NULL;

	JSON & getObj = document["get"];
	if( getObj.IsObject())
	{
		std::string type, mode;
		bool binary = false;
		af::jr_string("type", type, getObj);
		af::jr_string("mode", mode, getObj);
		af::jr_bool("binary", binary, getObj);

		bool json = true;
		if( binary )
			json = false;
		bool full = false;
		if( mode == "full")
			full = true;

		std::vector<int32_t> ids;
		af::jr_int32vec("ids", ids, getObj);

		std::string mask;
		af::jr_string("mask", mask, getObj);

		if( type == "jobs" )
		{
			if( getObj.HasMember("uids"))
			{
				std::vector<int32_t> uids;
				af::jr_int32vec("uids", uids, getObj);
				if( uids.size())
				{
					AfContainerLock jLock( i_args->jobs,  AfContainerLock::READLOCK);
					AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK);
					o_msg_response = i_args->users->generateJobsList( uids, type, json);
				}
			}
			if( getObj.HasMember("users"))
			{
				std::vector<std::string> users;
				af::jr_stringvec("users", users, getObj);
				if( users.size())
				{
					AfContainerLock jLock( i_args->jobs,  AfContainerLock::READLOCK);
					AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK);
					o_msg_response = i_args->users->generateJobsList( users, type, json);
				}
			}
			else if( mode == "output")
			{
				std::vector<int32_t> block_ids;
				std::vector<int32_t> task_ids;
				int number = 0;
				af::jr_int32vec("block_ids", block_ids, getObj);
				af::jr_int32vec("task_ids", task_ids, getObj);
				af::jr_int("number", number, getObj);
				if(( ids.size() == 1 ) && ( block_ids.size() == 1 ) && ( task_ids.size() == 1 ))
				{
					af::Msg * msg_request_render = NULL;
					std::string filename, error, name;

					// Get output from job, it can return a request message for render or a filename
					{
						AfContainerLock jlock( i_args->jobs,    AfContainerLock::READLOCK);
						AfContainerLock rLock( i_args->renders, AfContainerLock::READLOCK);

						JobContainerIt it( i_args->jobs);
						JobAf * job = it.getJob( ids[0]);
						if( job == NULL )
							o_msg_response = af::jsonMsgError("Invalid ID");
						else
						{
							msg_request_render = job->v_getTaskStdOut( block_ids[0], task_ids[0], number,
								i_args->renders, filename, error);
							name = job->generateTaskName( block_ids[0], task_ids[0]);
							if( number > 0 )
								name += "["+af::itos(number)+"]";
						}
					}

					if( filename.size()) // Reading output from file
					{
						int readsize = -1;
						char * data = af::fileRead( filename, &readsize, af::Msg::SizeDataMax, &error);
						if( data )
						{
							o_msg_response = af::jsonMsg( mode, name, data, readsize);
							delete [] data;
						}
					}
					else if( msg_request_render) // Retrieving output from render
					{
						msg_request_render->setReceiving();
						bool ok;
						af::Msg * response = af::msgsend( msg_request_render, ok, af::VerboseOn);
						if( response )
						{
							o_msg_response = af::jsonMsg( mode, name, response->data(), response->dataLen());
							delete response;
						}
						else
							error = "Retrieving output from render failed. See server logs for details.";
						delete msg_request_render;
					}
	
					if( error.size())
					{
						if( o_msg_response == NULL )
							o_msg_response = af::jsonMsgError( error);
						AFCommon::QueueLogError("TTaskOutputRequest: " + error);
					}
				}
			}
			else
			{
				AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK);
				JobAf * job = NULL;
				bool was_error = false;
				if( ids.size() == 1 )
				{
					JobContainerIt it( i_args->jobs);
					job = it.getJob( ids[0]);
					if( job == NULL )
						o_msg_response = af::jsonMsgError( "Invalid ID");
				}

				if( job )
				{
					std::vector<int32_t> block_ids;
					af::jr_int32vec("block_ids", block_ids, getObj);
					if( block_ids.size() && ( block_ids[0] != -1 ))
					{
						std::vector<int32_t> task_ids;
						af::jr_int32vec("task_ids", task_ids, getObj);
						if( task_ids.size() && ( task_ids[0] != -1))
							o_msg_response = job->writeTask( block_ids[0], task_ids[0], mode, binary);
						else
						{
							std::vector<std::string> modes;
							af::jr_stringvec("mode", modes, getObj);
							o_msg_response = job->writeBlocks( block_ids, modes);
						}
					}
					else if( mode.size())
					{
						if( mode == "thumbnail" )
							o_msg_response = job->writeThumbnail( binary);
						else if( mode == "progress" )
							o_msg_response = job->writeProgress( json);
						else if( mode == "error_hosts" )
							o_msg_response = job->writeErrorHosts();
						else if( mode == "log" )
							o_msg_response = job->writeLog();
					}
				}
				
				if( o_msg_response == NULL )
					o_msg_response = i_args->jobs->generateList(
						full ? af::Msg::TJob : af::Msg::TJobsList, type, ids, mask, json);
			}
		}
		else if( type == "renders")
		{
			AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK);
			if( mode.size())
			{
				RenderAf * render = NULL;
				if( ids.size() == 1 )
				{
					RenderContainerIt it( i_args->renders);
					render = it.getRender( ids[0]);
					if( render == NULL )
						o_msg_response = af::jsonMsgError( "Invalid ID");
				}
				if( render )
				{
					if( full )
						o_msg_response = render->jsonWriteSrvFarm();
					else if( mode == "log" )
						o_msg_response = render->writeLog();
					else if( mode == "tasks_log" )
						o_msg_response = af::jsonMsg("tasks_log", render->getName(), render->getTasksLog());
				}
			}
			if( o_msg_response == NULL )
			{
				if( mode == "resources" )
					o_msg_response = i_args->renders->generateList( af::Msg::TRendersResources, type, ids, mask, json);
				else
					o_msg_response = i_args->renders->generateList( af::Msg::TRendersList, type, ids, mask, json);
			}
		}
		else if( type == "users")
		{
			AfContainerLock lock( i_args->users, AfContainerLock::READLOCK);
			if( mode.size())
			{
				UserAf * user = NULL;
				if( ids.size() == 1 )
				{
					UserContainerIt it( i_args->users);
					user = it.getUser( ids[0]);
					if( user == NULL )
						o_msg_response = af::jsonMsgError( "Invalid ID");
				}
				if( user )
				{
					if( mode == "jobs_order" )
						o_msg_response = user->writeJobdsOrder();
					else if( mode == "log" )
						o_msg_response = user->writeLog();
				}
			}
			if( o_msg_response == NULL )
				o_msg_response = i_args->users->generateList( af::Msg::TUsersList, type, ids, mask, json);
		}
		else if( type == "monitors")
		{
			AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK);
			if( mode == "events")
			{
				MonitorContainerIt it( i_args->monitors);
				if( ids.size() )
				{
					MonitorAf* node = it.getMonitor( ids[0]);
					if( node != NULL )
					{
						o_msg_response = node->getEvents();
					}
					else
					{
						o_msg_response = af::jsonMsg("{\"monitor\":{\"id\":0}}");
					}
				}
				else
				{
					o_msg_response = af::jsonMsgError("id is not specified");
				}
			}
			else
				o_msg_response = i_args->monitors->generateList( af::Msg::TMonitorsList, type, ids, mask, json);
		}
		else if( type == "files")
		{
			std::string path;
			std::ostringstream files;
			af::jr_string("path", path, getObj);
			std::vector<std::string> list = af::getFilesListSafe( path);
			files << "{\"path\":\"" << path << "\",\n";
			files << "\"files\":[";
			for( int i = 0; i < list.size(); i++)
			{
				if( i )
					files << ',';
				files << '"' << list[i] << '"';
			}
			files << "]}";
			o_msg_response = af::jsonMsg( files);
		}
		else if( type == "config" )
		{
			o_msg_response = af::jsonMsg( af::Environment::getConfigData());
		}
	}
	else if( document.HasMember("action"))
	{
		i_args->msgQueue->pushMsg( i_msg);
		// To not to detele it, set to NULL, as it pushed to another queue
		i_msg = NULL;
	}
	else if( document.HasMember("job"))
	{
		if( af::Environment::isDemoMode() )
		{
			AFCommon::QueueLogError("Job registration is not allowed: Server demo mode.");
		}
		else
		{
			// No containers locks needed here.
			// Job registration is a complex procedure.
			// It locks and unlocks needed containers itself.
			i_args->jobs->job_register( new JobAf( document["job"]), i_args->users, i_args->monitors);
		}
	}
	else if( document.HasMember("monitor"))
	{
		AfContainerLock mlock( i_args->monitors, AfContainerLock::WRITELOCK);
		AfContainerLock ulock( i_args->users,    AfContainerLock::READLOCK);
		MonitorAf * newMonitor = new MonitorAf( document["monitor"], i_args->users);
		newMonitor->setAddressIP( i_msg->getAddress());
		o_msg_response = i_args->monitors->addMonitor( newMonitor, /*JSON = */ true);
	}
	else if( document.HasMember("user"))
	{
		AfContainerLock ulock( i_args->users, AfContainerLock::WRITELOCK);
		o_msg_response = i_args->users->addUser( new UserAf( document["user"]), i_args->monitors);
	}
	else if( document.HasMember("reload_farm"))
	{
		AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK);
		AfContainerLock rlock( i_args->renders,  AfContainerLock::WRITELOCK);

		printf("\n	========= RELOADING FARM =========\n\n");
		if( af::loadFarm( true))
		{
			RenderContainerIt rendersIt( i_args->renders);
			for( RenderAf *render = rendersIt.render(); render != NULL; rendersIt.next(), render = rendersIt.render())
			{
				render->getFarmHost();
				i_args->monitors->addEvent( af::Msg::TMonitorRendersChanged, render->getId());
			}
			printf("\n	========= FARM RELOADED SUCCESSFULLY =========\n\n");
			o_msg_response = af::jsonMsgStatus( true, "reload_farm",
				"Reloaded successfully.");
		}
		else
		{
			printf("\n	========= FARM RELOADING FAILED =========\n\n");
			o_msg_response = af::jsonMsgStatus( false, "reload_farm",
				"Failed, see server logs fo details. Check farm with \"afcmd fcheck\" at first.");
		}
	}
	else if( document.HasMember("reload_config"))
	{
		AfContainerLock jlock( i_args->jobs,	AfContainerLock::WRITELOCK);
		AfContainerLock rlock( i_args->renders, AfContainerLock::WRITELOCK);
		AfContainerLock ulock( i_args->users,	AfContainerLock::WRITELOCK);
		printf("\n	========= RELOADING CONFIG =========\n\n");
		std::string message;
		if( af::Environment::reload())
		{
			printf("\n	========= CONFIG RELOADED SUCCESSFULLY =========\n\n");
			o_msg_response = af::jsonMsgStatus( true, "reload_config",
				"Reloaded successfully.");
		}
		else
		{
			printf("\n	========= CONFIG RELOADING FAILED =========\n\n");
			o_msg_response = af::jsonMsgStatus( false, "reload_config",
				"Failed, see server logs fo details.");
		}
	}

	delete [] data;
	if( i_msg ) delete i_msg;

	return o_msg_response;
}
Beispiel #14
0
//######################################## main #########################################
int main(int argc, char *argv[])
{
	// Initialize environment:
	af::Environment ENV( af::Environment::Server, argc, argv);
	ENV.addUsage("-demo", "Disable tasks changing and new jobs.");

	// Initialize general library:
	if( af::init( af::InitFarm) == false) return 1;

	// Initialize store:
	afsql::init();

	// Environment aready printed usage and we can exit.
	if( ENV.isHelpMode()) return 0;

	// create directories if it is not exists
	if( af::pathMakePath( ENV.getTempDir(),    af::VerboseOn ) == false) return 1;
	if( af::pathMakeDir(  ENV.getJobsDir(),    af::VerboseOn ) == false) return 1;
	if( af::pathMakeDir(  ENV.getUsersDir(),   af::VerboseOn ) == false) return 1;
	if( af::pathMakeDir(  ENV.getRendersDir(), af::VerboseOn ) == false) return 1;

// Server for windows can be me more simple and not use signals at all.
// Windows is not a server platform, so it designed for individual tests or very small companies with easy load.
#ifndef _WIN32
// Interrupt signals catch.
// We need to catch interrupt signals to let threads to finish running function themselves.
// This needed mostly fot queues to let them to finish to process last item.
	struct sigaction actint;
	bzero( &actint, sizeof(actint));
	actint.sa_handler = sig_int;
	sigaction( SIGINT,  &actint, NULL);
	sigaction( SIGTERM, &actint, NULL);

// SIGPIPE signal catch.
// This is not an error for our application.
	struct sigaction actpipe;
	bzero( &actpipe, sizeof(actpipe));
	actpipe.sa_handler = sig_pipe;
	sigaction( SIGPIPE, &actpipe, NULL);

// SIGALRM signal catch and block.
// Special threads use alarm signal to unblock connect function.
// Other threads should ignore this signal.
	struct sigaction actalrm;
	bzero( &actalrm, sizeof(actalrm));
	actalrm.sa_handler = sig_alrm;
	sigaction( SIGALRM, &actalrm, NULL);
	sigset_t sigmask;
	sigemptyset( &sigmask);
	sigaddset( &sigmask, SIGALRM);
	if( sigprocmask( SIG_BLOCK, &sigmask, NULL) != 0) perror("sigprocmask:");
	if( pthread_sigmask( SIG_BLOCK, &sigmask, NULL) != 0) perror("pthread_sigmask:");
#endif

	// containers initialization
	JobContainer jobs;
	if( false == jobs.isInitialized()) return 1;

	UserContainer users;
	if( false == users.isInitialized()) return 1;

	RenderContainer renders;
	if( false == renders.isInitialized()) return 1;

	MonitorContainer monitors;
	if( false == monitors.isInitialized()) return 1;
	
	// Message Queue initialization, but without thread start.
	// Run cycle queue will read this messages itself.
	af::MsgQueue msgQueue("RunMsgQueue");
	if( false == msgQueue.isInitialized()) 
	  return 1;

	// Thread aruguments.
	ThreadArgs threadArgs;
	threadArgs.jobs      = &jobs;
	threadArgs.renders   = &renders;
	threadArgs.users     = &users;
	threadArgs.monitors  = &monitors;
	threadArgs.msgQueue  = &msgQueue;

	/*
	  Creating the afcommon object will actually create many message queues
	  that will spawn threads. Have a look in the implementation of AfCommon.
	*/
	AFCommon afcommon( &threadArgs );

	// Update SQL tables:
	afsql::DBConnection afdb_upTables("AFDB_upTables");
	afdb_upTables.DBOpen();
	if( afdb_upTables.isOpen())
	{
		afsql::UpdateTables( &afdb_upTables);
		afdb_upTables.DBClose();
	}

	//
	// Get Renders from store:
	//
	{
	printf("Getting renders from store...\n");

	std::vector<std::string> folders = AFCommon::getStoredFolders( ENV.getRendersDir());
	printf("%d renders found.\n", (int)folders.size());

	for( int i = 0; i < folders.size(); i++)
	{
		RenderAf * render = new RenderAf( folders[i]);
		if( render->isStoredOk() != true )
		{
			af::removeDir( render->getStoreDir());
			delete render;
			continue;
		}
		renders.addRender( render);
	}
	printf("%d renders registered.\n", renders.getCount());
	}

	//
	// Get Users from store:
	//
	{
	printf("Getting users from store...\n");

	std::vector<std::string> folders = AFCommon::getStoredFolders( ENV.getUsersDir());
	printf("%d users found.\n", (int)folders.size());

	for( int i = 0; i < folders.size(); i++)
	{
		UserAf * user = new UserAf( folders[i]);
		if( user->isStoredOk() != true )
		{
			af::removeDir( user->getStoreDir());
			delete user;
			continue;
		}
		if( users.addUser( user) == 0 )
			delete user;
	}
	printf("%d users registered from store.\n", users.getCount());
	}
	//
	// Get Jobs from store:
	//
	bool hasSystemJob = false;
	{
	printf("Getting jobs from store...\n");

	std::vector<std::string> folders = AFCommon::getStoredFolders( ENV.getJobsDir());
	std::string sysjob_folder = AFCommon::getStoreDir( ENV.getJobsDir(), AFJOB::SYSJOB_ID, AFJOB::SYSJOB_NAME);

	printf("%d jobs found.\n", (int)folders.size());
	for( int i = 0; i < folders.size(); i++)
	{
		JobAf * job = NULL;

		if( folders[i] == sysjob_folder)
			job = new SysJob( folders[i]);
		else
			job = new JobAf( folders[i]);

		if( job->isValidConstructed())
		{
			if( job->getId() == AFJOB::SYSJOB_ID )
			{
				SysJob * sysjob = (SysJob*)job;
				if( sysjob->initSystem() )
				{
					hasSystemJob = true;
				}
				else
				{
					printf("System job retrieved from store is obsolete. Deleting it...\n");
					delete job;
					continue;
				}
			}
			jobs.job_register( job, &users, NULL);
		}
		else
		{
			af::removeDir( job->getStoreDir());
			delete job;
		}
	}
	printf("%d jobs registered from store.\n", jobs.getCount());
	}

	// Disable new commands and editing:
	if( af::Environment::hasArgument("-demo"))
	{
		printf("Demo mode, no new commands.\n");
		af::Environment::setDemoMode();
	}

//
// Create system maintenance job if it was not in store:
	if( hasSystemJob == false )
	{
		SysJob* job = new SysJob();
		jobs.job_register( job, &users, NULL);
	}

	/*
	  Start the thread that is responsible of listening to the port
	  for incoming connections.
	*/
	DlThread ServerAccept;
	ServerAccept.Start( &threadAcceptClient, &threadArgs);

	// Run cycle thread.
	// All 'brains' are there.
	DlThread RunCycleThread;
	RunCycleThread.Start( &threadRunCycle, &threadArgs);

	/* Do nothing since everything is done in our threads. */
	while( AFRunning )
	{
		DlThread::Self()->Sleep( 1 );
	}

	AFINFO("afanasy::main: Waiting child threads.")
	//alarm(1);
	/*FIXME: Why we don`t need to join accent thread? */
	//ServerAccept.Cancel();
	//ServerAccept.Join();

	AFINFO("afanasy::main: Waiting Run.")
	// No need to chanel run cycle thread as
	// every new cycle it checks running external valiable
	RunCycleThread.Join();

	af::destroy();

	return 0;
}
Beispiel #15
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;
}