Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No timeout in RTU Server causes some sort of deadlock #19

Open
thegreatco opened this issue Sep 10, 2024 · 0 comments
Open

No timeout in RTU Server causes some sort of deadlock #19

thegreatco opened this issue Sep 10, 2024 · 0 comments

Comments

@thegreatco
Copy link

I'm trying to test out the RTU Server.

If I specify a timeout, the server is unstable: it either times out before the client connects or closes if requests are not made often enough.

If I don't specify a timeout, the server seems to work great, but calling Close seems to block forever and I can't cleanly shut it down.

With timeout speciffied

package main

import (
	"os"
	"os/signal"
	"time"

	"github.com/goburrow/serial"
	"github.com/tbrandon/mbserver"
)

func main() {
	serv := mbserver.NewServer()
	err := serv.ListenRTU(&serial.Config{
		Address:  "/dev/ttyUSB0",
		BaudRate: 115200,
		DataBits: 8,
		StopBits: 1,
		Parity:   "N",
		Timeout:  10 * time.Second})
	if err != nil {
		panic(err)
	}
	println("Server is running...")
	defer func() {
		println("Stopping server...")
		serv.Close()
		println("Server stopped")
		os.Exit(0)
	}()
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	<-c
}

Output

$ go run main.go
Server is running...
2024/09/10 16:52:10 serial read error serial: timeout
^CStopping server...
Server stopped

Note that I was able to read/write several coils with no problem. But if I wait longer than the timeout period to issue another command, I get the serial read error, and all subsequent requests to the server fail. However, I am able to close the server down cleanly.

Without timeout

package main

import (
	"os"
	"os/signal"

	"github.com/goburrow/serial"
	"github.com/tbrandon/mbserver"
)

func main() {
	serv := mbserver.NewServer()
	err := serv.ListenRTU(&serial.Config{
		Address:  "/dev/ttyUSB0",
		BaudRate: 115200,
		DataBits: 8,
		StopBits: 1,
		Parity:   "N"})
	if err != nil {
		panic(err)
	}
	println("Server is running...")
	defer func() {
		println("Stopping server...")
		serv.Close()
		println("Server stopped")
		os.Exit(0)
	}()
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	<-c
}
$ go run main.go
Server is running...
^CStopping server...
signal: terminated

I am able to read/write many times, with large gaps in between with no issues. Note that the server only shuts down cleanly now when a kill <pid> is issued. The program hangs on serv.Close().

It seems there is some sort of deadlock here. I noticed in the docs a section on Race Conditions, however I'm not doing anything with goroutines here and the version with a timeout works just fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant