/** * Creates a Task that is resolved when all the TaskQueues are "complete". * <p> * "Complete" is when all the TaskQueues complete the queue of Tasks that were in it before * whenAll was invoked. This will not keep track of tasks that are added on after whenAll * was invoked. */ private Task<Void> whenAll(Collection<TaskQueue> taskQueues) { List<Task<Void>> tasks = new ArrayList<>(); for (TaskQueue taskQueue : taskQueues) { Task<Void> task = taskQueue.enqueue(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(Task<Void> toAwait) { return toAwait; } }); tasks.add(task); } return Task.whenAll(tasks); }
/** * The results of encoding an object with this encoder will not be valid until the task returned * by this method is finished. */ public Task<Void> whenFinished() { return Task.whenAll(tasks).continueWithTask(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(Task<Void> ignore) { synchronized (tasksLock) { // It might be better to return an aggregate error here. for (Task<Void> task : tasks) { if (task.isFaulted() || task.isCancelled()) { return task; } } tasks.clear(); return Task.forResult(null); } } }); }
/** * Ensures that all auth sources have auth data (e.g. access tokens, etc.) that matches this * user. */ /* package */ Task<Void> synchronizeAllAuthDataAsync() { Map<String, Map<String, String>> authData; synchronized (mutex) { if (!isCurrentUser()) { return Task.forResult(null); } authData = getAuthData(); } List<Task<Void>> tasks = new ArrayList<>(authData.size()); for (String authType : authData.keySet()) { tasks.add(synchronizeAuthDataAsync(authType)); } return Task.whenAll(tasks); }
@Override public Task<Void> deleteAsync() { final Task<Void> ldsTask = ParseObject.unpinAllInBackground(pinName); return Task.whenAll(Arrays.asList( legacy.deleteAsync(), ldsTask )).continueWithTask(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(Task<Void> task) { // We only really care about the result of unpinning. return ldsTask; } }); } }
@Override public Task<Void> then(Task<Void> task) { int objectCount = uniqueObjects.size(); List<ParseObject.State> states = new ArrayList<>(objectCount); for (int i = 0; i < objectCount; i++) { ParseObject object = uniqueObjects.get(i); object.validateDelete(); states.add(object.getState()); } List<Task<Void>> batchTasks = getObjectController().deleteAllAsync(states, sessionToken); List<Task<Void>> tasks = new ArrayList<>(objectCount); for (int i = 0; i < objectCount; i++) { Task<Void> batchTask = batchTasks.get(i); final T object = uniqueObjects.get(i); tasks.add(batchTask.onSuccessTask(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(final Task<Void> batchTask) { return object.handleDeleteResultAsync().continueWithTask(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(Task<Void> task) { return batchTask; } }); } })); } return Task.whenAll(tasks); } });
return Task.whenAll(Arrays.asList(userTask, toAwait)).continueWithTask(new Continuation<Void, Task<Void>>() { @Override public Task<Void> then(Task<Void> task) {
tail = Task.whenAll(Arrays.asList(oldTail, task)); return task; } finally {
return Task.whenAll(tasks);
@Override public Task<T> then(Task<T> task) { final T object = task.getResult(); if (object == null) { return task; } return Task.whenAll(Arrays.asList( from.deleteAsync(), to.setAsync(object) )).continueWith(new Continuation<Void, T>() { @Override public T then(Task<Void> task) { return object; } }); } });
/* package for tests */ Task<Void> cleanUpAuthDataAsync() { ParseAuthenticationManager controller = getAuthenticationManager(); Map<String, Map<String, String>> authData; synchronized (mutex) { authData = getState().authData(); if (authData.size() == 0) { return Task.forResult(null); // Nothing to see or do here... } } List<Task<Void>> tasks = new ArrayList<>(); Iterator<Map.Entry<String, Map<String, String>>> i = authData.entrySet().iterator(); while (i.hasNext()) { Map.Entry<String, Map<String, String>> entry = i.next(); if (entry.getValue() == null) { i.remove(); tasks.add(controller.restoreAuthenticationAsync(entry.getKey(), null).makeVoid()); } } State newState = getState().newBuilder() .authData(authData) .build(); setState(newState); return Task.whenAll(tasks); }
@Override public Task<List<EventuallyPin>> then(Task<List<EventuallyPin>> task) { final List<EventuallyPin> pins = task.getResult(); List<Task<Void>> tasks = new ArrayList<>(); for (EventuallyPin pin : pins) { ParseObject object = pin.getObject(); if (object != null) { tasks.add(object.fetchFromLocalDatastoreAsync().makeVoid()); } } return Task.whenAll(tasks).continueWithTask(new Continuation<Void, Task<List<EventuallyPin>>>() { @Override public Task<List<EventuallyPin>> then(Task<Void> task) { return Task.forResult(pins); } }); } });
return Task.whenAll(tasks).continueWithTask(new Continuation<Void, Task<String>>() { @Override public Task<String> then(Task<Void> task) {
/* package */ Task<Void> logOutAsync(boolean revoke) { ParseAuthenticationManager controller = getAuthenticationManager(); List<Task<Void>> tasks = new ArrayList<>(); final String oldSessionToken; synchronized (mutex) { oldSessionToken = getState().sessionToken(); for (Map.Entry<String, Map<String, String>> entry : getAuthData().entrySet()) { tasks.add(controller.deauthenticateAsync(entry.getKey())); } State newState = getState().newBuilder() .sessionToken(null) .isNew(false) .build(); isCurrentUser = false; setState(newState); } if (revoke) { tasks.add(ParseSession.revokeAsync(oldSessionToken)); } return Task.whenAll(tasks); }
@Test public void testMultipleAsynchronousWrites() throws ParseException { int max = 100; ParseKeyValueCache.maxKeyValueCacheFiles = max; // Max out KeyValueCache for (int i = 0; i < max; i++) { ParseKeyValueCache.saveToKeyValueCache("key " + i, "test"); } List<Task<Void>> tasks = new ArrayList<>(); for (int i = 0; i < 1000; i++) { tasks.add(Task.call(new Callable<Void>() { @Override public Void call() { ParseKeyValueCache.saveToKeyValueCache("foo", "test"); return null; } }, Task.BACKGROUND_EXECUTOR)); } ParseTaskUtils.wait(Task.whenAll(tasks)); }
ParseTaskUtils.wait(Task.whenAll(tasks)); } catch (ParseException e) { assertTrue(e.getCause() instanceof AggregateException);
List<Task<Void>> deleteTaskList = controller.deleteAllAsync(states, "sessionToken"); Task.whenAll(deleteTaskList).waitForCompletion();
ParseTaskUtils.wait(Task.whenAll(tasks));
ParseTaskUtils.wait(Task.whenAll(tasks));
ParseTaskUtils.wait(Task.whenAll(tasks));
@Test public void testMultipleQueriesWithInflightChanges() throws ParseException { Parse.enableLocalDatastore(null); TestQueryController controller = new TestQueryController(); TaskCompletionSource<Void> tcs = new TaskCompletionSource<>(); controller.await(tcs.getTask()); ParseQuery<ParseObject> query = ParseQuery.getQuery("TestObject"); query.setUser(new ParseUser()); ParseCorePlugins.getInstance().registerQueryController(controller); List<Task<Void>> tasks = Arrays.asList( query.fromNetwork().findInBackground().makeVoid(), query.fromLocalDatastore().findInBackground().makeVoid(), query.setLimit(10).findInBackground().makeVoid(), query.whereEqualTo("key", "value").countInBackground().makeVoid()); assertTrue(query.isRunning()); tcs.trySetResult(null); ParseTaskUtils.wait(Task.whenAll(tasks)); assertFalse(query.isRunning()); }