Exemplo n.º 1
0
 public void repopulateQueueFromOutstandingTables() {
   syncLog("Constructing queue from outstanding tables"); // $NON-NLS-1$
   constructChangesHappenedFromOutstandingTable(Task.class, taskDao, taskOutstandingDao);
   constructChangesHappenedFromOutstandingTable(TagData.class, tagDataDao, tagOutstandingDao);
   constructChangesHappenedFromOutstandingTable(
       UserActivity.class, userActivityDao, userActivityOutstandingDao);
   constructChangesHappenedForTaskListMetadata(
       taskListMetadataDao, taskListMetadataOutstandingDao);
 }
Exemplo n.º 2
0
 // Reapplies changes still in the outstanding tables to the local database
 // Called after a batch has finished processing
 private void replayOutstandingChanges(boolean afterErrors) {
   syncLog("Replaying outstanding changes"); // $NON-NLS-1$
   new ReplayOutstandingEntries<Task, TaskOutstanding>(
           Task.class, NameMaps.TABLE_ID_TASKS, taskDao, taskOutstandingDao, afterErrors)
       .execute();
   new ReplayOutstandingEntries<TagData, TagOutstanding>(
           TagData.class, NameMaps.TABLE_ID_TAGS, tagDataDao, tagOutstandingDao, afterErrors)
       .execute();
   new ReplayTaskListMetadataOutstanding(
           taskListMetadataDao, taskListMetadataOutstandingDao, afterErrors)
       .execute();
 }
Exemplo n.º 3
0
  private void sync() {
    try {
      int batchSize = 4;
      List<ClientToServerMessage<?>> messageBatch = new ArrayList<ClientToServerMessage<?>>();
      while (true) {
        synchronized (monitor) {
          while ((pendingMessages.isEmpty() && !timeForBackgroundSync())
              || !actFmPreferenceService.isLoggedIn()
              || !syncMigration) {
            try {
              if ((pendingMessages.isEmpty() || !actFmPreferenceService.isLoggedIn())
                  && notificationId >= 0) {
                notificationManager.cancel(notificationId);
                notificationId = -1;
              }
              monitor.wait();
              AndroidUtilities.sleepDeep(
                  500L); // Wait briefly for large database operations to finish (e.g. adding a task
                         // with several tags may trigger a message before all saves are done--fix
                         // this?)

              if (!syncMigration) {
                syncMigration =
                    Preferences.getBoolean(AstridNewSyncMigrator.PREF_SYNC_MIGRATION, false);
              }
            } catch (InterruptedException e) {
              // Ignored
            }
          }
        }

        boolean recordSyncSuccess = true;
        if (timeForBackgroundSync()) {
          repopulateQueueFromOutstandingTables();
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(
                  TaskListMetadata.class, NameMaps.PUSHED_AT_TASK_LIST_METADATA),
              DEFAULT_REFRESH_RUNNABLE);
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(Task.class, NameMaps.PUSHED_AT_TASKS),
              DEFAULT_REFRESH_RUNNABLE);
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(TagData.class, NameMaps.PUSHED_AT_TAGS),
              DEFAULT_REFRESH_RUNNABLE);
          enqueueMessage(
              BriefMe.instantiateBriefMeForClass(User.class, NameMaps.PUSHED_AT_USERS),
              DEFAULT_REFRESH_RUNNABLE);
          setTimeForBackgroundSync(false);
        }

        while (messageBatch.size() < batchSize && !pendingMessages.isEmpty()) {
          ClientToServerMessage<?> message = pendingMessages.remove(0);
          if (message != null) {
            messageBatch.add(message);
          }
        }

        if (!messageBatch.isEmpty() && checkForToken()) {
          JSONPayloadBuilder payload = new JSONPayloadBuilder();
          MultipartEntity entity = new MultipartEntity();
          boolean containsChangesHappened = false;
          for (int i = 0; i < messageBatch.size(); i++) {
            ClientToServerMessage<?> message = messageBatch.get(i);
            boolean success = payload.addMessage(message, entity);
            if (success) {
              if (message instanceof ChangesHappened) {
                containsChangesHappened = true;
              }
            } else {
              messageBatch.remove(i);
              i--;
            }
          }

          if (payload.getMessageCount() == 0) {
            messageBatch.clear();
            continue;
          }

          setupNotification();

          payload.addJSONObject(getClientVersion());

          JSONArray errors = null;
          try {
            JSONObject response =
                actFmInvoker.postSync(
                    payload.closeAndReturnString(), entity, containsChangesHappened, token);
            // process responses
            String time = response.optString("time");
            JSONArray serverMessagesJson = response.optJSONArray("messages");
            if (serverMessagesJson != null) {
              setWidgetSuppression(true);
              for (int i = 0; i < serverMessagesJson.length(); i++) {
                JSONObject serverMessageJson = serverMessagesJson.optJSONObject(i);
                if (serverMessageJson != null) {
                  ServerToClientMessage serverMessage =
                      ServerToClientMessage.instantiateMessage(serverMessageJson);
                  if (serverMessage != null) {
                    serverMessage.processMessage(time);
                  } else {
                    syncLog(
                        "Index "
                            + i
                            + " unable to instantiate message "
                            + serverMessageJson.toString());
                  }
                }
              }
              errors = response.optJSONArray("errors");
              boolean errorsExist = (errors != null && errors.length() > 0);
              replayOutstandingChanges(errorsExist);
              setWidgetSuppression(false);
            }

            batchSize = Math.max(12, Math.min(batchSize, messageBatch.size()) * 2);

            if (recordSyncSuccess) {
              actFmPreferenceService.setLastError(null, null);
              actFmPreferenceService.recordSuccessfulSync();
            }
          } catch (IOException e) {
            Log.e(ERROR_TAG, "IOException", e);
            batchSize = Math.max(batchSize / 2, 1);
          }

          Set<SyncMessageCallback> callbacksExecutedThisLoop = new HashSet<SyncMessageCallback>();
          Map<Integer, List<JSONArray>> errorMap = buildErrorMap(errors);
          for (int i = 0; i < messageBatch.size(); i++) {
            ClientToServerMessage<?> message = messageBatch.get(i);
            try {
              SyncMessageCallback r = pendingCallbacks.remove(message);
              if (r != null && !callbacksExecutedThisLoop.contains(r)) {
                List<JSONArray> errorList = errorMap.get(i);
                if (errorList == null || errorList.isEmpty()) {
                  r.runOnSuccess();
                } else {
                  r.runOnErrors(errorList);
                }

                callbacksExecutedThisLoop.add(r);
              }
            } catch (Exception e) {
              Log.e(ERROR_TAG, "Unexpected exception executing sync callback", e);
            }
          }

          messageBatch.clear();
        }
      }
    } catch (Exception e) {
      // In the worst case, restart thread if something goes wrong
      Log.e(ERROR_TAG, "Unexpected sync thread exception", e);
      thread = null;
      startSyncThread();
    }
  }