From 1cf26c4ca6dcfa20ad5766e26f1e62d25cc6f955 Mon Sep 17 00:00:00 2001 From: Tim Su Date: Mon, 25 Apr 2011 02:47:35 -0700 Subject: [PATCH] Multi-threading google tasks sync --- .../gtasks/sync/GtasksSyncProvider.java | 112 +++++++++++------- 1 file changed, 68 insertions(+), 44 deletions(-) diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java index 1e53355b1..cc1ec096b 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.concurrent.Semaphore; import org.json.JSONException; @@ -204,7 +205,7 @@ public class GtasksSyncProvider extends SyncProvider { protected void performSync() { StatisticsService.reportEvent("gtasks-started"); gtasksPreferenceService.recordSyncStart(); - System.err.println("- -------- SYNC START!!!!"); + System.err.println("- -------- SYNC STARTED"); createdWithoutId = new ArrayList(); try { @@ -231,7 +232,7 @@ public class GtasksSyncProvider extends SyncProvider { Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH); ContextManager.getContext().sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); - System.err.println("- ------ SYNC FINITO!!!!"); + System.err.println("- ------ SYNC FINISHED"); } catch (IllegalStateException e) { // occurs when application was closed } catch (Exception e) { @@ -261,11 +262,7 @@ public class GtasksSyncProvider extends SyncProvider { throws IOException { // first, pull all tasks. then we can write them // include deleted tasks so we can delete them in astrid - try { - data.remoteUpdated = readAllRemoteTasks(true); - } catch (JSONException e) { - throw new GoogleTasksException(e); - } + data.remoteUpdated = readAllRemoteTasks(true); // match remote tasks to locally created tasks HashMap locals = new HashMap(); @@ -345,17 +342,36 @@ public class GtasksSyncProvider extends SyncProvider { // ------------------------------------------------- create / push / pull // ---------------------------------------------------------------------- - private ArrayList readAllRemoteTasks(boolean includeDeleted) - throws JSONException, IOException, GoogleLoginException { - ArrayList remoteTasks = new ArrayList(); - for(StoreObject dashboard : gtasksListService.getLists()) { - String listId = dashboard.getValue(GtasksList.REMOTE_ID); - - System.err.println("ACTION: getTasks, " + listId); - GetTasksAction action = new GetTasksAction(listId, includeDeleted); - taskService.executeActions(action); - List list = action.getGoogleTasks(); - addRemoteTasksToList(list, remoteTasks); + private ArrayList readAllRemoteTasks(final boolean includeDeleted) { + final ArrayList remoteTasks = new ArrayList(); + final Semaphore listsFinished = new Semaphore(0); + + // launch threads + StoreObject[] lists = gtasksListService.getLists(); + for(final StoreObject dashboard : lists) { + new Thread(new Runnable() { + @Override + public void run() { + try { + String listId = dashboard.getValue(GtasksList.REMOTE_ID); + System.err.println("ACTION: getTasks, " + listId); + GetTasksAction action = new GetTasksAction(listId, includeDeleted); + taskService.executeActions(action); + List list = action.getGoogleTasks(); + addRemoteTasksToList(list, remoteTasks); + } catch (Exception e) { + handleException("read-remotes", e, false); + } finally { + listsFinished.release(); + } + } + }).start(); + } + + try { + listsFinished.acquire(lists.length); + } catch (InterruptedException e) { + handleException("wait-for-remotes", e, false); } return remoteTasks; } @@ -430,24 +446,14 @@ public class GtasksSyncProvider extends SyncProvider { return local; } - private String updateTaskHelper(GtasksTaskContainer local, - GtasksTaskContainer remote, TaskBuilder builder) throws IOException { + private void updateTaskHelper(final GtasksTaskContainer local, + final GtasksTaskContainer remote, TaskBuilder builder) throws IOException { - String idTask = local.gtaskMetadata.getValue(GtasksMetadata.ID); - String idList = local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID); + final String idTask = local.gtaskMetadata.getValue(GtasksMetadata.ID); + final String idList = local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID); try { - - // moving between lists - if(remote != null && !idList.equals(remote.gtaskMetadata.getValue( - GtasksMetadata.LIST_ID))) { - System.err.println("ACTION: moveTask(5), " + idTask + ", " + idList + " to " + - remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID)); - taskService.executeActions(a.moveTask(idTask, idList, - remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), null)); - } - - // other properties + // set properties if(shouldTransmit(local, Task.DUE_DATE, remote)) builder.taskDate(local.task.getValue(Task.DUE_DATE)); if(shouldTransmit(local, Task.COMPLETION_DATE, remote)) @@ -457,10 +463,8 @@ public class GtasksSyncProvider extends SyncProvider { if(shouldTransmit(local, Task.NOTES, remote)) builder.notes(local.task.getValue(Task.NOTES)); - String id = idList; - // write task (and perform move action if requested) - ListAction action; + final ListAction action; if(builder instanceof TaskModifier) { System.err.println("ACTION: task edit (6), " + idTask); action = ((TaskModifier) builder).done(); @@ -470,15 +474,35 @@ public class GtasksSyncProvider extends SyncProvider { } else throw new GoogleTasksException("Unknown builder " + builder.getClass()); - if(idTask != null && local.parentId != null && (remote == null || local.parentId != remote.parentId || - local.priorSiblingId != remote.priorSiblingId)) { - System.err.println("ACTION: move(1) - " + idTask + ", " + local.parentId + ", " + local.priorSiblingId); - ListAction moveAction = l.move(idTask, local.parentId, local.priorSiblingId); - taskService.executeListActions(idList, action, moveAction); - } else if(action.toJson(idList).getJSONObject("entity_delta").length() > 0) - taskService.executeListActions(idList, action); + new Thread(new Runnable() { + @Override + public void run() { + try { + if(idTask != null && local.parentId != null && (remote == null || local.parentId != remote.parentId || + local.priorSiblingId != remote.priorSiblingId)) { + System.err.println("ACTION: move(1) - " + idTask + ", " + local.parentId + ", " + local.priorSiblingId); + ListAction moveAction = l.move(idTask, local.parentId, local.priorSiblingId); + taskService.executeListActions(idList, action, moveAction); + } else if(action.toJson(idList).getJSONObject("entity_delta").length() > 0) { + taskService.executeListActions(idList, action); + } + + // moving between lists + if(remote != null && !idList.equals(remote.gtaskMetadata.getValue( + GtasksMetadata.LIST_ID))) { + System.err.println("ACTION: moveTask(5), " + idTask + ", " + idList + " to " + + remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID)); + taskService.executeActions(a.moveTask(idTask, idList, + remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), null)); + } + } catch (IOException e) { + handleException("update-task", e, false); + } catch (JSONException e) { + handleException("update-task-json", e, false); + } + } + }).start(); - return id; } catch (JSONException e) { throw new GoogleTasksException(e); }