Meteor DDP Call возвращает неопределенное значение, когда слишком долго - PullRequest
1 голос
/ 25 июня 2019

У меня есть 2 сервера, один для основного приложения и другой для огромных задач.

User -> Server 1 -> Server 2
Server 1: Main app & Easy tasks
Server 2: Huge Tasks

Когда я вызываю функцию сервера 2, на ответ которой требуется много времени, сервер 1 получает неопределенное значение, когда сервер 2 отвечает на хороший результат. Однако если для ответа функции server2 требуется менее 1 минуты, сервер 1 получил результат, отправленный сервером 2, а затем отправил его обратно клиенту.

Почему он не работает только для функций, для вычисления которых требуется более 1 минуты?

Клиент:

Meteor.call('reporting.default', params.subReport, params, function(error, result) {
    if (result) self.setState({data: result});
    else self.setState({data: error.message});
});

Сервер 1:

Meteor.methods({
    'reporting.default'(subReport, params) {
        this.unblock();
        return Meteor.callWorker('reporting.' + subReport, Meteor.callId(), params).then((result, error) => { if (error) return error; else return result; }).await();
    },
});

Meteor.worker = DDP.connect('localhost:' + Meteor.settings.heavyTasksServer.port);
Meteor.callWorker = (method, ...myParameters) => new Promise((resolve, reject) => {
    console.log(method + ": REQUEST");
    Meteor.worker.call(method, ...myParameters, (err, res) => {
        if (err) {
            console.log(method + ": ERROR");
            reject(err);
        }
        else {
            console.log(method + ": ANSWER");
            resolve(res);
        }
    });
});

Meteor.callId = function () {
    const d =new Date();
    return d.getUTCFullYear() +""+ (d.getUTCMonth()+1) +""+ d.getUTCDate() +""+ d.getUTCHours() +""+ d.getUTCMinutes() +""+ d.getUTCSeconds() +""+ d.getUTCMilliseconds() + "-" + Meteor.userId();
};

Сервер 2:

Meteor.methods({
    'reporting.clientsAssets'(callId, params) {
        this.unblock();
        const funcName = "reporting.clientsAssets";
        if (canRunQuery(1, callId, arguments, funcName)) {
            console.log(funcName + ": START");
            const data = reportingClientsAssets(params);
            console.log(funcName + ": END");
            terminateQuery(callId);
            return data;
        }
    }
});

1 Ответ

0 голосов
/ 27 июня 2019

Вы можете рассмотреть асинхронную модель вместо синхронной (которая, вероятно, имеет тайм-аут).

Давайте подумаем о механизме организации очередей ... создадим задания для сбора вызовов (или что бы вы ни предпочли), а сервер 1 создаст запись в наборе заданий со статусом «готово».

Временная задача (для этого вы можете использовать node-cron) запускается на сервере 2, скажем, каждую минуту, и ищет задания со статусом «готово». Он берет первый, устанавливает статус «работает» и затем вызывает функцию для выполнения работы.

Когда эта функция завершается, она устанавливает статус задачи на «завершена».

Вы используете реактивность Метеора, чтобы пользователь мог видеть состояние задания, после того, как оно запущено, оно переходит к «выполнению», а затем к «завершению», как только оно выполнено. В этот момент может появиться ссылка, чтобы у них был доступ к данным, отчету или тому, что было создано.

Нет проблем с тайм-аутом с этим механизмом, и он прекрасно отделен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...