Firebase Functions 2代:如何在X分钟后丢弃重试事件?
Firebase Functions 1代转2代:事件时间戳获取与重试配置方案
一、获取事件时间戳(替代1代context.timestamp)
在2代Pub/Sub函数的event对象中,有两个符合RFC3339格式的时间戳可用,和1代格式完全兼容:
event.timestamp:事件触发的时间戳event.data.message.publishTime:Pub/Sub消息本身的发布时间戳
你可根据需求选择,比如要判断消息从发布到处理的时长,用publishTime更准确;要判断事件触发到处理的时长,用event.timestamp即可。
修改适配2代的shouldDropEvent函数:
function shouldDropEvent(event, maxAgeMs = retryEventMaxAgeMs) { // 根据需求选择时间戳字段 const eventTimestamp = event.data.message.publishTime; const eventAge = Date.now() - Date.parse(eventTimestamp); if (eventAge > maxAgeMs) { console.error( new Error( `Dropping event ${event.eventType} for ${event.resource.name} because max age was reached.` ) ); return true; } return false; }
二、配置重试行为(替代1代failurePolicy)
2代函数的重试配置比1代更精细化,除基础开关外,还支持自定义重试次数、退避策略等参数:
- 基础重试:设置
retry: true即可开启,等效于1代的failurePolicy: true - 进阶配置:通过
retryConfig设置具体规则,比如最大重试次数、最长重试时长、退避模式等
示例配置:
export const sendNotificationToUserToken_2ndGen = onMessagePublished( { topic: pubSendNotificationToUserToken.topic, // 基础重试开关 retry: true, // 精细化重试规则(可选) retryConfig: { maxAttempts: 5, // 最大重试次数(含首次尝试) maxRetrySeconds: 1200, // 最长重试时长(20分钟,与你的retryEventMaxAgeMs对应) backoffMode: "EXPONENTIAL", // 退避模式:EXPONENTIAL(指数)/ LINEAR(线性) minBackoffSeconds: 60, // 最小退避间隔 maxBackoffSeconds: 600, // 最大退避间隔 }, }, async (event) => { // 加入事件过期判断逻辑 if (shouldDropEvent(event, MINUTE_MS * 5)) { return; } await pubSendNotificationToUserToken.handle(event.data.message.json); } );
完整修改后的代码
import { pubSendNotificationToUserToken } from "@repo/core/notifications"; import { onMessagePublished } from "firebase-functions/v2/pubsub"; const MINUTE_MS = 60 * 1000; export const retryEventMaxAgeMs = 20 * MINUTE_MS; export const sendNotificationToUserToken_2ndGen = onMessagePublished( { topic: pubSendNotificationToUserToken.topic, retry: true, retryConfig: { maxRetrySeconds: retryEventMaxAgeMs / 1000, // 转换为秒单位 maxAttempts: 5, backoffMode: "EXPONENTIAL", }, }, async (event) => { if (shouldDropEvent(event, MINUTE_MS * 5)) { return; } await pubSendNotificationToUserToken.handle(event.data.message.json); } ); /** * 判断事件是否超过最大存活时长 */ function shouldDropEvent(event, maxAgeMs = retryEventMaxAgeMs) { const eventTimestamp = event.data.message.publishTime; const eventAge = Date.now() - Date.parse(eventTimestamp); if (eventAge > maxAgeMs) { console.error( new Error( `Dropping event ${event.eventType} for ${event.resource.name} because max age was reached.` ) ); return true; } return false; }
内容的提问来源于stack exchange,提问作者Thijs Koerselman
相关产品推荐
相关产品推荐

