Removed wait operations

This commit is contained in:
M66B 2019-03-08 15:26:12 +00:00
parent 5cd39ffeb9
commit e221a06247
4 changed files with 38 additions and 84 deletions

1
FAQ.md
View File

@ -200,7 +200,6 @@ The low priority status bar notification shows the number of pending operations,
* *body*: download message text
* *attachment*: download attachment
* *sync*: synchronize local and remote messages
* *wait*: wait for message synchronization
Operations are processed only when there is a connection to the email server or when manually synchronizing.
See also [this FAQ](#user-content-faq16).

View File

@ -202,7 +202,7 @@ class Core {
break;
case EntityOperation.WAIT:
return;
break;
default:
throw new IllegalArgumentException("Unknown operation=" + op.name);
@ -331,6 +331,10 @@ class Core {
if (message.answered.equals(answered))
return;
// This will be fixed when synchronizing the message
if (message.uid == null)
return;
Message imessage = ifolder.getMessageByUID(message.uid);
if (imessage == null)
throw new MessageRemovedException();
@ -481,10 +485,8 @@ class Core {
boolean autoread = (jargs.length() > 1 && jargs.getBoolean(1));
long uid;
if (!copy &&
istore.hasCapability("MOVE") &&
istore.hasCapability("UIDPLUS") &&
!EntityFolder.DRAFTS.equals(folder.type) &&
!EntityFolder.DRAFTS.equals(target.type)) {
// Autoread
@ -493,10 +495,7 @@ class Core {
imessage.setFlag(Flags.Flag.SEEN, true);
// Move message to target folder
AppendUID[] uids = ifolder.moveUIDMessages(new Message[]{imessage}, itarget);
if (uids == null || uids.length == 0)
throw new MessageRemovedException("Message not moved");
uid = uids[0].uid;
itarget.appendMessages(new Message[]{imessage});
} else {
if (!copy)
Log.w(folder.name + " MOVE by DELETE/APPEND");
@ -536,65 +535,42 @@ class Core {
icopy.setFlag(Flags.Flag.DRAFT, true);
// Append target
uid = append(istore, itarget, (MimeMessage) icopy);
long uid = append(istore, itarget, (MimeMessage) icopy);
try {
// Fixed timing issue of at least Courier based servers
itarget.close(false);
itarget.open(Folder.READ_WRITE);
// Fixed timing issue of at least Courier based servers
itarget.close(false);
itarget.open(Folder.READ_WRITE);
// Some providers, like Gmail, don't honor the appended seen flag
if (itarget.getPermanentFlags().contains(Flags.Flag.SEEN)) {
boolean seen = (autoread || message.ui_seen);
icopy = itarget.getMessageByUID(uid);
if (seen != icopy.isSet(Flags.Flag.SEEN)) {
Log.i(target.name + " Fixing id=" + message.id + " seen=" + seen);
icopy.setFlag(Flags.Flag.SEEN, seen);
}
// Some providers, like Gmail, don't honor the appended seen flag
if (itarget.getPermanentFlags().contains(Flags.Flag.SEEN)) {
boolean seen = (autoread || message.ui_seen);
icopy = itarget.getMessageByUID(uid);
if (seen != icopy.isSet(Flags.Flag.SEEN)) {
Log.i(target.name + " Fixing id=" + message.id + " seen=" + seen);
icopy.setFlag(Flags.Flag.SEEN, seen);
}
}
// This is not based on an actual case, so this is just a safeguard
if (itarget.getPermanentFlags().contains(Flags.Flag.DRAFT)) {
boolean draft = EntityFolder.DRAFTS.equals(target.type);
icopy = itarget.getMessageByUID(uid);
if (draft != icopy.isSet(Flags.Flag.DRAFT)) {
Log.i(target.name + " Fixing id=" + message.id + " draft=" + draft);
icopy.setFlag(Flags.Flag.DRAFT, draft);
}
// This is not based on an actual case, so this is just a safeguard
if (itarget.getPermanentFlags().contains(Flags.Flag.DRAFT)) {
boolean draft = EntityFolder.DRAFTS.equals(target.type);
icopy = itarget.getMessageByUID(uid);
if (draft != icopy.isSet(Flags.Flag.DRAFT)) {
Log.i(target.name + " Fixing id=" + message.id + " draft=" + draft);
icopy.setFlag(Flags.Flag.DRAFT, draft);
}
}
// Delete source
if (!copy) {
imessage.setFlag(Flags.Flag.DELETED, true);
ifolder.expunge();
}
} catch (MessageRemovedException ignored) {
} catch (Throwable ex) {
Log.w(ex);
// Delete source
if (!copy) {
imessage.setFlag(Flags.Flag.DELETED, true);
ifolder.expunge();
}
} finally {
if (itarget.isOpen())
itarget.close();
}
}
Log.i(folder.name + " moved uid=" + uid);
if (jargs.length() > 2 && !jargs.isNull(2)) {
long tmpid = jargs.getLong(2);
try {
db.beginTransaction();
db.message().setMessageUid(tmpid, uid);
int waits = -1;
if (jargs.length() > 3) {
long waitid = jargs.getLong(3);
waits = db.operation().deleteOperation(waitid);
}
db.setTransactionSuccessful();
Log.i(folder.name + " set id=" + tmpid + " uid=" + uid + " waits=" + waits);
} finally {
db.endTransaction();
}
}
}
private static void onDelete(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPFolder ifolder) throws MessagingException {
@ -1268,6 +1244,11 @@ class Core {
}
if (!message.answered.equals(answered) || !message.answered.equals(message.ui_answered)) {
if (!answered && message.ui_answered && ifolder.getPermanentFlags().contains(Flags.Flag.ANSWERED)) {
// This can happen when the answered operation was skipped because the message was moving
answered = true;
imessage.setFlag(Flags.Flag.ANSWERED, answered);
}
update = true;
message.answered = answered;
message.ui_answered = answered;

View File

@ -175,24 +175,9 @@ public class EntityOperation {
}
// Cross account move
if (source.account.equals(target.account)) {
jargs.put(2, tmpid);
// Block operations until message is moved
JSONArray wargs = new JSONArray();
wargs.put(source.id);
wargs.put(message.id);
EntityOperation wait = new EntityOperation();
wait.folder = target.id;
wait.message = tmpid;
wait.name = EntityOperation.WAIT;
wait.args = wargs.toString();
wait.created = new Date().getTime();
wait.id = db.operation().insertOperation(wait);
jargs.put(3, wait.id);
} else {
if (source.account.equals(target.account))
jargs.put(2, tmpid); // Can be null
else {
if (message.raw != null && message.raw) {
name = ADD;
folder = target.id;

View File

@ -819,7 +819,6 @@ public class ServiceSynchronize extends LifecycleService {
@Override
public void run() {
db.operation().liveOperations(folder.id).observe(owner, new Observer<List<EntityOperation>>() {
private List<Long> waiting = new ArrayList<>();
private List<Long> handling = new ArrayList<>();
private final ExecutorService folderExecutor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory);
private final PowerManager.WakeLock wlFolder = pm.newWakeLock(
@ -829,21 +828,11 @@ public class ServiceSynchronize extends LifecycleService {
public void onChanged(final List<EntityOperation> operations) {
boolean process = false;
List<Long> ops = new ArrayList<>();
List<Long> waits = new ArrayList<>();
for (EntityOperation op : operations) {
if (EntityOperation.WAIT.equals(op.name))
waits.add(op.id);
if (!handling.contains(op.id))
process = true;
ops.add(op.id);
}
for (long wait : waits)
if (!waiting.contains(wait)) {
Log.i(folder.name + " not waiting anymore");
process = true;
break;
}
waiting = waits;
handling = ops;
if (handling.size() > 0 && process) {