首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防火墙功能:如何维护“应用-全局”API客户端?

防火墙功能:如何维护“应用-全局”API客户端?
EN

Stack Overflow用户
提问于 2021-09-27 20:21:16
回答 1查看 95关注 0票数 2

如何实现跨云函数实例和函数调用共享的“应用程序范围”全局变量?我想要创建一个真正的“全局”对象,它在所有函数的生命周期内只初始化一次。

上下文:

我的应用程序的整个后端是Firestore + Firebase函数。也就是说,我使用背景触发器和HTTP函数的组合来实现后端逻辑。另外,我依赖第三方定位服务来不断地听传感器的位置更新。我只想要一个客户端的一个实例来订阅这些更新。

问题是Firebase/Google 云功能是无状态的。,这意味着函数实例不共享内存/对象/状态。如果我调用functionA、functionB、functionC,将至少创建3个locationService客户端实例,每个实例分别侦听第三方服务,因此我们最终会重复调用location回调。

样本代码:

代码语言:javascript
复制
// index.js
const functions = require("firebase-functions");

exports.locationService = require('./location_service');

this.locationService.initClient();

// define callable/HTTP functions & Firestore triggers
...

代码语言:javascript
复制
// location_service.js
var tracker = require("third-party-tracker-js");

const self = (module.exports = {
    initClient: function () {
        tracker.initialize('apiKey')
        .then((client)=>{
            client.setCallback(async function(payload) {
                console.log("received location update: ", payload)
                // process the payload ...
                // with multiple function instances running at once, we receive as many callbacks for each location update
            })

            client.subscribeProject()
            .then((subscription)=>{
                subscription.subscribe()
                .then((subscribeMsg)=>{
                    console.log("subscribed to project with message: ", subscribeMsg); // success
                });
                // subscription.unsubscribe(); // ??? at what point should we unsubscribe?
            })
            .catch((err)=>{
                throw(err)
            })
        })
        .catch((err)=>{
            throw(err)
        })
    },

});

我意识到,我所要做的,大致相当于在一个进程环境中实现一个守护进程,而像Firebase/Google函数这样的无服务器环境似乎并不是为了支持这种需求而设计的,因为每个实例都是作为自己的进程运行的。但我希望听到任何相反的想法和可能的解决办法。

另一个想法..。

受此相关SO关于无状态函数的官方GCF文档的启发,我考虑使用Firestore来持久化跟踪器值,该值允许我们有条件地初始化API客户端。大致如下:

代码语言:javascript
复制
// read value from db; only initialize the client if there's no valid subscription
let locSubscriberActive = await getSubscribeStatusFromDb();

if (!locSubscriberActive) {
   this.locationService.initClient();
}

// in `location_service.js`, do setSubscribeStatusToDb(); // set flag to true when we call subscribe(). reset when we get terminated

所面临的问题:我在什么时候解除/重置这个值?直观地说,当初始化客户端的函数实例被回收/终止时,我就会这么做。但是,似乎不可能知道Firebase函数实例何时终止?我到处找,但找不到关于如何发现这样的事件的文档.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-28 15:06:37

您想要做的是在云函数中完全不支持。重要的是要认识到,可能为每个已部署的功能分配了任意数量的服务器实例。这就是云功能如何向上和向下扩展,以符合成本效益的方式与功能上的负载相匹配。这些实例可能因任何原因而在任何时候终止。您无法指示实例何时终止。

此外,实例在空闲时无法执行任何计算。CPU资源在函数终止后被限制,并在调用该实例上的下一个函数时再次旋转。当没有主动调用函数时,您不能运行任何“守护程序”代码。我不知道您的locationService是做什么的,但是在函数终止之后,它肯定什么也不做,不管它是如何终止的。

对于任何类型的长时间运行或类似守护进程的代码,云函数都不是一个合适的产品。相反,您还应该考虑使用另一种产品,使您能够在不中断的情况下运行代码24/7。App引擎和Compute引擎是可行的替代方案,您必须仔细考虑是否以及如何让它们的服务器实例随负载进行扩展。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69352819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档