Esempio n. 1
0
/** \mainpage KeywordsIndexCreator service
 
    \section usage_section Использование

    \b keywords_indexcreator --- это модуль, ответственный за построение и обновление
	индекса библиотеки полнотекстового поиска CLucene. 

	Модуль является фоновым приложением, запускаемым как сервис из /etc/init.d

    Примеры использования из командной строки (indexator.conf - файл конфигурации, см. ниже):

    \code
	keywords_indexcreator indexator.conf
    \endcode


    \section settings_section Настройка сервиса

    keywords_indexcreator для построения индекса использует базу данных mongo, 
	которая содержит описание всех рекламных предложений. Это основная база данных проекта,
       которую использует пользовательская часть. На уровне приложения
       регистрируется как база данных по умолчанию (см. DB::addDatabase).


    Параметры подключения к базе данных хранятся в файле конфигурации.
	Параметры \c mongo_main_host, \c mongo_main_db содержат адрес (в формате
    "host[:port]" и названия баз данных. 

    По умолчанию будут использованы следующие параметры:

    \code
	mongo_main_host = localhost
	mongo_main_db = getmyad_db
	mongo_main_set = ''
	mongo_main_slave_ok = false
    \endcode

	Кроме того, в файле конфигурации хранится переменная \c index_folder, отвечающая за 
	место размещения индекса на физическом диске.

	По умолчанию будут использованы следующие параметры:

    \code
	index_folder = /var/www/index
    \endcode

	Пример конфигурационного файла:

    \code
	mongo_main_host=213.186.119.121:27017,213.186.119.121:27018,213.186.119.121:27019
	mongo_main_set=vsrv
	mongo_main_db=getmyad_db
	mongo_main_slave_ok=true
	index_folder=/var/www/index
    \endcode


*/
int main(int argc, char *argv[])
{
    google::InitGoogleLogging(argv[0]);
	if (argc ==1) { printf ("Configuration file is needed!\nProcess stoped.....\n"); return 0;}

    pid_t parpid, sid;
    
    parpid = fork(); //создаем дочерний процесс
    //The parent process should get a non-zero pid from fork
    //The child process should get 0

    if (parpid < 0) //negative indicates error
    {
        printf("Error: Start Daemon failed (%s)\n", strerror(errno));
        exit(EXIT_FAILURE);
    } 
    else if (parpid > 0) //parent process, exit success
    {
        printf("Demon starting... ");
	 	
    	SetPidFile(PID_FILE, parpid);	

        exit(EXIT_SUCCESS);
    }

    umask(0);//даем права на работу с фс
    sid = setsid();

    if(sid < 0)
    {
	printf("sid<0\n");
        exit(EXIT_FAILURE);
    }

    if((chdir("/")) < 0) {//выходим в tmp
	exit(EXIT_FAILURE);
	}
	close(STDIN_FILENO);
	open("/dev/null",O_RDONLY); 
	close(STDOUT_FILENO);
	open("/dev/null",O_WRONLY);
	close(STDERR_FILENO);
	dup(1);

	return IndexCreatorService(argv[1]).Serve();
}
Esempio n. 2
0
//следим за потомком
int TDaemon::MonitorProc()
{
    int      pid;
    int      status;
    int      need_start = 1;
    sigset_t sigset;
    siginfo_t siginfo;
    // настраиваем сигналы которые будем обрабатывать
    sigemptyset(&sigset);
    
    // сигнал остановки процесса пользователем
    sigaddset(&sigset, SIGQUIT);
    
    // сигнал для остановки процесса пользователем с терминала
    sigaddset(&sigset, SIGINT);
    
    // сигнал запроса завершения процесса
    sigaddset(&sigset, SIGTERM);
    
    // сигнал посылаемый при изменении статуса дочернего процесса
    sigaddset(&sigset, SIGCHLD); 
    
    // пользовательский сигнал который мы будем использовать для обновления конфига
    sigaddset(&sigset, SIGHUP); 
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    // данная функция создаст файл с нашим PID'ом
    SetPidFile(PID_FILE.c_str());
    // бесконечный цикл работы
    for (;;)
    {
        // если необходимо создать потомка
        if (need_start)
        {
            // создаём потомка
            pid = fork();
        }
        
        need_start = 1;
        
        if (pid == -1) // если произошла ошибка
        {
            // запишем в лог сообщение об этом
            WriteLog("%s [MONITOR] Fork failed (%s)\n",getTime(), strerror(errno));
        }
        else if (!pid) // если мы потомок
        {
            // данный код выполняется в потомке
            // запустим функцию отвечающую за работу демона
            status = WorkProc();
            // завершим процесс
            exit(status);
        }
        else // если мы родитель
        {
            // данный код выполняется в родителе
            
            // ожидаем поступление сигнала
            sigwaitinfo(&sigset, &siginfo);
            // если пришел сигнал от потомка
            if (siginfo.si_signo == SIGCHLD)
            {
                // получаем статус завершение
                wait(&status);
                
                // преобразуем статус в нормальный вид
                status = WEXITSTATUS(status);

                 // если потомок завершил работу с кодом говорящем о том, что нет нужды дальше работать
                if (status == CHILD_NEED_TERMINATE)
                {
                    // запишем в лог сообщени об этом 
                    WriteLog("%s [MONITOR] Child stopped\n", getTime());
                    
                    // прервем цикл
                    break;
                }
                else if (status == CHILD_NEED_WORK) // если требуется перезапустить потомка
                {
                    // запишем в лог данное событие
                    WriteLog("%s [MONITOR] Child restart\n", getTime());
                }
            }
            else if (siginfo.si_signo == SIGHUP) // если пришел сигнал что необходимо перезагрузить конфиг
            {
                kill(pid, SIGHUP); // перешлем его потомку
                need_start = 0; // установим флаг что нам не надо запускать потомка заново
            }
            else // если пришел какой-либо другой ожидаемый сигнал
            {
                // запишем в лог информацию о пришедшем сигнале
                WriteLog("%s [MONITOR] Signal %s\n", getTime(), strsignal(siginfo.si_signo));
                
                // убьем потомка
                kill(pid, SIGTERM);
                status = 0;
                break;
            }
        }
    }

    // запишем в лог, что мы остановились
    WriteLog("%s [MONITOR] Stop\n", getTime());
    
    // удалим файл с PID'ом
    unlink(PID_FILE.c_str());
    
    return status;
}