Я нахожусь в ситуации, когда у меня есть задача CRON в движке приложений Google (с использованием среды Flex), которая просто умирает после некоторого времени, но у меня нет следа ПОЧЕМУ (проверил журналы 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 Job четко говорит, что JOB провалился.
Здесь также находится мой 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.log(error);
return null;
}
}
Каким было бы решение? Моя идея состоит в том, чтобы в основном обеспечить одновременное выполнение меньшего количества запросов (чтобы все обещания были последовательными и потенциально добавляли сон между циклами в FOR.
Я не понимаю, потому что он работает хорошо до определенного момента (и довольно большой момент, это определенно другое количество, иногда это 800, иногда 1200 и т. Д.).
Имеется ли сценарий "исчерпание TCP-соединений"? Теоретически у нас не должно быть ничего, потому что у нас мало открытых в любой момент.
Кажется, это работает, если я выбрасываю ожидание 200 мс между каждым циклом и я подозреваю, что могу найти решение, все элементы не должны обновляться в одном и том же выполнении CRON, но это немного раздражает, и я хотел бы знать, что происходит.
Сборщик мусора недостаточно быстро догоняет, почему именно GA молча проваливает мою задачу cron?