I am trying to design a small app to send emails (stored in MongoDB) using 
golang utilizing goroutine and channel and this is the first time i use 
golang.


There are 2 types of worker in each server (Retriever and Sender). A single 
retriever will periodically (every few seconds) query MongoDB, fetch new 
email. Then new email will be sent to Senders via a buffered channel (has 
buffer size == number of Sender workers, this might be the issue). When a 
sigterm received, Retriever will exist using ctx.Done and close the email 
channel.  Since channel closed, Senders which range over channel will exit 
as well.


    go func() {
        defer wg.Done()
        for {
            select {
                case <-ctx.Done():
                    // received sigterm, close channel
                    close(emailCh)
                    return
                case <- time.After(5 * time.Second):
                    // query DB every 5 seconds to get a single new email....
                    if newEmail := dw.getNewEmail(); newEmail != nil {
                        emailCh <- newEmail
                    }
         }
    }



I realize this is a bad design and the issues are:

 I am using FindAndModify to fetch email every time ( I need to update 
email status to sending when fetching so that the app running in other 
server will not fetch the same doc). That means I am actually sending a 
single email in each interval which makes it non-sense to create multiple 
Sender goroutines. 


the alternative I can think of right now is:

1. I could run FindAndModify query multiple times in each interval to get N 
emails. But If the N is larger then buffer size, it will block the select 
and blocking time depends on how many more emails I retrieved than the 
buffer size. If N is too large, then sigterm received, I am not be able to 
shutdown the app in time. If N is too small, I can only send at most 
N/interval emails per second.


2. use an unbuffered channel without interval, (keeps polling the DB). 
Whenever there is a new email, send to channel. the blocking time should be 
minimal (1 email). But the app will continually poll the DB, will it create 
big overhead/too many connections?



go playground link:

https://play.golang.org/p/LRQ-cnLiDfB

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to