V
V
v- death2015-11-20 16:44:43
go
v- death, 2015-11-20 16:44:43

Why does it return the value of the third routine?

I'm making a simple cluster (for scientific purposes)
I have an
example.com domain on it with code that, in theory, should return me the name of the server that answered the fastest. But for some reason, server3 always answered first. Without hesitation, I brought my code where fmt.print is simply used

package main

import "fmt"

func getDataFromServer(res chan string, serverName string) {
  fmt.Println(serverName)
  res <- serverName
}

func main() {
  res := make(chan string, 3)
  go getDataFromServer(res, "Server1")
  go getDataFromServer(res, "Server2")
  go getDataFromServer(res, "Server3")

  data := <- res
  fmt.Println(data)
}

In theory, in this code, 1 goroutine should be completed first and server1 should be printed to the terminal, but for some reason it constantly prints server3
And here is the code by which I check the server
package main

import (
  "fmt"
  "log"
  "net/url"
)

func getDataFromServer(res chan string, serverName string) {
  ur := "http://" + serverName + "example.com"
  _, err := url.Parse(ur)
  if err != nil {
    log.Fatal(err)
  } else {
    res <- ur
  }
}

func main() {
  res := make(chan string, 3)
  go getDataFromServer(res, "Server1")
  go getDataFromServer(res, "Server2")
  go getDataFromServer(res, "Server3")
  go getDataFromServer(res, "Server4")
  go getDataFromServer(res, "Server5")

  data := <-res
  //по идее здесь должен быть url который ответил быстрее всех. Но почему то выводит адрес Server5 всегда
  fmt.Println(data)
}

Thanks in advance

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Pavlyuk, 2015-11-20
@vGrabko99

Go does not guarantee the order in which goroutines are executed. So server1 will not necessarily be the first.

O
Oleg Shevelev, 2015-11-20
@mantyr

Here are two examples to check that everything actually works correctly (if we understand the question correctly).

package main

import "fmt"
import "time"

func getDataFromServer(res chan string, serverName string, delay int64) {
  fmt.Println(serverName)
  time.Sleep(time.Duration(delay)*time.Second)
  res <- "test_"+serverName
}

func main() {
  res := make(chan string, 3)
  go getDataFromServer(res, "Server1", 10)
  go getDataFromServer(res, "Server2", 11)
  go getDataFromServer(res, "Server3", 12)

  data := <- res
  fmt.Println(data)
}
Server3
Server1
Server2
test_Server1

package main

import "fmt"
import "time"

func getDataFromServer(res chan string, serverName string, delay int64) {
  fmt.Println(serverName)
  time.Sleep(time.Duration(delay)*time.Second)
  res <- "test_"+serverName
}

func main() {
  res := make(chan string, 3)
  go getDataFromServer(res, "Server1", 15)
  go getDataFromServer(res, "Server2", 11)
  go getDataFromServer(res, "Server3", 12)

  data := <- res
  fmt.Println(data)
}
Server3
Server1
Server2
test_Server2

Golang decides when to context switch for better performance and less overhead.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question