Skip to content

Instantly share code, notes, and snippets.

@skaji
Created July 28, 2019 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skaji/afe75d1ed4dcfbd18a3b46f31ae1547a to your computer and use it in GitHub Desktop.
Save skaji/afe75d1ed4dcfbd18a3b46f31ae1547a to your computer and use it in GitHub Desktop.
package main
import (
"context"
"net"
"net/textproto"
"time"
)
// Client is
type Client struct {
baseConn net.Conn
conn *textproto.Conn
}
// New is
func New(ctx context.Context, addr string) (*Client, error) {
var dialer net.Dialer
baseConn, err := dialer.DialContext(ctx, "tcp", addr)
if err != nil {
return nil, err
}
conn := textproto.NewConn(baseConn)
return &Client{
baseConn: baseConn,
conn: conn,
}, nil
}
// Close is
func (c *Client) Close() error {
return c.baseConn.Close()
}
var reset = time.Time{}
var immediately = time.Unix(1, 0)
func (c *Client) wrapReadFunc(ctx context.Context, f func()) {
c.baseConn.SetReadDeadline(reset)
stop := make(chan struct{})
done := make(chan struct{})
go func() {
select {
case <-ctx.Done():
c.baseConn.SetReadDeadline(immediately)
case <-stop:
}
close(done)
}()
f()
close(stop)
<-done
c.baseConn.SetReadDeadline(reset)
}
func (c *Client) wrapWriteFunc(ctx context.Context, f func()) {
c.baseConn.SetWriteDeadline(reset)
stop := make(chan struct{})
done := make(chan struct{})
go func() {
select {
case <-ctx.Done():
c.baseConn.SetWriteDeadline(immediately)
case <-stop:
}
close(done)
}()
f()
close(stop)
<-done
c.baseConn.SetWriteDeadline(reset)
}
// ReadCodeLine is
func (c *Client) ReadCodeLine(ctx context.Context, code int) (outCode int, outMsg string, outErr error) {
c.wrapReadFunc(ctx, func() {
outCode, outMsg, outErr = c.conn.ReadCodeLine(code)
})
return
}
func main() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment