> If I was building a system like the one you describe for real, then the > first tool I'd reach for would be a email sending service, like Mailgun, > Sendgrid, or AWS SES. These sorts of services take care of queuing mail, > retrying on failure, and keeping track of mail bounces. They also all have > free tiers: Mailgun is free for the first 10,000 emails per month, Sendgrid > is free for around 3,000 emails a month, and SES is free for 62,000 emails > per month. They also save me the trouble of maintaining and configuring my > own email sending system. >
You are probably right that this is the most pragmatic solution. But I also learn a lot when I try to build these things myself and I would never have known about the Java Executors if I hadn't gone this path. > > If I was building something myself, for whatever reason, then I'd make it > as simple as possible. > > (defn send-queued-mail [db mail] > (let [sent-successfully? (send-mail mail)] > (if sent-succesfully? > (remove-mail-from-queue db mail)))) > > (defn send-queued-mail [db] > (doseq [mail (fetch-queued-mail-in-priority-order db)] > (send-queued-mail db mail))) > > (defn init-scheduler [db] > (doto (Executors/newScheduledThreadPool 32) > (.scheduleAtFixedRate #(send-queued-mail db) 30 30 TimeUnit/SECONDS))) > Ah, there you go. ScheduledThreadPool is another thing I didn't know about. James and Erik, thank you so much for your feedback and patience with my questions! It has been invaluable. Thanks, Brjánn > > > I wouldn't have an application-specific queue, as I'd want it to be robust > against the process ending. > > But I don't think there's any situation where I'd want to do it myself if > I could avoid it, not when there are solutions out there that already do > all of the heavy lifting for me. > > > On Sat, 27 Oct 2018 at 12:59, <brj...@gmail.com> wrote: > >> Thanks for pointing out the submit function and explaining the wrapper. >>>> Would you specifically advise against sending the result back through a >>>> channel? >>>> >>> >>> It depends what you're trying to do. What are you doing with the result, >>> and what's your reasoning for not handling it in your "send-email!" >>> function? >>> >> >> That is a very good question. I currently believe that the there will be >> three different scenarios of sending emails. >> >> 1. Fire and (almost) forget - where delivery is not guaranteed but the >> app user will be notified if delivery was unsuccessful as soon as that >> status is available. >> 2. First send of a guaranteed delivery message - where all messages are >> stored in the DB but the send is attempted immediately. >> 3. Retry of sending a guaranteed delivery message - i.e., a failed send >> is picked up from the DB by some scheduled task. >> >> I would like the send-mail function to be agnostic of which of these >> scenarios a particular message is sent in (and not have to include any DB >> logic). Rather, it would just return the status whenever it's available and >> let the caller decide what to do with it (scenario 1 or 2). If the status >> is returned as a future, the caller would have wait until the future is >> realized to avoid blocking - and do this wait in a non-blocking manner. It >> seems that returning using a channel and receiving the status in a go block >> would achieve precisely this with very little code. Also, if there is a >> chain of function between the sender and the worker thread, the channel >> would bypass the caller chain and each chained caller doesn't need know the >> nature of the status. Also, if some reason there are multiple parties who >> are interested in the status (no use case yet), it would be easy to just >> add more return channels to the email. Does this also seem over-enginereed >> compared to just returning the future from the worker and letting it bubble >> up to however is interested? >> >> Thanks, >> Brjánn >> >> >>> >>> -- >>> James Reeves >>> booleanknot.com >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to clojure+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > > -- > James Reeves > booleanknot.com > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.