Подтвердить что ты не робот

Облачные функции для Firebase и Express

Документы Firebase для пространства имен functions.https показывают, что функция принимает объект express.Request и объект express.Response. Нигде не упоминается, что вы можете передать объект экспресс-сервера в functions.https.onRequest. Тем не менее, я обнаружил, что люди делали это без каких-либо четких указаний от комментаторов, что это не должно быть сделано (за исключением одного человека в потоке functions-samples репо № 101)

см

Мои вопросы:

  • Как облачные функции для облачных функций Firebase или GCP обрабатывают время жизни объектов, инициализированных вне определения функции?
  • Как это влияет на время жизни функции? Выполняется ли оно до тайм-аута или работает аналогично AWS Lambda?

Разъяснение для 1 и 2: в Lambda любые ресурсы вне экспортируемой функции используются во всех последующих вызовах одного и того же экземпляра Lambda, в то время как этот экземпляр функции является "теплым". Это означает, что на время отклика функции не оказывает отрицательного влияния какой-либо сложный код инициализации, который вы можете иметь заранее, как это делается один раз на "теплый" экземпляр. В этом примере не нужно будет инициализировать сервер ExpressJS каждый вызов, только один раз, когда функция "тепла". Мне любопытно, делают ли облачные функции то же самое?

Кроме того, в Lambda существование сервера ExpressJS не увеличивает время выполнения функции (когда оно возвращается), мне также любопытно, как здесь реализованы облачные функции. Он просто делает то же самое, что и Lambda, или (потому что он может обрабатывать существующие объекты по-разному) делает ли он что-то еще?

  1. Документация functions.https.onRequest не указывает, что вы можете передать в нее объект сервера ExpressJS, так как это работает? Есть ли тогда два конечных точки? Может кто-нибудь объяснить, что здесь происходит?

Уточнение для 3: Я видел, как люди делают следующее:

// './functions/index.js'

var functions = require("firebase-functions");
const express = require("express");

// setup ExpressJS Server
const expressRouter = new express.Router();
expressRouter.get("*", (req, res) => {
  res.send(`Hello from Express in Cloud Functions for Firebase`);
});

// Cloud Function
exports.express = functions.https.onRequest(expressRouter);
4b9b3361

Ответ 1

Все это работает, потому что под обложками приложение Express фактически является просто функцией, которая принимает HTTP-запрос < Node.js HTTP и реагирует на них с помощью некоторого автоматического сахарирования, такого как маршрутизация. Таким образом, вы можете передать Express-маршрутизатор или приложение в обработчик облачной функции без проблем, поскольку объекты Express req и res совместимы со стандартными версиями Node.js. В принципе, это приложение "Double Express", в котором одно приложение вызывает другое.

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

Вы можете создавать ресурсы (например, приложение Express) вне вызова функции, и он будет выполняться, когда ресурсы вычислений будут развернуты для этой функции. Это сохранится до тех пор, пока это произойдет; тем не менее, ЦПУ/сеть дросселируются до нулевого уровня между вызовами, поэтому вы не можете выполнять "работу" вне жизненного цикла вызова функции. Как только обещание будет разрешено (или вы ответили на запрос HTTP), ваши ресурсы вычислений будут зажаты с помощью дросселирования и могут быть прекращены в любой момент.

Ответ 2

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

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