Home > front end >  Goroutines got hung up after a while
Goroutines got hung up after a while

Time:03-02

I am writing a program to check my SOCKS5 proxies. My way is to iterate over each element in the proxy array and create one goroutine for each proxy, and the program was ran perfectly, but, after a while (About 10 seconds after run the program), my program will be stopped for a long time and does nothing, even though it hasn't finished checking the list of proxies. How must I do now? This is my code:

func checkProxy(proxyAddress string, timeout time.Duration, sw *sync.WaitGroup, sm *sync.Mutex) {
    retry := 0
    headers := []byte("GET / HTTP/1.1\r\nHost: "   PROXY_JUDGE_HOST   "\r\n\r\n")
    for {
        if retry == 3 {
            break
        }
        conn, err := SocksClient(proxyAddress, PROXY_JUDGE_ADDRESS, timeout)
        if err != nil {
            retry  
            return
        }
        func(netConn net.Conn) {
            defer netConn.Close()
            if _, err = conn.Write(headers); err != nil {
                return
            }
        }(conn)
        break
    }
    fmt.Println("Found GOOD proxies: "   proxyAddress)
    sm.Lock()
    liveProxies = append(liveProxies, proxyAddress)
    sm.Unlock()
    sw.Done()
}

func main() {
    var sw sync.WaitGroup
    var sm sync.Mutex
    totalProxies = readFile("socks5.txt")
    for i := 0; i < len(totalProxies); i   {
        sw.Add(1)
        go checkProxy(totalProxies[i], 1*time.Second, &sw, &sm)
    }
    sw.Wait()
    // Code to add proxies list to the new file
}

CodePudding user response:

try this:

  1. if retry == 3 must return
  2. if error caught in call SocksClient should retry and continue to retry

note : I haven't tried this code bcz I don't have the file

func checkProxy(proxyAddress string, timeout time.Duration, sw *sync.WaitGroup, sm *sync.Mutex) {
    defer sw.Done()
    retry := 0
    headers := []byte("GET / HTTP/1.1\r\nHost: "   PROXY_JUDGE_HOST   "\r\n\r\n")
    for {
        if retry == 3 {
            return // not break
        }
        conn, err := SocksClient(proxyAddress, PROXY_JUDGE_ADDRESS, timeout)
        if err != nil {
            retry  
            time.Sleep(10*time.Second) // retry in 10 seconds
            continue // not return
        }
        func(netConn net.Conn) {
            defer netConn.Close()
            if _, err = conn.Write(headers); err != nil {
                return
            }
        }(conn)
        break
    }
    fmt.Println("Found GOOD proxies: "   proxyAddress)
    sm.Lock()
    liveProxies = append(liveProxies, proxyAddress)
    sm.Unlock()
}

CodePudding user response:

In your code, there is one path where your function returns before decrementing the counter on the sync.WaitGroup:

func checkProxy(....) {
    for {
    ....
        if err != nil {
            retry  
            return
        }
    }

}

I guess you meant to add a continue there instead. If there is an error, the sw.Done() call will never be executed as the function returns before.

As a best practice make sure you defer your sw.Done call so it is called on any exit path.

func checkProxy(..., sw *sync.WaitGroup, ...) {
   defer sw.Done() // decrement once goroutine is done.
}
  • Related