Function does not return value with goroutines

Asked

Viewed 57 times

1

Good afternoon.

I own this code:

package main

import(
    "fmt"
    "net/http"
    "bytes"
    "io/ioutil"
    urlU "net/url"
    "strconv"
    "math/rand"
    "strings"
)

func random(min, max int) int {
    return rand.Intn(max - min) + min
} 


var (
    err2 error
    body []byte
)

type requestResponse struct {
    err error
    body string
}

type requestOptions struct {
    url string
    method string
    body string
    headers map[string]string
}


func (options *requestOptions) doRequest() requestResponse {
    for i := 0; i < 10; i++ {
        transport := &http.Transport{}

        proxyParse, _ := urlU.Parse("http://lum-customer-hl_5e2e538e-zone-static-session-" + strconv.Itoa(rand.Intn(9999999)) + ":[email protected]:22225")
        transport = &http.Transport{Proxy: http.ProxyURL(proxyParse)}


        client := &http.Client{Transport: transport}

        request, err := http.NewRequest(options.method, options.url, bytes.NewBuffer([]byte(options.body)))

        if err != nil { continue }

        request.Close = true

        for headerField, headerValue := range options.headers {
            request.Header.Add(headerField, headerValue)
        }

        response, err := client.Do(request)

        if err != nil { continue }

        defer response.Body.Close()
        body, err2 = ioutil.ReadAll(response.Body)

        if err != nil { continue }

        if strings.Contains(string(body), "") {continue}

        break
    }

    return requestResponse{err: nil, body: string(body)}
}


func main() {


        for i := 0; i < 5; i ++ {

            myrand := random(000000, 999999)
            disparar(myrand)


        }

}

func disparar(myrand int){
    options := &requestOptions{
        url: "https://api...",
        method: "PUT",
        body: fmt.Sprintf(`{"code_2fa":"%s"}`,myrand),
        headers: map[string]string{
            "Authorization" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkNWFmMjI4MTg0NzU5MDAxODdjZWJkZSIsInR5cGVMb2dpbiI6InVzZXIiLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNTY5MzQwNzQxLCJleHAiOjE1NjkzNDE2NDF9.TgUcTTeh4cZIqmndRoBuULlPS0AiPExicXq0gTci_ac"},
        }

        retorno := options.doRequest()
        fmt.Println(myrand,retorno.body)
}

I’m trying to use goroutines to speed up the script process.

When I add go on the line disparar(myrand), the function passes to returns no value in the console.

func main() {


        for i := 0; i < 5; i ++ {

            myrand := random(000000, 999999)
            go disparar(myrand)


        }

}

How can I fire these requests asynchronously using goroutines ?

1 answer

2

When you use go when calling the function, the function is executed in another plane. The problem you have is that the main task does not wait for the execution of tasks in the background to finish the program, when the main task ends, the program ends.

Then you need some way to synchronize the main task with the background tasks, to wait for the execution of all background tasks before proceeding with the main task.

You can use channels, or the package sync for this synchronization, example:

func main() {
    // variável responsável por sincronizar as tarefas
    var wg sync.WaitGroup

    for i := 0; i < 5; i ++ {
        // sinaliza para esperar por mais uma tarefa
        wg.Add(1)
        myrand := random(000000, 999999)

        // função anônima imediatamente invocada que irá rodar em segundo plano
        go func(wg *sync.WaitGroup, myrand int){
            disparar(myrand)

            // sinaliza que uma das tarefas terminou
            wg.Done()
        }(&wg, myrand)
    }

    // espera por todas as tarefas terminarem
    wg.Wait()
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.