Django signal 信号机制的使用

背景:如果这个任务(定时或者立即)执行完毕,然后把一些执行情况生成pdf,通过邮件发送给客户。
现象:我通过celery周期查看任务的执行状态,如果任务执行完毕,异步更改任务状态,然后执行发送邮件。但是时不时会出现重复发送邮件,原因异步任务重复进入celery任务队列,导致有的任务会重复发送邮件。
解决方案:通过django的signal信号机制来监测任务状态表数据的变更,一旦任务状态变成完成,触发signal信号,然后执行发送邮件逻辑代码。(但是需要注意不要在周期之中反复更改这个状态)

要监控的表结构:

class PdfTask(models.Model):
    """pdf任务表"""
    IS_CREATE_CHOICES = (
        (0, u'未生成'),
        (1, u'生成中'),
        (2, u'已生成'),
        (3, u'异常')
    )
    task_url = models.TextField(verbose_name='任务详情链接')
    pdf_path = models.TextField(verbose_name='pdf的保存的目录')
    pdf_name = models.TextField(verbose_name='pdf的名称')
    foreign_key_id = models.IntegerField(verbose_name='外键的id', null=True)

    is_create = models.IntegerField(verbose_name=u'是否生成', choices=IS_CREATE_CHOICES, default=0)
    result = models.BooleanField(verbose_name='生成的结果', default=False)
    run_num = models.IntegerField(verbose_name='执行生成的次数', default=0)
    is_delete = models.IntegerField(choices=[(0, u'未删除'), (1, u'已删除')], default=0)

    class Meta:
        verbose_name = 'pdf任务表'
        db_table = 't_pdf_task'

在这里主要监测is_create字段的变化,当组的哑巴

监测加发送邮件代码:

# 采用信号监听 能够确保邮件发送只被触发一次 PDF邮件无论是否生成正确还是不正确的
@receiver(signals.post_save, sender=PdfTask)
def inspect_instance(instance, created, **kwargs):
    if not created and instance.is_create in [2, 3]:
        logger.warning('第一步:触发邮件发送')
        from apps.inspection_tasks.models import InspectionReport
        inspection_report_objs = InspectionReport.objects.filter(id=instance.foreign_key_id)
        if inspection_report_objs:
            inspection_report = inspection_report_objs[0]
            if inspection_report.is_send_email is False:
                logger.warning('第二步:触发邮件状态更改')
                inspection_report.is_send_email = True
                inspection_report.save()
                title = "{}巡检报告-{}".format(
                    inspection_report.data_center.data_center_name,
                    datetime.datetime.strftime(inspection_report.begin_time, '%Y%m%d')
                )
                content = """
                                           亲爱的业务系统管理员:蓝鲸平台于{0}生成{2}系统巡检报告,巡检过程耗时{1}秒。请登录蓝鲸平台,在"系统巡检->巡检报告->巡检历史"中找到当日巡检任务,查看巡检报告内容详情!
                                           """.format(
                    datetime.datetime.strftime(inspection_report.begin_time, '%Y%m%d %H:%M'),
                    inspection_report.use_time,
                    inspection_report.data_center.data_center_name
                )
                receiver = inspection_report.temp_id.receiver
                logger.warning('第三步:触发邮件信息组装')
                pdf_name = instance.pdf_name
                pdf_path = instance.pdf_path
                pwd_file = pdf_path + pdf_name
                with open(pwd_file, 'rb') as f:
                    base64_data = base64.b64encode(f.read())
                    file_data = base64_data.decode()
                attachments = [{
                    "filename": pdf_name,
                    "content": file_data
                }]
                from apps.commons.cmsi_handle import send_email
                logger.warning('第四步:执行邮件信息发送')
                send_email(title, content, receiver, attachments)
                logger.warning('第五步:执行邮件信息发送完毕')

猜你喜欢

转载自blog.csdn.net/qq_42631707/article/details/112984274