Open maitredede opened 2 years ago
A quick and dirty implementation may be :
func (port *unixPort) SetDeadline(t time.Time) error {
return port.SetReadTimeout(time.Until(t))
}
but it would be also interesting to have timeouts/deadlines on .Write()
:slightly_smiling_face:
Hello, More precisions about my use case, I need to communicate with devices that respects some timouts, when both reading and writing.
Either the native timeout or the context approach can be used in my case, but I need both read and write timeouts :smiley:
I need this as well. I would like to use io.ReadFull
on the go-serial reader/Port interface. But since go-serial's SetReadTimeout()
only causes go-serial's Read()
implementation to do return 0, nil
, the ReadFull
gets stuck. My workaround might end up using SetReadTimeout()
, and the doing my own Read-loop, reading 1 byte at a time into my buffer and interpreting n, nil
as the timeout. related #148
How about the same interface as net.conn?
SetDeadline(t time.Time) error
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
which could be set using for example port.SetReadDeadline(time.Now().Add(time.Second))
.
If implementing the same interface as net.Conn one could keep much code between networked and serial connections without much change. As long as one of the existing interfaces from either from this or os.File is used then I'm happy.
How about the same interface as net.conn?
SetDeadline(t time.Time) error SetReadDeadline(t time.Time) error SetWriteDeadline(t time.Time) error
which could be set using for example
port.SetReadDeadline(time.Now().Add(time.Second))
.If implementing the same interface as net.Conn one could keep much code between networked and serial connections without much change. As long as one of the existing interfaces from either from this or os.File is used then I'm happy.
I second this! I had to implement serial port handling in software that was already using net.Conn
, so having the deadline functions would have made Port
basically a drop in replacement. It would be nice to have it in the long run, but for the time being this is what I've come up with:
type portWithDeadline struct {
serial.Port
writeDeadline *time.Time
}
func (p portWithDeadline) SetDeadline(t time.Time) error {
p.SetWriteDeadline(t)
return p.SetReadDeadline(t)
}
func (p portWithDeadline) SetReadDeadline(t time.Time) error {
return p.SetReadTimeout(time.Until(t))
}
func (p portWithDeadline) SetWriteDeadline(t time.Time) error {
p.writeDeadline = &t
return nil
}
func (p portWithDeadline) Write(b []byte) (n int, err error) {
if p.writeDeadline == nil || p.writeDeadline.IsZero() {
return p.Port.Write(b)
}
finishedCh := make(chan struct{})
timeoutCh := time.After(time.Until(*p.writeDeadline))
go func() {
defer close(finishedCh)
n, err = p.Port.Write(b)
}()
select {
case <-timeoutCh:
return 0, errors.New("write operation timed out")
case <-finishedCh:
return n, err
}
}
Hello,
Thanks for PR #109 (timeouts).
I am using your lib (go 1.16.7 on linux/amd64) to drive Ingenico payement hardware that has timeouts defined in its communication protocol. But the timeouts are not the same between protocol states. For example : when I write a ENQ byte, there is a response timeout of 2s; when I ended sending something, I have to listen 2s before I can start sending a new item; when there is a communication conflict, the timeout is 5s before retry...
My first driving implementation was based on your lib, and did not fully respected all the timeouts. My second implementation use directly the
/dev/ttyACM0
file (using os.File), and respects the timeouts, using the `os.File.SetDeadline` func.So I would like if it is possible to add a
SetDeadline
implementation that can be called when needed, and that may have the same behavior that the*os.File
. :slightly_smiling_face: