6.9.5 qmgr_active_done_3_generic函数:将邮件文件移入deferred队列
2016-04-07 15:42
344 查看
通过qmgr_active_done_2_generic和qmgr_active_done_25_generic函数,已经完成了退信、延迟提醒信、DSN状态提醒信的发送工作,接下就可以处理依然存放在active队列中的邮件文件本身了,需要将其移除或移入deferred队列:如果邮件已经没有待发收件人,则根据dont_save函数的设置移除邮件文件或将其移入save文件夹。如果邮件还有待发收件人,则仍需尝试重发该邮件,将其移入deferred队列。
536-548 如果邮件还有待发收件人,则仍需尝试发送该邮件。只有在邮件还有待发收件人的情况下,才需要将邮件纳入延迟重发流程。
这里要确定一个延迟时间,qmgr_active_defer函数将以此为参数设定移动到deferred队列中的邮件的存取和修改时间。
参数minimal_backoff_time(默认300秒)和maximal_backoff_time(默认4000秒)分别设定邮件在deferred队列中的最短和最长等待时间。超出maximal_backoff_time时限则该延迟邮件必然会被尝试投递,不到minimal_backoff_time时限则邮件不会被尝试投递。延迟时间为当前时间和邮件进入队列时间的差,但必须在minimal_backoff_time和maximal_backoff_time参数之间。
函数qmgr_active_defer通过rename函数将邮件移入deferred队列。它与通用的在队列间移动邮件的mail_queen_rename函数的区别是:会将邮件的存取和修改时间设为一个“未来时刻”:
struct utimbuf tbuf;
tbuf.actime = tbuf.modtime = event_time() +delay;
根据6.5节,qmgr模块使用fairness策略交替从incoming队列和deferred队列取信到active队列,正是这个“未来时刻”实现了邮件的延迟:qmgr_active_feed函数取信时将跳过时间未到的延迟邮件:
553-570 至此,完成了根据邮件的状态发送退信、延迟提醒信、或DSN状态通知信的工作。对延迟邮件也做了处理。如果邮件再没有需要发送的收件人了,则可以销毁或另存邮件本身和其内存数据了。
函数mail_queue_remove根据dont_remove参数的设置决定是直接用remove函数删除邮件本身还是将其放入saved文件夹以供研究。最后释放QMGR_MESSAGE结构体。
/qmgr/qmgr_active.c 518 /* qmgr_active_done_3_generic -continue processing */ 519 520 static void qmgr_active_done_3_generic(QMGR_MESSAGE*message) 521 { 522 const char *myname = "qmgr_active_done_3_generic"; 523 int delay; 524 525 /* 526 * Some recipients need to be tried again. Move the queue file time 527 * stamps into the future by the amount of time that the message is 528 * delayed, and move the message to the deferred queue. Impose minimal 529 * and maximal backoff times. 530 * 531 * Since we look at actual time in queue, not time since last delivery 532 * attempt, backoff times will be distributed. However, we can still see 533 * spikes in delivery activity because the interval between deferred 534 * queue scans is finite. 535 */ 536 if (message->flags) { 537 if (message->create_time > 0) { 538 delay = event_time() -message->create_time; 539 if (delay >var_max_backoff_time) 540 delay = var_max_backoff_time; 541 if (delay <var_min_backoff_time) 542 delay = var_min_backoff_time; 543 } else { 544 delay = var_min_backoff_time; 545 } 546 qmgr_active_defer(message->queue_name, message->queue_id, 547 MAIL_QUEUE_DEFERRED,delay); 548 }
536-548 如果邮件还有待发收件人,则仍需尝试发送该邮件。只有在邮件还有待发收件人的情况下,才需要将邮件纳入延迟重发流程。
这里要确定一个延迟时间,qmgr_active_defer函数将以此为参数设定移动到deferred队列中的邮件的存取和修改时间。
参数minimal_backoff_time(默认300秒)和maximal_backoff_time(默认4000秒)分别设定邮件在deferred队列中的最短和最长等待时间。超出maximal_backoff_time时限则该延迟邮件必然会被尝试投递,不到minimal_backoff_time时限则邮件不会被尝试投递。延迟时间为当前时间和邮件进入队列时间的差,但必须在minimal_backoff_time和maximal_backoff_time参数之间。
函数qmgr_active_defer通过rename函数将邮件移入deferred队列。它与通用的在队列间移动邮件的mail_queen_rename函数的区别是:会将邮件的存取和修改时间设为一个“未来时刻”:
struct utimbuf tbuf;
tbuf.actime = tbuf.modtime = event_time() +delay;
根据6.5节,qmgr模块使用fairness策略交替从incoming队列和deferred队列取信到active队列,正是这个“未来时刻”实现了邮件的延迟:qmgr_active_feed函数取信时将跳过时间未到的延迟邮件:
/* * Skip files that have time stamps into the future. They need to cool * down. Incoming and deferred files can have future time stamps. */ if ((scan_info->flags & QMGR_SCAN_ALL) == 0 &&st.st_mtime > time((time_t *) 0) + 1) { if(msg_verbose) msg_info("%s: skip %s (%ldseconds)", myname, queue_id, (long) (st.st_mtime - event_time())); return(0); }
549 550 /* 551 * All recipients done. Remove the queue file. 552 */ 553 else { 554 if (mail_queue_remove(message->queue_name, message->queue_id)) { 555 if (errno != ENOENT) 556 msg_fatal("%s: remove %sfrom %s: %m", myname, 557 message->queue_id, message->queue_name); 558 msg_warn("%s: remove %s from%s: %m", myname, 559 message->queue_id,message->queue_name); 560 } else { 561 /* Same format as loggedby postsuper. */ 562 msg_info("%s: removed",message->queue_id); 563 } 564 } 565 566 /* 567 * Finally, delete the in-core message structure. 568 */ 569 qmgr_message_free(message); 570 }
553-570 至此,完成了根据邮件的状态发送退信、延迟提醒信、或DSN状态通知信的工作。对延迟邮件也做了处理。如果邮件再没有需要发送的收件人了,则可以销毁或另存邮件本身和其内存数据了。
函数mail_queue_remove根据dont_remove参数的设置决定是直接用remove函数删除邮件本身还是将其放入saved文件夹以供研究。最后释放QMGR_MESSAGE结构体。
相关文章推荐
- Jquery 判断滚动条到达顶部或底部
- 自定义Dialog样式+大小+位置
- (1,eval)('this')释义
- zepto.js
- javascript学习笔记 对象
- JSP 中文乱码问题
- 【剑指offer系列】 在O(1)时间删除链表节点___13
- 利用请求头Referer防止盗链
- JavaScript字符串转数字
- 6.9.1.1 qmgr_defer_todo:为延迟邮件清理待发送收件人列表
- 6.9.1 qmgr_ defer.c:销毁活动数据
- CSS 制作三角形原理剖析
- css选择器总结
- 多层json解析
- hadoop SecondNamenode
- (OK) VirtualBox 5.0.10 中 Fedora 23 在安装了增强工具后无法自动调节虚拟机分辨率的问题
- 剑指Offer——翻转英文句子中的单词顺序
- javascript 之闭包详解
- react-native-闪屏页
- 剑指offer:二叉树的下一个结点