Работа Cron не удалась без причины

Я нахожусь в ситуации, когда у меня есть задача CRON в движке приложения Google (с использованием гибкой среды), которая просто умирает по истечении времени немного, но у меня нет следов, ПОЧЕМУ (проверил журналы GA, ничего, попробовал попробовать / поймать и явно зарегистрировать его - Нет ошибки).

Я явно подтвердил, что если я создам задачу cron, которая выполняется в течение 8 минут (но мало что делает - просто спит и обновляет базу данных каждую секунду), она будет работать успешно. Это просто доказательство того, что задания CRON могут выполняться не менее 8 минут, если не больше., и я правильно настроил комбинацию Express и NodeJS.

Все в порядке, но похоже, что моя работа cron разное умирает через 2-3 минуты, так что довольно быстро. Он достигает какого-то предела, но я понятия не имею, как его контролировать или даже какой это предел, поэтому все, что я могу делать, - это строить предположения.

Расскажу подробнее о своей задаче CRON. По сути, это быстрый запрос к базе данных MongoDB, причем каждый запрос выполняется довольно быстро. Я пробовал тот же код локально, и проблем нет.

Я предполагаю, что я каким-то образом создаю слишком много запросов MongoDB одновременно и, возможно, у меня что-то заканчивается?

Вот псевдокод (просто чтобы описать, о каких масштабных данных мы говорим - числа и поток точно такие же):

function q1() {
      return await mongoExecute(async (db) => {
        const [l1, l2] = await Promise.all([
            db.collection('Obj1').count({uid1: c1, u2action: 'L'}),
            db.collection('Obj1').count({uid2: c2, u1action: 'L'}),
        ]);

        return l1+l2;
    });
}

for(let i = 0; i < 8000; i++) {
   const allImportantInformation = Promise.all([
       q1(),
       q2(),
       q3(),
       .....
       q10()
   ])

   await mongoDb.saveToServer(document);
}

Это происходит где-то вокруг i=1600, прежде чем работа CRON просто умирает без каких-либо объяснений. На панели заданий GA Cron четко указано, что задание не выполнено.

Вот также мой mongoExecute (это просто отдельный модуль, который кэширует объект db, что, надеюсь, является правильной практикой для обеспечения правильной работы пула mongodb.)

import { MongoClient, Db } from 'mongodb';

let db = null;
let promiseInProgress = null;

export async function mongoExecute<T> (executor: (instance: Db) => T): Promise<T | null> {

    if (!db) {
        if (!promiseInProgress) {
            promiseInProgress = new Promise(async (resolve, reject) => {
                const tempDb = await MongoClient.connect(process.env.MONGODB_URL);
                resolve(tempDb);
            });
        }

        db = await promiseInProgress;
    }
    try {
        const value = await executor(db);
        return value;
    } catch (error) {
        console.info(error);
        return null;
    }
}

Какое было бы решение? Моя идея состоит в том, чтобы обеспечить одновременное выполнение меньшего количества запросов (чтобы все обещания были последовательными и потенциально добавляли сон между каждым циклом в FOR.

Я не понимаю, потому что он отлично работает до определенной точки (и довольно большой, это определенно другое количество, иногда 800, иногда 1200 и т. д.).

Происходит ли какой-либо сценарий «исчерпания TCP-соединений»? Теоретически у нас не должно ничего заканчиваться, потому что в любой момент у нас мало открытых.

Кажется, работает, если я бросаю 200 мс ожидания между каждым циклом & Я подозреваю, что могу найти решение, все элементы не нужно обновлять в одном и том же выполнении CRON, но это немного раздражает, и я хотел бы знать, что происходит.

Сборщик мусора не догоняет достаточно быстро, почему именно GA молча терпит неудачу в моей задаче cron?

Я предполагаю, что код MongoClient.connect() вызывается быстро, поэтому задание потребляет слишком много TCP-соединений, поскольку connect() в драйвере узла по умолчанию создает пул соединений, содержащий 5 соединений. Это могло бы объяснить, почему ожидание в 200 мс заставляет его работать, поскольку код обнаружил, что db больше не является нулевым, поэтому он не запускает метод connect() и правильно использует существующий пул соединений. По сути, без ожидания код быстро создает множество пулов соединений. С ожиданием он создает только один пул соединений.

kevinadi 10.01.2019 01:04

Вы можете проверить, действительно ли это так, переместив код MongoClient.connect() за пределы MongoExecute в основную часть кода. Передайте объект db в каждую функцию q(). В любом случае это лучшая практика, MongoClient.connect() должен вызываться только один раз за выполнение приложения, поскольку он создает пул соединений вместо одного соединения с базой данных.

kevinadi 10.01.2019 01:12

Это интересная теория, хотя, насколько я понимаю, выполнение задания CRON является однопоточным (поскольку JS является однопоточным), что означает отсутствие состояния гонки (и MongoClient.connect следует вызывать только один раз). Тем не менее, на самом деле это не повредит, так что я попробую. Спасибо

Erti-Chris Eelmaa 10.01.2019 09:55

@KevinAdistambha Я пробовал это, но это ожидаемо: mongoExecute () всегда создает только одно соединение во время жизни приложения, независимо от того, насколько быстро выполняется mongoExecute (). Я также исправил проблему, обновив драйвер mongodb.

Erti-Chris Eelmaa 10.01.2019 12:05
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
228
1

Ответы 1

Я обнаружил, в чем заключается ошибка, и исправил ее соответствующим образом.

Позвольте мне перефразировать это; Я понятия не имею, в чем была ошибка, и отсутствие ошибок в какой-либо момент обескураживало, однако мне удалось исправить (удачное предположение) все, что происходило, обновив мой драйвер nodejs mongodb до последней версии (с 2.xx -> 3.1. 10).

В моем коде больше не требуется сна.

Другие вопросы по теме