我有一个每三分钟运行一次的预定函数。
它应该查看数据库(firestore),查询相关用户,发送电子邮件或执行其他数据库操作。
一旦它向用户发送了一封电子邮件,它就会用一个字段'sent_to_today:true'更新用户。
如果sent_to_today == true,则该函数在24小时内不会触及该用户,这是预期的。
但是,因为我有很多用户,而函数正在做很多工作,所以当它用sent_to_today:true更新用户时,另一个调用提前到达该用户并处理它们以发送电子邮件。
这会导致一些用户收到相同的邮件,两次。
我有什么办法来确保这不会发生?
数据模型(简化):
users (Collection)
--- userId (document)
--- sent_to_today [Boolean]
--- NextUpdateTime [String representing a Timestamp in ISO String]
函数运行时,if ("Now">= nextpdatetime) &&(sent_to_today==false),则处理用户,否则跳过用户。
如何确保用户每天只被一个调用处理,而不是多次调用?
正如我所说,当它们被一个函数调用处理时(它设置了&;sent_to_today&;)对于true),下一次调用到达该用户并处理它们。
在更好地构建数据或使用任何其他逻辑方法方面的任何帮助都将非常感谢。
这是我正在考虑的一个想法:
- 每次调用设置一个全局文档的字段,例如:busy_right_now: true;在开始和结束时,它再次将其设置为false。如果后续调用在当前完成之前运行,则如果busy_right_now仍然为true,则不执行任何操作。
选项1
你认为这个函数可以每十分钟调用一次,而不是每三分钟调用一次吗?如果是-只需修改调度程序,并确保'max instances'属性为'1'。由于函数超时时间只有540秒,10分钟(600秒)足以避免重叠。
2 .选项
当选择一个firestore文档进行处理时,云函数修改一些属性—例如__state
—并将其值设置为IN_PROGRESS
。当处理完成(发送邮件)时,该属性值再次被修改,例如为DONE
。因此,如果该函数拾取一个在__state
属性中值为IN_PROGRESS
的文档,它将直接忽略并继续执行下一个文档。
缺点-如果函数崩溃-可能有IN_PROGRESS
状态的文档,并且应该有一些机制来监视和解决这种情况。
3 .选项
一个云函数在firestore集合中运行,对于要处理的每个文档,它发送一个pubsub消息,该消息触发另一个云函数。那只适用于一个firestore文档。然而,需要"状态机"控制(如上面的选项2)。选项3的好处是功能之间的专门化程度更高,并且可能会有许多并行运行的"第二"云功能。