K-9 often can't connect to the internet after a while. I have to kill and reopen it to make it work.
Internet in the same time works perfectly for other apps (browser, for example).
How can I help you for improving this ?
K-9 Mail version: 5.402 F-droid
Android version: 7.1.2 (LOS)
Account type (IMAP, POP3, WebDAV/Exchange): IMAP
Sounds to me you need to disable "battery optimization" for k9.
Battery optimization is already disabled for K-9.
But, to better understand, I have activated the debug log mode. When K-9 will be blocked I think I will be able to see what is the blocking instruction. And, for sure, since I have activated this debug log mode, the problem does not happen anymore... !

@Massedil thanks for finding this workaround. I can confirm it is working even on AICP Custom ROM.
Hello,
I have investigating for this problem with debug log activated.
Here a fresh log file :
02-22 19:50:39.040 I/MessagingController(5485): Running command 'getFolderUnread:XXXXXXXXXX.YYYY:INBOX', seq = 79 (foreground priority)
02-22 19:50:39.049 I/MessagingController(5485): Command 'getFolderUnread:XXXXXXXXXX.YYYY:INBOX' completed
02-22 19:50:43.285 I/MessagingController(5485): Running command 'synchronizeMailbox', seq = 80 (background priority)
02-22 19:50:43.286 I/MessagingController(5485): Synchronizing folder XXXXXXXXXX.YYYY:INBOX
02-22 19:50:43.287 D/MessagingController(5485): SYNC: About to process pending commands for account XXXXXXXXXX.YYYY
02-22 19:50:43.292 V/MessagingController(5485): SYNC: About to get local folder INBOX
02-22 19:50:43.314 D/LocalFolder(5485): Updated last UID for folder INBOX to 6308
02-22 19:50:43.319 V/MessagingController(5485): SYNC: About to get remote folder INBOX
02-22 19:50:43.321 V/MessagingController(5485): SYNC: About to open remote folder INBOX
02-22 19:50:43.325 V/ImapConnection(5485): conn264303763>>> 127 NOOP
02-22 19:51:43.418 V/ImapConnection(5485): conn160229065>>> 124 NOOP
02-22 19:52:43.896 D/ImapConnection(5485): Connecting to imap.XXXXXXXXXX.YYYY as imap.XXXXXXXXXX.YYYY/A.B.C.D
02-22 19:52:44.124 V/ImapConnection(5485): conn171592757 <<< #null# [OK, [CAPABILITY, IMAP4rev1, LITERAL+, SASL-IR, LOGIN-REFERRALS, ID, ENABLE, IDLE, AUTH=PLAIN], Dovecot ready.]
The problem is always at this moment : V/ImapConnection(5485): connXXXXXXXXXX>>> nnn NOOP.
Here are old logs :
01-20 14:17:48.571 V/ImapConnection(15563): conn229504011>>> 33 NOOP
01-20 14:18:49.008 D/ImapConnection(15563): Connecting to imap.XXXXXXXXXX.YYYY as imap.XXXXXXXXXX.YYYY/A.B.C.D
[...]
01-21 00:52:50.103 V/ImapConnection(15563): conn206356584>>> 9 NOOP
01-21 00:53:50.504 D/ImapConnection(15563): Connecting to imap.XXXXXXXXXX.YYYY as imap.XXXXXXXXXX.YYYY/A.B.C.D
[...]
01-24 18:44:30.870 V/ImapConnection(4218): conn155697025>>> 9 NOOP
01-24 18:45:31.548 D/ImapConnection(4218): Connecting to imap.XXXXXXXXXX.YYYY as imap.XXXXXXXXXX.YYYY/A.B.C.D
So the operation seems to time out.
Sometimes, it works fine :
01-20 14:18:52.421 V/ImapConnection(15563): conn206356584>>> 7 NOOP
01-20 14:18:52.459 V/ImapResponseParser(15563): conn206356584<<<#7# [OK, NOOP completed.]
Here, I think, is the 60 seconds timeout :
https://github.com/k9mail/k-9/blob/master/k9mail-library/src/main/java/com/fsck/k9/mail/store/RemoteStore.java#L29
Here, I think, is the ImapConnection classes that uses this timeout :
https://github.com/k9mail/k-9/blob/master/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java
Here, I think, is the line where the looong NOOP call is done :
https://github.com/k9mail/k-9/blob/master/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapStore.java#L327
A timeout of 2 or 5 seconds is not reasonable for the internet. In rare cases people have a regular network latency in that order.
I believe a better way to fix this is to close IMAP connections in the connection pool after a short timeout, say 5 -10 minutes. Most zombie connections (you can't reach the other side, but as far as your OS is concerned the connection is still established) are due to NAT gateways that kill the mapping of TCP connections after a timeout. Usually that timeout is around 30 minutes, but some providers are more aggressive and use shorter timeouts.
A timeout of 2 or 5 seconds is not reasonable for the internet.
Sure, I suggested it only in the case I described.
But, why don't we close the IMAP connection after using it ? (Except keeping special connections for PUSH, if necessary)
I mean why when 10 minutes after manually fetching my emails, there is still an open TCP connection that we try to reuse ?
It was like this when I joined the project. So I can only speculate. My guess is because of the "high" cost of establishing a connection and logging in (there's quite a bit of back and forth). Opening an unread message usually triggers a 'mark as read' operation that sends a command to the server. You don't want to create new IMAP connections for that all the time when you can reuse an existing one.
Ok, well, I understand that : it's better to do not open a new connection for each instruction to send to the server.
So, in that case, for me, a reasonable time to keep a TCP connection opened in the pool is not about minutes but seconds (still except for IMAP PUSH). Closing a TCP connection in the pool after 30 seconds of ___inactivity___ seems good, no ?
Because what we want to avoid is creating and destroying a lot of TCP connection, not keeping a TCP connection opened for minutes.
I don't see anything wrong with keeping a connection open for a couple of minutes. I don't want to optimize for super aggressive NAT gateways that break the internet.
A timeout of 30 seconds means you have to be done reading an email in 30 seconds in order to be able to reuse the IMAP connection when you trigger a mark as read upon opening the next email. It feels like that would make the connection pool almost useless.
A timeout of 30 seconds means you have to be done reading an email in 30 seconds in order to be able to reuse the IMAP connection when you trigger a mark as read upon opening the next email. It feels like that would make the connection pool almost useless.
I agree.
So, may be close TCP connections after some seconds when the app is in the background ? And/or if the screen is off ? In this case, there is no need to keep them open, no ?
I believe a better way to fix this is to close IMAP connections in the connection pool after a short timeout, say 5 -10 minutes.
After, may be your proposition will work, but it is just that I think keeping an opened TCP connection on a mobile device for 5/10 minutes without sending nothing on it will possibly fail, like now. And be blocked by the long 60 seconds timeout in that case.
Here they speak about difficulty to keep a TCP connection opened :
https://stackoverflow.com/questions/865987/
May be there is two approach to solve the problem :
If the connection is opened since a long time, use a smaller time out : more the last sent command is far, less will be the timeout value. (not like now)
When the user is using the app, try to reuse connections.
When the user is not using the app anymore, close the connections.
Are you planning on implementing this? Why are you insisting on a super low timeout being the answer? Did you actually check whether the proposed idle connection timeout of 10 minutes wouldn't work in your case?
First, sorry, I really just want to be constructive and I really don't presume to be right.
Did you actually check whether the proposed idle connection timeout of 10 minutes wouldn't work in your case?
No, I have not checked.
But, if it works because you are right and a NAS on my network kills the connection after 10 minutes or more, the problem will still happens for a NAS that kills the connection after 2 minutes.
I don't know if it is accurate, but here someone speaks about seconds for a NAS to maintain a TCP connection in some configurations : https://stackoverflow.com/a/866003
Why are you insisting on a super low timeout being the answer?
I'm not insisting on this. My point n掳2 (close the TCP connection when it's accurate) don't speak about timeout.
To summurize, and if I have well understood, the problem is that a user can wait 60 seconds, time for the app to understand that the TCP channel is broken and to create a new one. I'm just searching with you how to improve it.
Are you planning on implementing this?
I don't know the project/code structure. But if you can and want to help me, I can try.
Again, I just want to be constructive. Sorry if you thought I was aggressive with you, it's not what I wanted.
Sincerely.
Closing TCP connections when the app is not in focus / the screen is off, completely kills background email. It's not a workable solution.
Closing TCP connections that are idle for more than say 30 seconds makes IDLE completely useless because it forces IDLE connections to spam IDLE keep alives.
The person on that StackOverflow post says it's specified in seconds. They aren't saying it's a few seconds.
These entries have a default timeout value of 86400 seconds (24 hours)
...
TCP translations time out after 24 hours, unless a RST or FIN is seen on the stream, in which case it times out in 1 minute.
We are defaulting to 60 minutes, way inside the standard allowance (and Cisco make so much networking kit that their defaults are pretty industry standard).
We're only talking about IMAP connections that aren't currently in use and are "parked" in ImapStore's connection pool. Currently we have no timeout to close those parked connections and they can be around for hours. That's also why a NOOP command is sent. It's to test if the connection is still alive before handing it to a caller of ImapStore.getConnection(). If the connection is alive from the OS's point of view but the other side never receives any packets (e.g. NAT mapping was killed), it'll take the read timeout of 60 seconds to detect a connection as dead.
So my suggestion is to close those parked connections before their NAT mapping expires. Usually the NAT timeout is around 30 minutes (so e.g. IMAP IDLE can work). We probably don't need to keep them open for that long. Around 10 minutes sounds like a reasonable value to me. But ideally, we use some mechanism that closes connections when the modem is going to send some data anyway. Otherwise we might wake up the modem just to close a connection.
It's also worth looking at #2652 here - we have a very long read timeout which affects checking for NOOP responses from dead connections.
Is there an option to specify which of NOOP or IDLE is used? Or another command often not used for this purpose ro escape detection?