Beispiel #1
0
af::Msg * JobContainer::registerJob( JSON & i_object, UserContainer * i_users, MonitorContainer * i_monitoring)
{
	JobAf * job = new JobAf( i_object);

	int32_t id = 0; int64_t serial = 0; std::string err;
	if( registerJob( job, err, i_users, i_monitoring))
	{
		id = job->getId();
		serial = job->getSerial();
	}
	else
		job = NULL;

	std::ostringstream oss;
	oss << "{";
	oss << "\n\"id\":" << id;
	oss << ",\n\"serial\":" << serial;

	if( err.size())
	{
		oss << ",\n\"error\":\"" << err << "\"";
	}
	else if( job == NULL )
	{
		oss << ",\n\"error\":\"Job registration failed. See server log for details.\"";
	}


	oss << "\n}";

	return af::jsonMsg( oss);
}
Beispiel #2
0
void BranchSrv::v_postSolve(time_t i_curtime, MonitorContainer * i_monitoring)
{
	// Generate a new active jobs list:
	m_active_jobs_list.clear();
	AfListIt jIt(&m_jobs_list);
	for (AfNodeSrv * node = jIt.node(); node != NULL; jIt.next(), node = jIt.node())
	{
		JobAf * job = (JobAf*)node;
		if(job->isDone())
			continue;
		m_active_jobs_list.push_back(job);
	}


	// Clear active users (and delete users data)
	for (std::list<BranchUserData*>::iterator it = m_active_users_list.begin(); it != m_active_users_list.end(); it++)
		delete (*it);
	m_active_users_list.clear();

	// Generate a new active users list:
	std::map<UserAf*, BranchSrvUserData*>::iterator uIt = m_users.begin();
	for (; uIt != m_users.end(); uIt++)
	{
		if ((*uIt).second->running_tasks_num == 0)
			continue;

		m_active_users_list.push_back(
			new BranchUserData((*uIt).first, (*uIt).second->running_tasks_num, (*uIt).second->running_capacity_total));
	}
}
Beispiel #3
0
void JobContainer::reconnectTask( af::TaskExec * i_taskexec, RenderAf & i_render, MonitorContainer * i_monitoring)
{
	#ifdef AFOUTPUT
	AF_DEBUG << "Reconnecting task " << i_taskexec << " with " << i_render;
	#endif

	JobContainerIt jobsIt( this);
	JobAf* job = jobsIt.getJob( i_taskexec->getJobId());
	if( NULL == job )
	{
		AF_ERR << "Job with id=" << i_taskexec->getJobId() << " does not exists.";
		delete i_taskexec;
		return;
	}

	return job->reconnectTask( i_taskexec, i_render, i_monitoring);
}
Beispiel #4
0
const std::vector<int32_t> JobContainer::getIdsBySerials( const std::vector<int64_t> & i_serials)
{
	std::vector<int32_t> ids;

	JobContainerIt jobsIt( this);
	for( JobAf *job = jobsIt.job(); job != NULL; jobsIt.next(), job = jobsIt.job())
	{
		for( int i = 0; i < i_serials.size(); i++)
		{
			if( i_serials[i] == job->getSerial())
			{
				ids.push_back( job->getId());
				break;
			}
		}
	}

	if( ids.size() == 0 )
		ids.push_back(-1);

	return ids;
}
Beispiel #5
0
void RenderAf::ejectTasks( JobContainer * jobs, MonitorContainer * monitoring, uint32_t upstatus, const std::string * i_keeptasks_username )
{
	if( m_tasks.size() < 1)
		return;

	std::list<int>id_jobs;
	std::list<int>id_blocks;
	std::list<int>id_tasks;
	std::list<int>numbers;
	for( std::list<af::TaskExec*>::const_iterator it = m_tasks.begin(); it != m_tasks.end(); it++)
	{
		 // Skip if username to keep tasks provided:
		 if( i_keeptasks_username != NULL )
			  if( *i_keeptasks_username == (*it)->getUserName())
					continue;
		id_jobs.push_back( (*it)->getJobId());
		id_blocks.push_back( (*it)->getBlockNum());
		id_tasks.push_back( (*it)->getTaskNum());
		numbers.push_back( (*it)->getNumber());
		appendLog( std::string("Ejecting task: ") + (*it)->v_generateInfoString( false));
	}

	JobContainerIt jobsIt( jobs);
	std::list<int>::const_iterator jIt = id_jobs.begin();
	std::list<int>::const_iterator bIt = id_blocks.begin();
	std::list<int>::const_iterator tIt = id_tasks.begin();
	std::list<int>::const_iterator nIt = numbers.begin();
	std::list<int>::const_iterator end = numbers.end();
	for( ; nIt != end; jIt++, bIt++, tIt++, nIt++)
	{
		JobAf* job = jobsIt.getJob( *jIt);
		if( job != NULL )
		{
			af::MCTaskUp taskup( m_id, *jIt, *bIt, *tIt, *nIt, upstatus);
			job->v_updateTaskState( taskup, ms_renders, monitoring);
		}
	}
}
Beispiel #6
0
void JobContainer::updateTaskState( af::MCTaskUp &taskup, RenderContainer * renders, MonitorContainer * monitoring)
{
    switch( taskup.getStatus())
    {
    case af::TaskExec::UPNULL:
    case af::TaskExec::UPNoTaskRunning:
    case af::TaskExec::UPNoJob:
    case af::TaskExec::UPLAST:
        AFERRAR("JobContainer::updateTaskState: Bad task update status (jobID=%d).\n", taskup.getNumJob());
    return;
    }

    JobContainerIt jobsIt( this);
    JobAf* job = jobsIt.getJob( taskup.getNumJob());
    if( job != NULL )
    {
        job->v_updateTaskState( taskup, renders, monitoring);
        return;
    }

    // Job does not exist!
    AFERRAR("JobContainer::updateTaskState: Job with id=%d does not exists.", taskup.getNumJob())
            if( taskup.getStatus() == af::TaskExec::UPPercent) RenderAf::closeLostTask( taskup);
}
Beispiel #7
0
void JobContainer::getWeight( af::MCJobsWeight & jobsWeight )
{
   JobContainerIt jobsIt( this);
   for( JobAf *job = jobsIt.job(); job != NULL; jobsIt.next(), job = jobsIt.job())
   {
      int weight = job->v_calcWeight();
      jobsWeight.add(
            job->getName(),
            job->getId(),
            job->getLogsWeight(),
            job->getBlackListsWeight(),
            job->getProgressWeight(),
            weight
         );
   }
}
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 #9
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 #10
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;
}