public void onDataArrive(DataType data) {
      final Object session;
      InitLaterDataController newController;
      newController = new InitLaterDataController(getDataState());

      // It is just a minor performance optimization: don't bother
      // requesting another link
      boolean canceled = cancelToken.isCanceled();
      mainLock.lock();
      try {
        if (!initializedController) {
          newController = currentController;
          currentController = null;
        }

        session = newSession();
        currentSession = session;
        sessionReport = null;

        if (canceled) {
          newController = null;
          sessionReport = AsyncReport.CANCELED;
        } else {
          currentController = newController;
        }

        initializedController = true;
      } finally {
        mainLock.unlock();
      }

      try {
        if (newController != null) {
          AsyncDataController queryController;
          queryController =
              query.createDataLink(data).getData(cancelToken, new QueryListener(session));
          newController.initController(queryController);
        }
      } catch (Throwable ex) {
        failSession(session, ex);
        throw ex;
      }
    }
Example #2
0
  @Override
  public void execute(CancellationToken cancelToken, CancelableTask task, CleanupTask cleanupTask) {
    final TaskDef taskDef = new TaskDef(cancelToken, task, cleanupTask);

    final RefCollection.ElementRef<TaskDef> taskDefRef;
    queueLock.lock();
    try {
      taskDefRef = taskQueue.addLastGetReference(taskDef);
    } finally {
      queueLock.unlock();
    }

    final ListenerRef cancelRef;
    if (taskDef.hasCleanupTask()) {
      cancelRef =
          cancelToken.addCancellationListener(
              new Runnable() {
                @Override
                public void run() {
                  taskDef.removeTask();
                }
              });
    } else {
      cancelRef =
          cancelToken.addCancellationListener(
              new Runnable() {
                @Override
                public void run() {
                  queueLock.lock();
                  try {
                    taskDefRef.remove();
                  } finally {
                    queueLock.unlock();
                  }
                }
              });
    }

    final AtomicBoolean executorCancellation = new AtomicBoolean(true);
    // Notice that we pass an Cancellation.UNCANCELABLE_TOKEN and so we
    // assume if the submitted task gets canceled
    executor.execute(
        Cancellation.UNCANCELABLE_TOKEN,
        new CancelableTask() {
          @Override
          public void execute(CancellationToken cancelToken) {
            try {
              dispatchTasks(cancelToken);
            } finally {
              executorCancellation.set(false);
            }
          }
        },
        new CleanupTask() {
          @Override
          public void cleanup(boolean canceled, Throwable error) {
            try {
              cancelRef.unregister();
            } finally {
              // If the executor did not execute our task, this might be
              // our last chance to execute the cleanup tasks.
              // Note that since we pass CANCELED_TOKEN, only cleanup
              // tasks will be executed.
              if (executorCancellation.get()) {
                dispatchTasks(Cancellation.CANCELED_TOKEN);
              }
            }
          }
        });
  }