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; }
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); }
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); }
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; }
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; }
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; }
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); }
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; }
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); }
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; }
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()); } }
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; }
//######################################## 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; }
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; }