From ea42bb828c9ae2a5328eb467fab818a9e2c77212 Mon Sep 17 00:00:00 2001 From: Sam Bosley Date: Thu, 29 Mar 2012 16:56:39 -0700 Subject: [PATCH] Fixed gtasks sync timing issues --- .../astrid/gtasks/sync/GtasksSyncService.java | 99 +++++++++++++------ .../gtasks/sync/GtasksSyncV2Provider.java | 1 + 2 files changed, 69 insertions(+), 31 deletions(-) diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java index c86b04858..83471ae10 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncService.java @@ -2,6 +2,7 @@ package com.todoroo.astrid.gtasks.sync; import java.io.IOException; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.Semaphore; import android.content.ContentValues; import android.text.TextUtils; @@ -43,7 +44,9 @@ public final class GtasksSyncService { private final LinkedBlockingQueue operationQueue = new LinkedBlockingQueue(); - private abstract class SyncOnSaveOperation { /**/ } + private abstract class SyncOnSaveOperation { + abstract public void op(GtasksInvoker invoker) throws IOException; + } private class TaskPushOp extends SyncOnSaveOperation { protected Task model; @@ -52,47 +55,44 @@ public final class GtasksSyncService { public TaskPushOp(Task model) { this.model = model; } + + @Override + public void op(GtasksInvoker invoker) throws IOException { + if(DateUtilities.now() - creationDate < 1000) + AndroidUtilities.sleepDeep(1000 - (DateUtilities.now() - creationDate)); + pushTaskOnSave(model, model.getMergedValues(), invoker, false); + } } - class MoveOp extends SyncOnSaveOperation { + private class MoveOp extends SyncOnSaveOperation { protected Metadata metadata; public MoveOp(Metadata metadata) { this.metadata = metadata; } + + @Override + public void op(GtasksInvoker invoker) throws IOException { + pushMetadataOnSave(metadata, invoker); + } + } + + private class NotifyOp extends SyncOnSaveOperation { + private final Semaphore sema; + + public NotifyOp(Semaphore sema) { + this.sema = sema; + } + + @Override + public void op(GtasksInvoker invoker) throws IOException { + sema.release(); + } } - @SuppressWarnings("nls") public void initialize() { - new Thread(new Runnable() { - public void run() { - while (true) { - SyncOnSaveOperation op; - try { - op = operationQueue.take(); - } catch (InterruptedException e) { - continue; - } - try { - if (!gtasksPreferenceService.isOngoing()) { - GtasksInvoker invoker = new GtasksInvoker(gtasksPreferenceService.getToken()); - if (op instanceof TaskPushOp) { - TaskPushOp taskPush = (TaskPushOp)op; - if(DateUtilities.now() - taskPush.creationDate < 1000) - AndroidUtilities.sleepDeep(1000 - (DateUtilities.now() - taskPush.creationDate)); - pushTaskOnSave(taskPush.model, taskPush.model.getMergedValues(), invoker, false); - } else if (op instanceof MoveOp) { - MoveOp move = (MoveOp)op; - pushMetadataOnSave(move.metadata, invoker); - } - } - } catch (IOException e) { - Log.w("gtasks-sync-error", "Sync on save failed", e); - } - } - } - }).start(); + new OperationPushThread(operationQueue).start(); taskDao.addListener(new ModelUpdateListener() { public void onModelUpdated(final Task model) { @@ -115,6 +115,43 @@ public final class GtasksSyncService { }); } + private class OperationPushThread extends Thread { + private final LinkedBlockingQueue queue; + + public OperationPushThread(LinkedBlockingQueue queue) { + this.queue = queue; + } + + @SuppressWarnings("nls") + @Override + public void run() { + while (true) { + SyncOnSaveOperation op; + try { + op = queue.take(); + } catch (InterruptedException e) { + continue; + } + try { + GtasksInvoker invoker = new GtasksInvoker(gtasksPreferenceService.getToken()); + op.op(invoker); + } catch (IOException e) { + Log.w("gtasks-sync-error", "Sync on save failed", e); + } + } + } + } + + public void waitUntilEmpty() { + Semaphore sema = new Semaphore(0); + operationQueue.offer(new NotifyOp(sema)); + try { + sema.acquire(); + } catch (InterruptedException e) { + // Ignored + } + } + private static final Property[] TASK_PROPERTIES = { Task.ID, Task.TITLE, Task.NOTES, Task.DUE_DATE, Task.COMPLETION_DATE, Task.DELETION_DATE }; diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java index b522a22e0..7bef636e9 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java @@ -184,6 +184,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider { try { String authToken = getValidatedAuthToken(); callback.incrementProgress(25); + gtasksSyncService.waitUntilEmpty(); final GtasksInvoker service = new GtasksInvoker(authToken); synchronizeListHelper(gtasksList, service, manual, null, callback); } finally {