1:- module(bc_mail_queue, [
    2    bc_mail_enqueue_text/4, % +Text, +From, +Subject, +To
    3    bc_mail_queue_wipe/0,
    4    bc_mail_queue_size/1,   % -Size
    5    bc_mail_set_behavior/1  % +Behavior
    6]).    7
    8:- use_module(library(error)).    9:- use_module(library(debug)).   10:- use_module(library(docstore)).   11
   12:- use_module(bc_mail).   13
   14% Queue behavior: ignore, retain, send.
   15% Production value is send.
   16
   17:- dynamic(behavior/1).   18:- dynamic(queue/5).   19
   20% Default is used for testing.
   21
   22:- assertz(behavior(retain)).   23
   24bc_mail_set_behavior(Behavior):-
   25    must_be(oneof([retain, send, ignore]), Behavior),
   26    retractall(behavior(_)),
   27    assertz(behavior(Behavior)).
   28
   29bc_mail_enqueue_text(Text, From, Subject, To):-
   30    must_be(atomic, Text),
   31    must_be(atomic, From),
   32    must_be(atomic, Subject),
   33    must_be(atomic, To),
   34    (   behavior(ignore)
   35    ->  true
   36    ;   ds_uuid(Uuid),
   37        assertz(queue(Uuid, Text, From, Subject, To)),
   38        debug(bc_mail, 'queued mail to ~w', [To])).
   39
   40bc_mail_queue_wipe:-
   41    retractall(queue(_, _, _, _, _)),
   42    debug(bc_mail, 'wiping mail queue', []).
   43
   44bc_mail_queue_size(Size):-
   45    findall(_, queue(_, _, _, _, _), Mails),
   46    length(Mails, Size).
   47
   48% Sleep time setting for the
   49% mail queue thread.
   50
   51queue_thread_sleep(1).
   52
   53start_mail_thread:-
   54    debug(bc_mail, 'started queue thread', []),
   55    queue_thread_sleep(Sleep),
   56    sleep(Sleep),
   57    queue_loop.
   58
   59% Tail-call optimized loop.
   60
   61queue_loop:-
   62    queue_loop_iteration,
   63    queue_thread_sleep(Sleep),
   64    sleep(Sleep),
   65    queue_loop.
   66
   67queue_loop_iteration:-
   68    (   behavior(send)
   69    ->  send_all_mails
   70    ;   true).
   71
   72% Queue loop thread is always started.
   73
   74:- thread_create(start_mail_thread, _, []).   75
   76% Sends all mails.
   77
   78send_all_mails:-
   79    findall(
   80        queue(Uuid, Text, From, Subject, To),
   81        queue(Uuid, Text, From, Subject, To), Mails),
   82    length(Mails, Count),
   83    debug(bc_mail, 'sending ~w mails from queue', [Count]),
   84    maplist(send_mail, Mails).
   85
   86% Sends one mail.
   87
   88send_mail(Mail):-
   89    Mail = queue(Uuid, Text, From, Subject, To),
   90    debug(bc_mail, 'sending mail to ~w', [To]),
   91    retractall(queue(Uuid, _, _, _, _)),
   92    bc_mail_send_text(Text, From, Subject, To)