I want to develop a simple email sender in Go, but I have encountered some problems, This is my actual code:
package main
import (
"flag"
"sync"
"fmt"
)
var logLevel = 0
func sendEmail(try combo){
fmt.Printf("test send %s %s %s
", try.to, try.from, try.subject)
}
// where we actually do the work
func work(toSend chan combo, wg *sync.WaitGroup) {
for send := range toSend {
sendEmail(send)
}
// let the main thread know we're done
wg.Done()
}
// the basic unit that we pass around
type combo struct {
to string
from string
subject string
header string
body string
success bool
}
func main() {
//defaults variables
emailsList, smtpList := "", ""
typeConnect, ConnFileName := "", ""
delimStart, delimEnd := "_STARTSUB_", "_ENDSUB_"
threads, bcc := 5, 1
skip := 0
logFile := ""
// Args parse
flag.StringVar(&emailsList, "e", "", "load email list (required)")
flag.StringVar(&smtpList, "s", "", "load smtp list - (required)")
flag.IntVar(&bcc, "b", 1, "number of emails sent per connection")
flag.IntVar(&threads,"t", 2, "run `N` attempts in parallel threads")
flag.StringVar(&typeConnect, "c", "","direct - send emails directly through smtp
"+"\tsocks - send emails through smtp via socks5 [requires -f argument]
"+"\thosts - send emails through smtp via server's ip addresses [requires -f argument]
")
flag.StringVar(&ConnFileName, "f", "", "if sending via socks the list should contain socks5 proxies in the following formats
"+"\tip:port
"+"\tip:port:user:pass
")
flag.StringVar(&delimStart, "q", "_STARTSUB_", "start delimiter for subject.")
flag.StringVar(&delimEnd, "w", "_ENDSUB_", "end delimiter for subject.")
flag.IntVar(&skip, "l", 0, "skip first `n` lines of input")
flag.StringVar(&logFile, "debug", "", "write debug output to `file`")
flag.IntVar(&logLevel, "d", 0, "set debug `level`")
flag.Parse()
var wg sync.WaitGroup // keep track of the workers
toSend := make(chan combo) // to the workers
// initialize n workers
wg.Add(int(threads))
for i := 0; i < int(threads); i++ {
go work(toSend, &wg)
}
for email := range StreamLines("EMAILS", emailsList, skip) {
from := "info@testfrom.com"
subject := "test subject"
header := "test header"
body := "test boady"
try := combo{email,from, subject, header, body, false}
toSend <- try
}
wg.Wait()
close(toSend)
fmt.Println("Send emails Done!")
}
I'm try to use channels for pass email to workers in golang, and return this error:
F:\dev\GoLang\gitlab\EasySend>go run main.go usage.go utils.go -e emails.txt
test send test@gmail.com info@testfrom.com test subject
test send test@gmail.com info@testfrom.com test subject
test send test@gmail.com info@testfrom.com test subject
test send test@gmail.com info@testfrom.com test subject
test send test@gmail.com info@testfrom.com test subject
test send test@gmail.com info@testfrom.com test subject
test send test@gmail.com info@testfrom.com test subject
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc04204c0fc)
C:/Go/src/runtime/sema.go:56 +0x40
sync.(*WaitGroup).Wait(0xc04204c0f0)
C:/Go/src/sync/waitgroup.go:131 +0x79
main.main()
F:/dev/GoLang/gitlab/EasySend/main.go:90 +0x7af
goroutine 18 [chan receive]:
main.work(0xc04203e0c0, 0xc04204c0f0)
F:/dev/GoLang/gitlab/EasySend/main.go:19 +0x110
created by main.main
F:/dev/GoLang/gitlab/EasySend/main.go:76 +0x5db
goroutine 19 [chan receive]:
main.work(0xc04203e0c0, 0xc04204c0f0)
F:/dev/GoLang/gitlab/EasySend/main.go:19 +0x110
created by main.main
F:/dev/GoLang/gitlab/EasySend/main.go:76 +0x5db
exit status 2
I want to know where I'm wrong? Way return this error
"fatal error: all goroutines are asleep - deadlock!"