-
Notifications
You must be signed in to change notification settings - Fork 0
API: Create Mail queue (to be used by (*Email).Send or (*Email).Enqueue) #20
Comments
Naive version that can only send 1 email at a time -- var EmailQueue = make(chan *Email)
go func() {
for {
email := <-EmailQueue
// Synchronous .Send prevents emails
// from being added to queue; BAD
err := email.Send()
if err != nil {
// FAILED
continue
}
// SUCCESS
}
} Note also that this doesn't allow any new emails to be queued up while another email is sent, which makes this especially egregious. We could at least allow new emails to enter the queue by changing the first line from
to
which would allow |
Another option: effectively infinite queue (channel reads are immediate), but limit the number of email attempts at any given moment (perhaps to please Mandrill or whoever) using a buffered channel as a semaphore -- var EmailQueue = make(chan *Email)
var semaphore = make(chan bool, 10) // Can only send 10 at once
go func() {
for {
email := <-EmailQueue
// Spawn goroutine immediately
go func(e *Email) {
// Will only block if 10 emails already being sent.
// That is, will only block if 10 bools
// are already in the `semaphore` channel
semaphore <- true
defer func() {
// Drain value from channel to make room
// for another email sender
<-semaphore
}()
err := e.Send()
if err != nil {
// FAILED
return
}
// SUCCESS
}(email)
}
} Another semaphore example: search http://golang.org/doc/effective_go.html for |
Notice how Go allows for all these various behaviors/dynamics all using just channels and goroutines? No special parallel async generator types or whatever, just simple, powerful primitives that can be used to quickly build anything. |
Async email sending (infinite queue) --
What is an
EmailStatus
? See #19.The text was updated successfully, but these errors were encountered: