The use of Django signal signal mechanism

Background : If this task (timed or immediately) is executed, then some execution status will be generated into pdf and sent to the customer by email.
Phenomenon : I check the execution status of the task through the celery cycle. If the task is executed, change the task status asynchronously, and then send the email. But from time to time there will be repeated emails, because asynchronous tasks repeatedly enter the celery task queue, causing some tasks to send emails repeatedly.
Solution : Use django's signal signal mechanism to monitor the change of task status table data. Once the task status becomes complete, trigger the signal signal, and then execute the mail sending logic code. (But be careful not to change this state repeatedly during the cycle)

Table structure to be monitored:

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'

Here we mainly monitor the change of is_create field, when the group is dumb

Monitoring and sending mail code:

# 采用信号监听 能够确保邮件发送只被触发一次 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('第五步:执行邮件信息发送完毕')

Guess you like

Origin blog.csdn.net/qq_42631707/article/details/112984274