go-imap
go-imap copied to clipboard
`UidFetch` never return
I try to build an IMAP email client, and it has many email accounts.
When I use the pprof
for debugging my codes, I found in some cases, the UidFetch
function never return.
I'm pretty sure the follwing:
1. I had set the net.Conn
deadline (half of hour);
2. The message channel used in UidFetch
has the big size (999), and SeqSet
has just one number.
Here are the two goroutines that blocked.
goroutine 27794 [select, 75 minutes]:
github.com/emersion/go-imap/client.(*Client).execute(0xc00485a000, 0xc6b560, 0xc005d06d90, 0xc6b5e0, 0xc00000d648, 0x4, 0x28, 0x30)
D:/Go/pkg/mod/github.com/emersion/[email protected]/client/client.go:261 +0x38e
github.com/emersion/go-imap/client.(*Client).fetch(0xc00485a000, 0x1, 0xc00aec9340, 0xc003ed8690, 0x3, 0x3, 0xc0001bae40, 0x0, 0x0)
D:/Go/pkg/mod/github.com/emersion/[email protected]/client/cmd_selected.go:153 +0x152
github.com/emersion/go-imap/client.(*Client).UidFetch(0xc00485a000, 0xc00aec9340, 0xc003ed8690, 0x3, 0x3, 0xc0001bae40, 0x1, 0x2)
D:/Go/pkg/mod/github.com/emersion/[email protected]/client/cmd_selected.go:169 +0x65
// exec UidFetch
grabmail/grab/client.(*imap).FetchInboxMail(0xc00353e0f0, 0xc73f00, 0xc00038a000, 0xc000f7d1c0, 0x7, 0x7, 0x7, 0x7, 0x8, 0x0, ...)
D:/Go/src/grabmail/grab/client/imap.go:151 +0x459
grabmail/grab.run(0xc73f00, 0xc00038a000, 0xb8ce75, 0x7, 0xc000497c80, 0x0, 0x0)
D:/Go/src/grabmail/grab/grab.go:205 +0x6cf
grabmail/grab.(*Grab).acRun.func2(0xc00017d200, 0xc0000982a0, 0xc0000a8550, 0xc73f00, 0xc00038a000, 0xc000497c80)
D:/Go/src/grabmail/grab/grab.go:153 +0x155
created by grabmail/grab.(*Grab).acRun
D:/Go/src/grabmail/grab/grab.go:135 +0x38c
// guess this goroutine by `go reader()` after exec UidFetch
goroutine 27596 [IO wait, 75 minutes]:
internal/poll.runtime_pollWait(0x7f0a57e7ef60, 0x72, 0xc0074806c0)
C:/Go/src/runtime/netpoll.go:173 +0x66
internal/poll.(*pollDesc).wait(0xc0004abd18, 0x72, 0xffffffffffffff00, 0xc6da80, 0x11454d8)
C:/Go/src/internal/poll/fd_poll_runtime.go:85 +0x9a
internal/poll.(*pollDesc).waitRead(0xc0004abd18, 0xc002362000, 0x7f1b, 0x7f1b)
C:/Go/src/internal/poll/fd_poll_runtime.go:90 +0x3d
internal/poll.(*FD).Read(0xc0004abd00, 0xc0023620e5, 0x7f1b, 0x7f1b, 0x0, 0x0, 0x0)
C:/Go/src/internal/poll/fd_unix.go:169 +0x179
net.(*netFD).Read(0xc0004abd00, 0xc0023620e5, 0x7f1b, 0x7f1b, 0x408a3b, 0xc00001c000, 0xace9c0)
C:/Go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc0038c8028, 0xc0023620e5, 0x7f1b, 0x7f1b, 0x0, 0x0, 0x0)
C:/Go/src/net/net.go:177 +0x68
crypto/tls.(*block).readFromUntil(0xc006253ef0, 0xc6c780, 0xc0038c8028, 0x401d, 0xc0038c8028, 0x0)
C:/Go/src/crypto/tls/conn.go:492 +0x89
crypto/tls.(*Conn).readRecord(0xc00006f180, 0xbcde17, 0xc00006f2a0, 0x0)
C:/Go/src/crypto/tls/conn.go:638 +0x1f3
crypto/tls.(*Conn).Read(0xc00006f180, 0xc0086cc000, 0x1a520, 0x1a520, 0x0, 0x0, 0x0)
C:/Go/src/crypto/tls/conn.go:1145 +0xf1
bufio.(*Reader).Read(0xc00066d440, 0xc0086cc000, 0x1a520, 0x1a520, 0x4000, 0x0, 0x0)
C:/Go/src/bufio/bufio.go:202 +0x127
io.ReadAtLeast(0xc6b180, 0xc0018c0060, 0xc008680000, 0x66520, 0x66520, 0x66520, 0xa7fa80, 0x1, 0xc008680000)
C:/Go/src/io/io.go:310 +0x88
io.ReadFull(0xc6b180, 0xc0018c0060, 0xc008680000, 0x66520, 0x66520, 0x66520, 0x0, 0xc001ada680)
C:/Go/src/io/io.go:329 +0x58
github.com/emersion/go-imap.(*Reader).ReadLiteral(0xc0018c0060, 0x0, 0x0, 0x0, 0x0)
D:/Go/pkg/mod/github.com/emersion/[email protected]/read.go:256 +0x257
github.com/emersion/go-imap.(*Reader).ReadFields(0xc0018c0060, 0x28, 0x1, 0x0, 0x0, 0x1)
D:/Go/pkg/mod/github.com/emersion/[email protected]/read.go:314 +0x599
github.com/emersion/go-imap.(*Reader).ReadList(0xc0018c0060, 0x0, 0x0, 0x0, 0x0, 0xc0035f69a0)
D:/Go/pkg/mod/github.com/emersion/[email protected]/read.go:364 +0x12c
github.com/emersion/go-imap.(*Reader).ReadFields(0xc0018c0060, 0xc007480e18, 0x9d9b58, 0xc007480e18, 0x40c3d8, 0x30)
D:/Go/pkg/mod/github.com/emersion/[email protected]/read.go:318 +0x5d9
github.com/emersion/go-imap.(*Reader).ReadLine(0xc0018c0060, 0xc003cab2c0, 0x0, 0x0, 0x1, 0xc0035f6980)
D:/Go/pkg/mod/github.com/emersion/[email protected]/read.go:380 +0x2f
github.com/emersion/go-imap.ReadResp(0xc0018c0060, 0x6, 0xc00051b3e0, 0x0, 0x0)
D:/Go/pkg/mod/github.com/emersion/[email protected]/response.go:91 +0x162
github.com/emersion/go-imap/client.(*Client).readOnce(0xc00485a000, 0xbcda01, 0x0, 0x0)
D:/Go/pkg/mod/github.com/emersion/[email protected]/client/client.go:145 +0x50
github.com/emersion/go-imap/client.(*Client).reader(0xc00485a000)
D:/Go/pkg/mod/github.com/emersion/[email protected]/client/client.go:130 +0x5d
created by github.com/emersion/go-imap/client.(*Client).handleGreetAndStartReading
D:/Go/pkg/mod/github.com/emersion/[email protected]/client/client.go:502 +0x16e
dialer := new(net.Dialer)
dialer.Timeout = time.Duration(30) * time.Minute
cli, err := DialWithDialer(dialer, addr)
// DialWithDialer connects to an IMAP server using an unencrypted connection
// using dialer.Dial.
//
// Among other uses, this allows to apply a dial timeout.
func DialWithDialer(dialer *net.Dialer, address string) (c *Client, err error) {
conn, err := dialer.Dial("tcp", address)
if err != nil {
return nil, err
}
// We don't return to the caller until we try to receive a greeting. As such,
// there is no way to set the client's Timeout for that action. As a
// workaround, if the dialer has a timeout set, use that for the connection's
// deadline.
if dialer.Timeout > 0 {
err = conn.SetDeadline(time.Now().Add(dialer.Timeout))
if err != nil {
return
}
}
c, err = New(conn)
return
}
Any suggestion will be helpful. Tks.
I have got the same issue @beiping96 beiping96 Have you solved the issue?
Closing because this is an issue about go-imap v1. I'm now focusing on go-imap v2.
Please re-open if you can reproduce with go-imap v2.