我有一个React web应用程序,它使用Firestore作为数据库,每个Firestore集合有多个(10+(Firebase函数,用于消除副作用,如发布到社交媒体等:
exports.onUserSignUp = functions.auth.user().onCreate(user => {
// Insert into users collection
// Insert into profiles collection
// Notify via Discord webhook
// insert into history collection to keep track of actions performed by users
})
exports.onCityCreate = functions.firestore.document('cities/{cityId}').onCreate(doc => {
// Notify via Discord webhook
// Send tweet
// Update cache in a collection
// Insert into history collection to keep track of actions performed by users
})
等等。
在Firebase函数教程中,他们经常建议您为以下副作用声明Firebase函数:
exports.onCityCreate = functions.firestore.document('/cities/{documentId}')
.onCreate((snap, context) => {
...
})
如果你有一个小的副作用,比如通过Twitter REST API发送推文,这是有道理的,但随着时间的推移,我添加了越来越多的副作用——比如通过webhook发送到Discord,将新记录插入其他数据库,缓存数据等等。
当我在AWS中学习lambdas时,我被教导要使我的函数变小,并限制在一个工作中,而不是一个大函数。这意味着,如果一个副作用失败,它不会降低其他副作用。它使代码更易于理解和阅读。它使调试更加容易。
因此,上面的函数可以分解为每个作业:
exports.sendTweetOnCityCreate = functions.firestore.document('cities/{cityId}').onCreate(doc => {
// send tweet via REST API
})
exports.sendDiscordOnCityCreate = functions.firestore.document('cities/{cityId}').onCreate(doc => {
// send Discord message via webhook
})
exports.updateCitiesCache = functions.firestore.document('cities/{cityId}').onCreate(doc => {
// update a record in a cache collection with some kind of tally etc.
})
exports.recordCityInHistory = functions.firestore.document('cities/{cityId}').onCreate(doc => {
// insert into history collection to keep track of actions performed by users
})
为每个副作用声明一个小的、独立的函数,而不是一个大的函数,是否会受到惩罚(性能-较慢或财务-谷歌的成本更高(;做所有的";就像我现在一样
性能不会有明显变化。无论您有多少函数,事件从Firestore传递到函数所需的时间基本上都是相同的。
一体式方法最糟糕的情况是,您的函数没有大规模扩展,因为每个函数处理其事件的并发服务器实例上限为1000个。但这是相当多的例子。如果您将功能拆分,每个功能将能够扩展到1000个服务器实例。不过,这只会在非常大规模的情况下有用。