如何创建动态计划任务?
Posted
技术标签:
【中文标题】如何创建动态计划任务?【英文标题】:How to create a dynamically scheduled task? 【发布时间】:2021-03-30 04:46:56 【问题描述】:我正在尝试创建一个模拟在酒吧打开标签的应用程序。我遇到了一个我似乎无法弄清楚的问题 - 它如下:
当有人打开一个栏标签时,动态创建一个计划任务,该任务执行代码以在 24 小时后关闭该标签。
如果选项卡在 24 小时前关闭,请取消计划任务。
-
如果标签在 24 小时后没有关闭,请执行步骤 1 中描述的代码,以在用于打开标签的卡上发起付款。
我最初正在研究 Firebase 函数,并正在考虑使用 setTimeout() 可调用函数,但在做了一些研究后,我发现 Firebase 函数的调用时间不能超过 9 分钟。
注意:我希望这是动态的。意思是,让它占不同数量的用户。平台上可能有 100 或 1000 个用户,每个用户都需要能够为他们设置一个唯一的计划任务(有时每个用户有多个)。
【问题讨论】:
我可以提供一些关于写好问题的小技巧吗?除非您定义“最佳”的客观标准,否则要求“最佳方式”是非常主观的。只需将您的问题表述为“我如何创建动态计划任务”。此外,诸如“请让我知道您认为解决此问题的最佳解决方案是什么”之类的陈述是无用的,可以省略。我们都知道您想要一个答案……因为您提出了一个问题。 【参考方案1】:请查看 cmets 以获得完整的解决方案。
有多种方法可以规避 10 分钟规则(这在无服务器代码中很普遍),但这里有一些可以帮助您的方法。我建议将任务分为三个:
-
调用时关闭选项卡的云函数。
调用它的调度函数 (https://firebase.google.com/docs/functions/schedule-functions)
一种启动和停止计划功能的方法。
我不确定 firebase 函数是如何工作的,但我之前使用过 azure 函数,并且可以使用命令行 (CLI) 或使用您选择的语言的 sdk 来控制这些函数。要使用命令行取消,请尝试以下操作:
firebase functions:delete scheduledFunction
来自How to cancel a scheduled firebase function?。
现在剩下的就是如何弄清楚如何启动函数,以及是否可以传入参数来调度它。
祝你好运!
【讨论】:
感谢您的回复!我还有几个问题。创建计划功能后,我是否能够动态创建这些功能(对于多个用户,并将必要的付款信息传递给这些计划功能)?另外,有没有办法唯一标识计划任务,以便在用户关闭选项卡时我可以专门将其删除? @Devon 我对云功能不太熟悉,但是您可以使用名称唯一地识别它们。在 azure world 中有一个唯一的 instance id,但我不确定它是否可用。我建议不要直接在预定功能上传递付款/用户信息。您应该将其存储在数据库中,并让主要的云功能来处理它 关于支付信息,我正在使用 Stripe 的 API,因此可以在那里安全地处理。我只是将用户的客户 ID 传递给调度程序。我想我仍然不太确定的是,假设用户 A 在晚上 8 点打开一个标签,而用户 B 在晚上 8:30 打开一个标签 - 我正在寻找一个动态计划的功能,让两个用户完全关闭他们的标签24 小时后(分别为晚上 8 点和晚上 8:30)。这个解决方案可以为我做到这一点吗?我可能在这里遗漏了一些东西。感谢您的所有帮助。 @Devon 是的,仅将客户 ID 传递给调度程序是安全的。通常它是一个 POST 请求来启动它,您可以将该信息放在正文中。我想到的是为每个用户创建一个功能。因此,您应该有一个名为 scheduleUser1 的调度函数,其 CRON 设置为('0 20 * * *')
,第二个 scheduleUser2 其 CRON 设置为 ('30 20 * * *)
。我使用crontab.guru/#0_8___* 来生成 CRON
嗯,这取决于您对任务的准确度/时间敏感性。如果大约一分钟的任务时间精度还可以,那么您可以每分钟运行一个计划函数来检查所有选项卡(或订单)并关闭那些过期的选项卡。我假设这些选项卡存储在数据库中?此选项卡的模型应包括 userId、startTime 和 isActive。如果您可以牺牲一点准确性以获得更容易的可扩展性和更低的成本,则此选项比部署您自己的 express 服务器更好。以上是关于如何创建动态计划任务?的主要内容,如果未能解决你的问题,请参考以下文章