AfterShip / email-verifier

:white_check_mark: A Go library for email verification without sending any emails.
MIT License
1.17k stars 149 forks source link

How to get Faster Resposne from email-verifier when checking list of emails. #111

Open shihabmi7 opened 7 months ago

shihabmi7 commented 7 months ago

well, First thanks for contributors for awesome library.

I already created a Go application using this library. I created a post endpoint that takes only a list of emails. Then Using this library I generate a custom validation response. But for a list of 10 emails, it took 32~40 seconds. I want to reduce that one. Note that my internet speed is well. Sample code for lists of email verifications.

Thanks in Advance.


func ProcessEmailList(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

    w.Header().Set("Content-Type", "application/json")

    errorResponse := ErrorResponse{
        Code:    400,
        Message: "Error",
    }

    // Read the request body
    body, err := io.ReadAll(r.Body)
    if err != nil {
        errorResponse.Message = err.Error()
        error_json, _ := json.Marshal(errorResponse)
        w.WriteHeader(http.StatusBadRequest)
        fmt.Fprint(w, string(error_json))

        return
    }

    // Unmarshal the JSON request body into EmailListRequest struct
    var request EmailListRequest
    if err := json.Unmarshal(body, &request); err != nil {
        errorResponse.Message = "Error parsing JSON"
        error_json, _ := json.Marshal(errorResponse)
        w.WriteHeader(http.StatusBadRequest)
        fmt.Fprint(w, string(error_json))
        return
    }

    // Split the comma-separated string into a slice of email addresses
    emails := strings.Split(request.Emails, ",")
    responseList := []EmailRespose{}

    // Process the list of emails
    for _, email := range emails {
        responseList = append(responseList, SimplyVerifyEmail(email))
    }

    // Respond to the client
    w.WriteHeader(http.StatusOK)
    jsonResponse, err := json.Marshal(responseList)
    fmt.Fprint(w, string(jsonResponse))
}
guide-giangnt commented 5 months ago

I tried applying multithread with Goroutines Performance improved a bit

    var wg sync.WaitGroup
    wg.Add(n)
    resultsCh := make(chan emailverifier.Result)

    for _, email := range emails {
        println(email)
        go worker(email, resultsCh, &wg)
    }

    // Start a goroutine to collect results from workers
    go func() {
        wg.Wait()
        close(resultsCh)
    }()

    var results []emailverifier.Result
    for result := range resultsCh {
        fmt.Println(result)
        results = append(results, result)
    }
func worker(email string, results chan<- emailverifier.Result, wg *sync.WaitGroup) {
    defer wg.Done()
    result, err := verifier.Verify(email)
    if err != nil {
        fmt.Println("verify email address failed, error is: ", err)
    }
    results <- *result
}
shihabmi7 commented 5 months ago

@guide-giangnt thanks for sharing. I will update you, after testing.