Контроль и рассылка уведомлений о просроченных сообщениях обмена для сервиса

This commit is contained in:
Mikhail Chechnev 2019-01-07 17:49:22 +03:00
parent 6fb79a34ee
commit a522cdf3b6
2 changed files with 50 additions and 20 deletions

View File

@ -30,6 +30,9 @@ const NDETECTING_LOOP_DELAY = 3000;
//Интервал проверки доступности сервисов (мс) //Интервал проверки доступности сервисов (мс)
const NDETECTING_LOOP_INTERVAL = 60000; const NDETECTING_LOOP_INTERVAL = 60000;
//Таймаут проверки доступности адреса сервиса (мс)
const NNETWORK_CHECK_TIMEOUT = 10000;
//------------ //------------
// Тело модуля // Тело модуля
//------------ //------------
@ -62,8 +65,8 @@ class ServiceAvailableController extends EventEmitter {
this.notifier = prms.notifier; this.notifier = prms.notifier;
//Запомним логгер //Запомним логгер
this.logger = prms.logger; this.logger = prms.logger;
//Установим таймаут проведки адреса сервиса (мс) //Запомним подключение к БД
this.nCheckTimeout = 10000; this.dbConn = prms.dbConn;
//Привяжем методы к указателю на себя для использования в обработчиках событий //Привяжем методы к указателю на себя для использования в обработчиках событий
this.serviceDetectingLoop = this.serviceDetectingLoop.bind(this); this.serviceDetectingLoop = this.serviceDetectingLoop.bind(this);
} else { } else {
@ -108,7 +111,7 @@ class ServiceAvailableController extends EventEmitter {
) { ) {
try { try {
//Отправляем проверочный запрос //Отправляем проверочный запрос
await rqp({ url: this.services[i].sSrvRoot, timeout: this.nCheckTimeout }); await rqp({ url: this.services[i].sSrvRoot, timeout: NNETWORK_CHECK_TIMEOUT });
//Запрос прошел - фиксируем дату доступности и сбрасываем дату недоступности //Запрос прошел - фиксируем дату доступности и сбрасываем дату недоступности
this.services[i].dAvailable = new Date(); this.services[i].dAvailable = new Date();
this.services[i].dUnAvailable = null; this.services[i].dUnAvailable = null;
@ -120,7 +123,7 @@ class ServiceAvailableController extends EventEmitter {
if (e.error) { if (e.error) {
let sSubError = e.error.code || e.error; let sSubError = e.error.code || e.error;
if (e.error.code === "ESOCKETTIMEDOUT") if (e.error.code === "ESOCKETTIMEDOUT")
sSubError = `сервис не ответил на запрос в течение ${this.nCheckTimeout} мс`; sSubError = `сервис не ответил на запрос в течение ${NNETWORK_CHECK_TIMEOUT} мс`;
sError = `Ошибка передачи данных: ${sSubError}`; sError = `Ошибка передачи данных: ${sSubError}`;
} }
if (e.response) { if (e.response) {
@ -151,8 +154,6 @@ class ServiceAvailableController extends EventEmitter {
let nDiffMins = Math.round(((nDiffMs % 86400000) % 3600000) / 60000); let nDiffMins = Math.round(((nDiffMs % 86400000) % 3600000) / 60000);
//Если простой больше указанного в настройках - будем оповещать по почте //Если простой больше указанного в настройках - будем оповещать по почте
if (nDiffMins >= this.services[i].nUnavlblNtfTime) { if (nDiffMins >= this.services[i].nUnavlblNtfTime) {
//Подготовим тему для уведомления
let sSubject = `Удалённый сервис ${this.services[i].sCode} неотвечает на запросы`;
//Подготовим сообщение для уведомления //Подготовим сообщение для уведомления
let sMessage = `Сервис недоступен более ${ let sMessage = `Сервис недоступен более ${
this.services[i].nUnavlblNtfTime this.services[i].nUnavlblNtfTime
@ -161,23 +162,41 @@ class ServiceAvailableController extends EventEmitter {
}`; }`;
//Положим уведомление в протокол работы сервера приложений //Положим уведомление в протокол работы сервера приложений
await this.logger.error(sMessage, { nServiceId: this.services[i].nId }); await this.logger.error(sMessage, { nServiceId: this.services[i].nId });
//И в почту, если есть список адресов //И в очередь уведомлений
if (this.services[i].sUnavlblNtfMail) { await this.notifier.addMessage({
try { sTo: this.services[i].sUnavlblNtfMail,
this.notifier.addMessage({ sSubject: `Удалённый сервис ${this.services[i].sCode} неотвечает на запросы`,
sTo: this.services[i].sUnavlblNtfMail, sMessage
sSubject, });
sMessage
});
} catch (e) {
await this.logger.error(makeErrorText(e), {
nServiceId: this.services[i].nId
});
}
}
} }
} }
} }
//Если сервис надо проверять на доступность то проверим так же - есть ли у него неотработанные сообщения обмена
if (this.services[i].nUnavlblNtfSign == objServiceSchema.NUNAVLBL_NTF_SIGN_YES) {
try {
let res = await this.dbConn.getServiceExpiredQueueInfo({
nServiceId: this.services[i].nId
});
//Если у сервиса есть просроченные сообщения - будет отправлять информацию об этом
if (res.nCnt > 0) {
//Отправляем уведомление
await this.notifier.addMessage({
sTo: this.services[i].sUnavlblNtfMail,
sSubject: `Для сервиса ${
this.services[i].sCode
} зафиксированы просроченные сообщения обмена (${res.nCnt} ед.)`,
sMessage: res.sInfoList
});
}
} catch (e) {
await this.logger.error(
`При проверке просроченных сообщений сервиса ${this.services[i].sCode}: ${makeErrorText(
e
)}`,
{ nServiceId: this.services[i].nId }
);
}
}
} }
} catch (e) { } catch (e) {
//Фиксируем ошибку в протоколе работы сервера приложений //Фиксируем ошибку в протоколе работы сервера приложений

View File

@ -11,6 +11,7 @@ const Schema = require("validate"); //Схемы валидации
const { defServices } = require("./obj_services"); //Схема валидации списка сервисов const { defServices } = require("./obj_services"); //Схема валидации списка сервисов
const { Notifier } = require("../core/notifier"); //Класс рассылки уведомлений const { Notifier } = require("../core/notifier"); //Класс рассылки уведомлений
const { Logger } = require("../core/logger"); //Класс для протоколирования работы const { Logger } = require("../core/logger"); //Класс для протоколирования работы
const { DBConnector } = require("../core/db_connector"); //Класс взаимодействия в БД
//------------------ //------------------
// Интерфейс модуля // Интерфейс модуля
@ -37,6 +38,16 @@ exports.ServiceAvailableController = new Schema({
`Объект для протоколирования работы (${path}) имеет некорректный тип данных (ожидалось - Logger)`, `Объект для протоколирования работы (${path}) имеет некорректный тип данных (ожидалось - Logger)`,
required: path => `Не указаны объект для протоколирования работы (${path})` required: path => `Не указаны объект для протоколирования работы (${path})`
} }
},
//Объект для взаимодействия с БД
dbConn: {
type: DBConnector,
required: true,
message: {
type: path =>
`Объект для взаимодействия с БД (${path}) имеет некорректный тип данных (ожидалось - DBConnector)`,
required: path => `Не указан объект для взаимодействия с БД (${path})`
}
} }
}); });