web-dev-qa-db-fra.com

Fonctions cloud pour Firebase et Express

Les documents Firebase pour l'espace de noms functions.https Montrent que la fonction accepte un objet express.Request Et un objet express.Response. Nulle part cela ne mentionne que vous pouvez passer un objet serveur express à functions.https.onRequest. Cependant, j'ai constaté que les gens l'ont fait sans indication claire des commentateurs que cela ne devrait pas être fait (sauf une personne dans le fil # 101 du problème de dépôt functions-samples)

voir:

Mes questions sont alors:

  1. Comment les fonctions cloud pour Firebase ou GCP Cloud Functions gèrent-elles la durée de vie des objets initialisés en dehors de la définition de la fonction?
  2. Comment ce qui précède affecte-t-il la durée de vie de la fonction? Exécute-t-il jusqu'à l'expiration ou fonctionne-t-il de manière similaire à AWS Lambda?

Clarification pour 1 et 2: dans Lambda, toutes les ressources en dehors de la fonction exportée sont utilisées pour toutes les invocations ultérieures de la même instance Lambda alors que cette instance de fonction est "à chaud". Cela signifie que le temps de réponse de la fonction n'est pas affecté négativement par un code d'initialisation complexe que vous pourriez avoir à l'avance car il est effectué une fois par instance "chaude". Dans cet exemple, il n'aurait alors pas besoin d'initialiser un serveur ExpressJS à chaque appel, une seule fois alors que la fonction est "chaude". Je suis curieux de savoir si les fonctions cloud font de même?

Toujours dans Lambda, l'existence du serveur ExpressJS ne prolonge pas le temps d'exécution de la fonction (quand il revient c'est fait), je suis également curieux de savoir comment les fonctions cloud sont implémentées ici. Fait-il simplement la même chose que Lambda, ou (parce qu'il peut gérer différemment les objets existants) fait-il autre chose?

  1. La documentation functions.https.onRequest Ne spécifie pas que vous pouvez y passer un objet serveur ExpressJS, alors comment cela fonctionne-t-il? Y a-t-il alors deux points finaux? Quelqu'un peut-il expliquer ce qui se passe ici?

Clarification pour 3: j'ai vu des gens faire ce qui suit:

// './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);

Et je souhaite savoir comment cela fonctionne étant donné que l'API Cloud Functions spécifie uniquement l'acceptation des paramètres functions.https.onRequest(request, response) modélisés d'après l'API ExpressJS.

Ces paramètres sont basés sur les objets Express Request et Response - firebase.google.com/docs/functions/http-events

Étant donné que toutes les questions se rapportent à l'extrait de code unique et à ce cas d'utilisation, j'ai pensé qu'il serait préférable de répondre ensemble.

Merci d'avance :)

22
jthegedus

Tout cela fonctionne parce que sous les couvertures, une application Express n'est en fait qu'une fonction qui prend une demande et une réponse HTTP Node.js et agit sur elles avec un sucre automatique tel que le routage. Vous pouvez donc transmettre sans problème un routeur ou une application Express à un gestionnaire de fonctions cloud, car les objets req et res d'Express sont compatibles avec les versions standard de Node.js. Fondamentalement, c'est une application "double Express" où une application en appelle une autre.

En ce qui concerne le cycle de vie des fonctions et l'état partagé: les fonctions sont générées dans des instances de calcul éphémères qui peuvent survivre pour traiter plusieurs demandes, mais pas. Vous ne pouvez pas régler ou garantir si une fonction sera invoquée ou non dans la même instance de calcul d'une invocation à la suivante.

Vous pouvez créer des ressources (telles qu'une application Express) en dehors de l'invocation de la fonction et elle sera exécutée lorsque les ressources de calcul seront augmentées pour cette fonction. Cela survivra aussi longtemps que l'instance le fera; cependant, le CPU/réseau est limité à zéro entre les invocations, vous ne pouvez donc pas faire de "travail" en dehors du cycle de vie d'une invocation de fonction. Une fois la promesse résolue (ou que vous avez répondu à la demande HTTP), vos ressources de calcul seront bloquées via la limitation et peut se terminer à tout moment.

26
Michael Bleigh

Vous ne devez pas vous attendre à conserver une ressource au-delà de la durée de vie d'une fonction. Vous devez vous attendre à ce que le conteneur se nettoie complètement une fois que la promesse finale de la fonction a été résolue ou que la réponse HTTP a été entièrement envoyée. Il n'y a aucun état partagé entre les invocations de fonction. C'est la seule façon dont les fonctions cloud peuvent évoluer. Si vous avez besoin d'un état partagé, stockez-le dans la base de données et lisez-le à chaque appel, en le protégeant avec une transaction si nécessaire.

Je ne sais pas ce que vous demandez dans la troisième question. Cela semble en quelque sorte sans rapport avec les deux premières questions - peut-être que ce devrait être sa propre question? Pour autant que je sache, il n'y a qu'un seul point de terminaison pour votre backend.

4
Doug Stevenson