Golang is listening on multiple ports blocking BigTable connection
I am creating a simple udp client that listens on multiple ports and saves the request to a large column.
Before you ask, you need to listen on different ports.
Everything worked beautifully until I turned on the large table. After that, listeners block completely.
My stripped-down code without a large table looks like this:
func flow(port string) {
protocol := "udp"
udpAddr, err := net.ResolveUDPAddr(protocol, "0.0.0.0:"+port)
if err != nil {
fmt.Println("Wrong Address")
return
}
udpConn, err := net.ListenUDP(protocol, udpAddr)
if err != nil {
fmt.Println(err)
}
defer udpConn.Close()
for {
Publish(udpConn, port)
}
}
func main() {
fmt.Print("Starting server.........")
for i := *Start; i <= *End; i++ {
x := strconv.Itoa(i)
go flow(x)
}
}
This works great, however, as soon as I add the following for a large table, it all gets blocked. If I remove the go procedure that creates the listener (which means I cannot listen on multiple ports) it works.
func createBigTable() {
ctx := context.Background()
client, err := bigtable.NewClient(ctx, *ProjectID, *Instance)
if err != nil {
log.Fatal("Bigtable NewClient:", err)
}
Table = client.Open("x")
}
I managed to get it to work by adding a request to the createBigTable function, but the program still blocks later.
I have no idea if this is a bigtable, grpc problem or just the way I do it.
Would have liked some kind of advice on how to fix it.
--- UPDATE ---
I found that the problem was not only related to BigTable - I also have the same problem when I call gcloud pubsub.
--- UPDATE 2 ---
createBigtable is called in the init function (BEFORE THE MAIN FUNCTION):
func init() {
createBigTable
}
--- Update 3 ---
The way out of Sikkit can be found here:
source to share
In your example playground, you are using for {}
to keep the server running forever. This seems to rob the gorutas from ever running. Try using a, for example, WaitGroup
to get control from a subroutine main()
and the subroutines flow()
handle incoming UDP packets.
import (
...
"sync"
...
)
...
func main() {
fmt.Print("Starting server.")
for i := *Start; i <= *End; i++ {
x := strconv.Itoa(i)
go flow(x)
}
var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
}
source to share