Функция Firestore в облаке занимает несколько минут для инициализации и выполнения первых запросов. - PullRequest
1 голос
/ 05 мая 2020

Для этого простого запроса Firestore, выполняемого в облачной функции, всегда требуется много времени, если мы не вызывали его какое-то время и нам нужно создать новое клиентское соединение (самое долгое время было 100+ секунд)

Ниже приведен минимальный воспроизводимый index.ts и подробный журнал. Я пробовал использовать как admin.firestore(), так и new Firestore({ grpc }) и получил аналогичный результат.

import {https, config} from 'firebase-functions';
import * as admin from "firebase-admin";
const { Firestore } = require('@google-cloud/firestore');
const grpc = require('@grpc/grpc-js');

let initialized = false;

exports.timeQuery = https.onRequest(async (req:any, res) => {
        res.json({received: true});

    if (!initialized) {
      admin.initializeApp(config().firebase);
      admin.firestore.setLogFunction(console.log);
      initialized = true;
    }
    // using gRPC
    console.log('using gRPC via @google-cloud/firestore')
    const db = new Firestore({ grpc });
    // using admin node SDK
    // const db = admin.firestore();

    await db.collection("debugCollection")
        .doc("debug")
        .get();
    }
  );

Я включил ведение журнала отладки в Firestore и обнаружил, что инициализация клиента Firestore GAPI C заняла 47 секунд.

Firestore (3.7.5) 2020-05-04T20:37:23.541Z ##### [Firestore]: Initialized Firestore GAPIC Client
  1:36:36.054 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:36:36.054Z peRnr [ClientPool.acquire]: Creating a new client

и между отправкой запросов и получением ответа на запрос прошло еще 35 секунд.

Firestore (3.7.5) 2020-05-04T20:38:00.139Z peRnr [Firestore.requestStream]: Received response: {"transaction":{"type":"Buffer","data":[]},"readTime":{"seconds":"1588624676","nanos":86619000},"missing":"projects/xxxxxxxx-my-project-id/databases/(default)/documents/debugCollection/debug","result":"missing"}
  1:37:25.141 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:37:25.141Z peRnr [Firestore.requestStream]: Sending request: {"database":"projects/xxxxxxxx-my-project-id/databases/(default)","documents":["projects/xxxxxxxx-my-project-id/databases/(default)/documents/debugCollection/debug"]}

Вот подробные журналы.


  1:38:05.440 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:38:05.440Z peRnr [Firestore.getAll_]: Received 1 results
  1:38:05.240 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:38:05.240Z peRnr [Firestore._initializeStream]: Received stream end
  1:38:00.340 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:38:00.340Z peRnr [Firestore.getAll_]: Document missing: projects/xxxxxxxx-my-project-id/databases/(default)/documents/debugCollection/debug
  1:38:00.141 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:38:00.140Z peRnr [Firestore._initializeStream]: Releasing stream
  1:38:00.141 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:38:00.139Z peRnr [Firestore.requestStream]: Received response: {"transaction":{"type":"Buffer","data":[]},"readTime":{"seconds":"1588624676","nanos":86619000},"missing":"projects/lovecaster-staging/databases/(default)/documents/debugCollection/debug","result":"missing"}
  1:37:25.141 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:37:25.141Z peRnr [Firestore.requestStream]: Sending request: {"database":"projects/xxxxxxxx-my-project-id/databases/(default)","documents":["projects/xxxxxxxx-my-project-id/databases/(default)/documents/debugCollection/debug"]}
  1:37:25.140 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:37:25.140Z peRnr [ClientPool.acquire]: Re-using existing client with 100 remaining operations
  1:37:24.440 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:37:24.440Z ##### [Firestore.initializeIfNeeded]: Detected project ID: xxxxxxxxxxx-my-projectID
  1:37:23.541 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:37:23.541Z ##### [Firestore]: Initialized Firestore GAPIC Client
  1:36:36.054 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:36:36.054Z peRnr [ClientPool.acquire]: Creating a new client
  1:36:36.052 PM
  timeQuery
  Firestore (3.7.5) 2020-05-04T20:36:36.051Z ##### [Firestore]: Initialized Firestore
  1:36:36.050 PM
  timeQuery
  using gRPC via @google-cloud/firestore
  1:36:36.043 PM
  timeQuery
  Function execution took 54 ms, finished with status code: 200
  1:36:35.989 PM
  timeQuery
  Function execution started

И узел версии пакета: "firebase-admin": "^8.11.0", "@grpc/grpc-js": "0.8.1", "@google-cloud/firestore": "3.7.5",

1 Ответ

0 голосов
/ 05 мая 2020

Ваша функция ведет себя так, потому что вы отправляете ответ до того, как вся работа будет завершена. Согласно документации , функция завершается сразу после отправки ответа. Любая другая работа после этого может не завершиться sh правильно. Итак, ваш вызов res.json({received: true}); должен быть самым последним в функции.

Если вы хотите, чтобы ваша функция вместо этого отправляла ответ немедленно клиенту и продолжала работать помимо этого, вы не сможете сделать это с помощью одной функции HTTP. Вместо этого вам придется переложить эту работу на другую службу или функцию. Обычно в функцию pubsub отправляют сообщение, чтобы оно находилось в фоновом режиме там, где остановилась первая функция.

...