/** * Главный метод воркера Ping. * * Выплняет в цикле пинг хостов и запись в кэш Redis. * * @access public * @static */ public static function main() { DEBUG && (print "PingWorker::main(): begin\n"); // регистрация обработчика сигналов static::initSignalHandlers(); // подключение к СУБД и кэшу Redis - оба используются DB::open(); RKS::open(); // объявление массива очередей $queue_lists = ['ok', 'prefailed', 'failed']; // итерация массива очередей foreach ($queue_lists as $queue_list) { DEBUG && printf("PingWorker::main(): begin queue '%s'\n", $queue_list); // итерация очереди while (static::$worker_loop) { // получение следующей записи из очереди $label = static::fetch($queue_list); // записей нет - выход из цикла очереди if (!$label) { DEBUG && printf("NslookupWorker::main(): break loop '%s'\n", $queue_list); break; } // выполнение процедур для лейбла static::exec($label); } DEBUG && printf("PingWorker::main(): end queue '%s'\n", $queue_list); } DB::close(); RKS::close(); DEBUG && (print "PingWorker::main(): end\n\n"); }
/** * Сброс состояний и статусов хостов в кэше Redis и СУБД. * * @param int $status * @access protected * @static */ protected static function resetHostsStatuses($status) { DEBUG && printf("Master::resetHostsStatuses(%d): begin\n", $status); DB::open(); $redis = RKS::getInstance(); $hosts = $redis->sMembers('hosts:enabled'); DEBUG && printf("Master::resetHostsStatuses(): Redis->sMembers('host:enabled')\n%s\n", var_export($hosts, true)); foreach ($hosts as $label) { DEBUG && printf("Master::resetHostsStatuses(): begin label '%s'\n", $label); $data = $redis->hGetAll('hosts:data:' . $label); DEBUG && printf("Master::resetHostsStatuses(): Redis->hGetAll('host:data:%s')\n%s\n", $label, var_export($data, true)); if (!$data || empty($data['addr'])) { DEBUG && printf("Master::resetHostsStatuses(): host '%s' not ready\n", $label); continue; } $data_out = ['state' => 0, 'status' => $status]; DEBUG && printf("Master::resetHostsStatuses(): Redis->hMset('host:data:%s', %s)\n", $label, var_export($data_out, true)); $redis->hMset('hosts:data:' . $label, $data_out); DBQueries::dataPush($data['id'], $status, 0); DEBUG && printf("Master::resetHostsStatuses(): end label '%s'\n", $label); } DB::close(); DEBUG && (print "Master::resetHostsStatuses(): end\n\n"); }
/** * Деактивация хоста. * * @param string $label Лейбл деактивируемого хоста. * @access public * @static */ public static function cmdDisable($label) { // первичная проверка аргументов if (!preg_match('~^[a-z0-9-]{3,48}$~', $label)) { fwrite(STDERR, "Label contains invalid characters. Only [a-z0-9-]{3,48} allowed.\n"); exit(1); } // подключение к СУБД DB::open(); // поиск лейбла в базе хостов $res = DBQueries::hostByLabel($label); if (0 == $res->num_rows) { fwrite(STDERR, spinrtf("Host with label '%s' was not found.\n", $label)); exit(1); } if (1 < $res->num_rows) { fwrite(STDERR, sprintf("Fatal: Expected 1 row, has %d\n", $res->num_rows)); exit(1); } /* @var $host \Ganzal\Lulz\Pinger\Assets\Host */ $host = $res->fetch_object('\\Ganzal\\Lulz\\Pinger\\Assets\\Host'); if (0 == $host->host_enabled) { fwrite(STDERR, "Host is already disabled.\n"); } else { // обновление статуса в таблице хостов $res = DBQueries::hostXXable($host->host_id, 0); // отсечка о прекращении сбора данных DBQueries::dataPush($host->host_id, HostStatuses::DISABLED, 0); /* @var $redis \Redis */ $redis = RKS::getInstance(); // обновление статуса в кэше Redis. // удаление лейбла из списка hosts:enabled отключает будущие пинги. // удаление из всех пулов queue:* так как не известно где он может быть. $redis->sRemove("hosts:enabled", $label); $redis->sRemove("queue:ping:ok", $label); $redis->sRemove("queue:ping:prefailed", $label); $redis->sRemove("queue:ping:failed", $label); $redis->sRemove("queue:nslookup", $label); $redis->hMset('hosts:data:' . $label, ['state' => '', 'status' => '']); fwrite(STDERR, "Host successfully disabled.\n"); } exit(0); }
/** * Выполнение <code>nslookup</code> для лейбла. * * @param string $label * @return void * @access public * @static */ public static function exec($label) { DEBUG && printf("NslookupWorker::exec(%s): begin\n", $label); $redis = RKS::getInstance(); // получение свединей о лейбле из кэша Redis $data = $redis->hGetAll('hosts:data:' . $label); DEBUG && printf("NslookupWorker::exec(): Redis->hGetAll('host:data:%s')\n%s\n", $label, var_export($data, true)); if (!$data) { DEBUG && printf("NslookupWorker::exec(): host '%s' not ready\n", $label); return; } // поиск адреса $addr = SystemNslookupWrapper::exec($data['fqdn']); DEBUG && printf("NslookupWorker::exec(): addr = %s\n", var_export($addr, true)); $data_out = ['addr' => $addr, 'status' => $addr ? (int) $data['status'] : HostStatuses::NXDOMAIN]; if (HostStatuses::NXDOMAIN == $data_out['status'] && HostStatuses::NXDOMAIN != $data['status'] || HostStatuses::NXDOMAIN != $data_out['status'] && HostStatuses::NXDOMAIN == $data['status']) { DB::open(); DBQueries::dataPush($data['id'], $data_out['status'], 0); DB::close(); } DEBUG && printf("NslookupWorker::exec(): Redis->hMset('host:data:%s', %s)\n", $label, var_export($data_out, true)); // запись сведений в кэш Redis $redis->hMset('hosts:data:' . $label, $data_out); DEBUG && (print "NslookupWorker::exec(): end\n\n"); }