Prevent reconnect loop from occurring
I noticed recently that when composing a draft message, if the connection to the Drafts folder was dropped by the server, Geary would enter a fast reconnect loop. The problem was that, even if Imap.Folder signals "disconnect", it's close_async() must be called. This adds that logic to the background reestablishment code.
This commit is contained in:
parent
c7b56db19a
commit
86f1854edf
1 changed files with 32 additions and 10 deletions
|
|
@ -643,25 +643,26 @@ private class Geary.ImapEngine.GenericFolder : Geary.AbstractFolder, Geary.Folde
|
||||||
|
|
||||||
if (closing_remote_folder != null) {
|
if (closing_remote_folder != null) {
|
||||||
// to avoid keeping the caller waiting while the remote end closes (i.e. drops the
|
// to avoid keeping the caller waiting while the remote end closes (i.e. drops the
|
||||||
// connection or performs an IMAP CLOSE operation), close it in the background
|
// connection or performs an IMAP CLOSE operation), close it in the background and
|
||||||
|
// reestablish connection there, if necessary
|
||||||
//
|
//
|
||||||
// TODO: Problem with this is that we cannot effectively signal or report a close error,
|
// TODO: Problem with this is that we cannot effectively signal or report a close error,
|
||||||
// because by the time this operation completes the folder is considered closed. That
|
// because by the time this operation completes the folder is considered closed. That
|
||||||
// may not be important to most callers, however.
|
// may not be important to most callers, however.
|
||||||
closing_remote_folder.close_async.begin(cancellable);
|
//
|
||||||
|
// It also means the reference to the Folder must be maintained until completely
|
||||||
|
// closed. Also not a problem, as GenericAccount does that internally. However, this
|
||||||
|
// might be an issue if GenericAccount removes this folder due to a user command or
|
||||||
|
// detection on the server, so this background op keeps a reference to the Folder
|
||||||
|
close_remote_folder_async.begin(this, closing_remote_folder, remote_reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
remote_opened = false;
|
remote_opened = false;
|
||||||
|
|
||||||
// reestablish connection (which requires renormalizing the remote with the local) if
|
// if remote reason is an error, then close_remote_folder_async() will be performing
|
||||||
// close was in error
|
// reestablishment, so go no further
|
||||||
if (remote_reason.is_error()) {
|
if (remote_reason.is_error())
|
||||||
debug("Reestablishing broken connect to %s", to_string());
|
|
||||||
|
|
||||||
open_internal(OpenFlags.NO_DELAY, null);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// forced closed one way or another
|
// forced closed one way or another
|
||||||
open_count = 0;
|
open_count = 0;
|
||||||
|
|
@ -703,6 +704,27 @@ private class Geary.ImapEngine.GenericFolder : Geary.AbstractFolder, Geary.Folde
|
||||||
return old_remote_folder;
|
return old_remote_folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See note in close_async() for why this method is static and uses an owned ref
|
||||||
|
private static async void close_remote_folder_async(owned GenericFolder folder,
|
||||||
|
owned Imap.Folder remote_folder, Folder.CloseReason remote_reason) {
|
||||||
|
// force the remote closed; if due to a remote disconnect and plan on reopening, *still*
|
||||||
|
// need to do this
|
||||||
|
try {
|
||||||
|
yield remote_folder.close_async(null);
|
||||||
|
} catch (Error err) {
|
||||||
|
debug("Unable to close remote %s: %s", remote_folder.to_string(), err.message);
|
||||||
|
|
||||||
|
// fallthrough
|
||||||
|
}
|
||||||
|
|
||||||
|
// reestablish connection (which requires renormalizing the remote with the local) if
|
||||||
|
// close was in error
|
||||||
|
if (remote_reason.is_error()) {
|
||||||
|
debug("Reestablishing broken connection to %s", folder.to_string());
|
||||||
|
folder.open_internal(OpenFlags.NO_DELAY, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override async void find_boundaries_async(Gee.Collection<Geary.EmailIdentifier> ids,
|
public override async void find_boundaries_async(Gee.Collection<Geary.EmailIdentifier> ids,
|
||||||
out Geary.EmailIdentifier? low, out Geary.EmailIdentifier? high,
|
out Geary.EmailIdentifier? low, out Geary.EmailIdentifier? high,
|
||||||
Cancellable? cancellable = null) throws Error {
|
Cancellable? cancellable = null) throws Error {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue