Answer the question
In order to leave comments, you need to log in
Why is code not being executed in goroutines?
The task is simple: a small server responding on several ports when some given messages connect. I made it so that a goroutine with a listener was raised on each port.
The code works when run locally, but does not work on a remote server on DO (it starts, writes a greeting and goes into a loop without starting to listen to ports). Rebuilding on a server VM with a similar version of golang doesn't help.
package main
import (
"fmt"
"net"
"os"
"log"
)
const HOST = "0.0.0.0"
type ServerConfig struct {
Protocol string
Port int
Banner []byte
}
func main() {
fmt.Println("Server started!")
var config *ServerConfig
config = &ServerConfig{
Protocol:"tcp",
Port:8001,
Banner: []byte("Hello!\n")}
go config.startListener()
config = &ServerConfig{
Protocol:"tcp",
Port:8002,
Banner: []byte("World\n")}
go config.startListener()
for {}
}
func (c *ServerConfig) startListener() error {
sockAddr := HOST+":"+fmt.Sprintf("%v", hc.Port)
l, err := net.Listen(c.Protocol, sockAddr)
if err != nil {
fmt.Println("Error listening:", err.Error())
//os.Exit(1)
return err
}
defer l.Close()
fmt.Println("Listening on " + sockAddr)
for {
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// Handle connections in a new goroutine.
go handleRequest(conn, c.Banner)
}
}
// Handles incoming requests.
func handleRequest(conn net.Conn, banner []byte) {
// Make a buffer to hold incoming data.
conn.Write([]byte(banner))
buf := make([]byte, 1024)
// Read the incoming connection into the buffer.
_, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err.Error())
}
// Send a response back to person contacting us.
conn.Write([]byte(banner))
// Close the connection when you're done with it.
conn.Close()
}
Answer the question
In order to leave comments, you need to log in
Run the second listener in main, not in goroutine
config.startListener() // не нужно go config.startListener()
//обязательно уберите for{}, это плохая конструкция
select{} //хотя бы так, а если оставить листенер в main треде то и это необязательно
How many cores are in a DO machine?
There is an assumption that it
does not allow processing incoming connections. clogs the percentage completely
In general, as Andrey Tsvetkov said, the code is very strange ...
Replace for{} with select{}
In your launch settings on the server, the GOMAXPROC environment variable is set to 1, most likely, so the empty loop occupies a single process and does not allow the rest of the goroutines to work. select{} will just put your main goroutine to sleep without wasting resources.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question