Вызов Flutter для облачной функции разрешается в исключении облачной функции DEADLINE_EXCEEDED - PullRequest
0 голосов
/ 27 мая 2020

У меня проблема с вызовом облачной функции из Flutter. В этой облачной функции я делаю разные вещи, например, безопасный поиск, проверяющий изображение с помощью ML-Vision ImageAnnotatorClient, добавляя документ в Firestore или обновляя метаданные для файла хранилища. Обычно все это работает нормально, но почти каждый раз, когда устройство через некоторое время впервые вызывает эту функцию, происходит сбой CloudFunctionException DEADLINE_EXCEEDED. В каждой другой попытке он работает нормально без каких-либо проблем. Есть ли у кого-нибудь идеи, что могло его вызвать?

Я читал, что есть «холодный старт» функции, из-за которого функция требует гораздо больше времени для выполнения. Но, тем не менее, он всегда выполняется менее чем за 10 секунд, поэтому тайм-аут здесь не кажется проблемой.

Так я вызываю функцию Flutter Cloud

final HttpsCallable callable = _cloudFunctions.getHttpsCallable(
  functionName: 'function',
);

dynamic resp = await callable.call({'prop1': prop1String, 'prop2': prop2String});

Это содержимое облачной функции

exports.function = functions.https.onCall(async (req, context) => {
    if (!context.auth) return {status: 'ERROR', code: 401, body: 'Not signed in'};

    const [result] = await client.safeSearchDetection(req.url);
    const detections = result.safeSearchAnnotation;
    if (detections) {
        if (detections.adult === 'VERY_LIKELY') {
            const storage = new Storage();
            await storage
                .bucket('xxx.appspot.com/')
                .file(req.filename)
                .delete();
            return {status: 'ERROR', code: 400, body: 'NSFW'};
        }
    }

    return refs.add({
        'prop1': req.prop2,
        'prop2': req.prop1
    })
        .then(async () => {
            const images = [];
            const query = await refs
                .where('prop1', '==', req.prop1)
                .get();
            query.forEach((document) => images.push(document));
            if (images.length > 0) {
                const docRef = refs.doc(images[0].id);
                const filename = images[0['_fieldsProto']['filename']['stringValue'];
                const storage = new Storage();
                await storage
                    .bucket('xxx.appspot.com/')
                    .file(filename)
                    .setMetadata({metadata: {receiver: req.uid}});
                docRef.update({'receiver': req.uid, 'receivedTimestamp': FieldValue.serverTimestamp()});
                return {status: 'OK', code: 200, body: images[0]};
            } else {
                return {status: 'OK', code: 200, body: null};
            }
        })
        .catch(err => {
            console.log(err);
            return {status: 'ERROR', code: 500, body: 'failed to create ref in firestore'};
        });
});

В коде Flutter возникает ошибка при вызове вызываемого объекта.

1 Ответ

1 голос
/ 03 июня 2020

Я не мог понять, какой вызов вызывает эту ошибку, но есть несколько вещей, которые вы можете сделать, чтобы обойти это.

  • Увеличьте объем памяти и таймаут вашей функции.

Ваша функция в настоящее время работает с настройками по умолчанию, которые составляют 128 МБ памяти и 60 секунд до тайм-аута. Вы можете изменить это значение до 2 ГБ и 540, обратите внимание, что это повлияет на ваш биллинг. Вы можете реализовать это, выполнив следующие действия:

const runtimeOpts = {
    timeoutSeconds: 300,
    memory: '1GB'
}
exports.function = functions.runWith(runtimeOpts).https.onCall(...)

Также здесь документация с более подробной информацией об этом.

  • Увеличьте время ожидания вашего Firestore вызывает

. Вы можете добавить следующий код в инициализацию своего хранилища, заменив YOUR_NUMBER_HERE, чтобы увеличить время до тайм-аута (по умолчанию 60000 или 1 минута), это также может повлиять на ваш счет:

const firestore = new Firestore({
      clientConfig: {
        interfaces: {
          'google.firestore.v1.Firestore': {
              methods: {
                RunQuery: {
                  timeout_millis: YOUR_NUMBER_HERE
                }
              }
            }
          }
        }
      });

Сообщите мне, решило ли это проблему.

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