Search in sources :

Example 1 with TaskQueueAddRequest

use of com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest in project appengine-java-standard by GoogleCloudPlatform.

the class QueueImpl method addAsync.

/**
 * See {@link Queue#addAsync(com.google.appengine.api.datastore.Transaction, Iterable)}.
 */
@Override
public Future<List<TaskHandle>> addAsync(Transaction txn, Iterable<TaskOptions> taskOptions) {
    final List<TaskOptions> taskOptionsList = new ArrayList<>();
    Set<String> taskNames = new HashSet<>();
    final TaskQueueBulkAddRequest.Builder bulkAddRequest = TaskQueueBulkAddRequest.newBuilder();
    boolean hasPushTask = false;
    boolean hasPullTask = false;
    for (TaskOptions option : taskOptions) {
        TaskQueueAddRequest.Builder addRequest = bulkAddRequest.addAddRequestBuilder();
        validateAndFillAddRequest(txn, option, addRequest);
        if (addRequest.getMode() == TaskQueueMode.Mode.PULL) {
            hasPullTask = true;
        } else {
            hasPushTask = true;
        }
        taskOptionsList.add(option);
        if (option.getTaskName() != null && !option.getTaskName().isEmpty()) {
            if (!taskNames.add(option.getTaskName())) {
                throw new IllegalArgumentException(String.format("Identical task names in request : \"%s\" duplicated", option.getTaskName()));
            }
        }
    }
    if (bulkAddRequest.getAddRequestCount() > QueueConstants.maxTasksPerAdd()) {
        throw new IllegalArgumentException(String.format("No more than %d tasks can be added in a single add call", QueueConstants.maxTasksPerAdd()));
    }
    if (hasPullTask && hasPushTask) {
        throw new IllegalArgumentException("May not add both push tasks and pull tasks in the same call.");
    }
    TaskQueueBulkAddRequest builtRequest = bulkAddRequest.build();
    if (txn != null && builtRequest.getSerializedSize() > QueueConstants.maxTransactionalRequestSizeBytes()) {
        throw new IllegalArgumentException(String.format("Transactional add may not be larger than %d bytes: %d bytes requested.", QueueConstants.maxTransactionalRequestSizeBytes(), builtRequest.getSerializedSize()));
    }
    Future<TaskQueueBulkAddResponse> responseFuture = makeAsyncCall("BulkAdd", builtRequest, TaskQueueBulkAddResponse.getDefaultInstance());
    return new FutureAdapter<TaskQueueBulkAddResponse, List<TaskHandle>>(responseFuture) {

        @Override
        protected List<TaskHandle> wrap(TaskQueueBulkAddResponse bulkAddResponse) {
            if (bulkAddResponse.getTaskResultCount() != bulkAddRequest.getAddRequestCount()) {
                throw new InternalFailureException(String.format("expected %d results from BulkAdd(), got %d", bulkAddRequest.getAddRequestCount(), bulkAddResponse.getTaskResultCount()));
            }
            List<TaskHandle> tasks = new ArrayList<>();
            RuntimeException taskqueueException = null;
            for (int i = 0; i < bulkAddResponse.getTaskResultCount(); ++i) {
                TaskQueueBulkAddResponse.TaskResult.Builder taskResult = bulkAddResponse.toBuilder().getTaskResultBuilder(i);
                TaskQueueAddRequest addRequest = bulkAddRequest.getAddRequest(i);
                TaskOptions options = taskOptionsList.get(i);
                if (taskResult.getResult() == TaskQueueServiceError.ErrorCode.OK) {
                    String taskName = options.getTaskName();
                    if (taskResult.hasChosenTaskName()) {
                        taskName = taskResult.getChosenTaskName().toStringUtf8();
                    }
                    TaskOptions taskResultOptions = new TaskOptions(options);
                    taskResultOptions.taskName(taskName).payload(addRequest.getBody().toByteArray());
                    TaskHandle handle = new TaskHandle(taskResultOptions, queueName);
                    tasks.add(handle.etaUsec(addRequest.getEtaUsec()));
                } else if (taskResult.getResult() != TaskQueueServiceError.ErrorCode.SKIPPED) {
                    // not successfully added.
                    if (taskqueueException == null || taskqueueException instanceof TaskAlreadyExistsException) {
                        int result = taskResult.getResult().getNumber();
                        String detail = (result == TaskQueueServiceError.ErrorCode.UNKNOWN_QUEUE_VALUE) ? queueName : options.getTaskName();
                        RuntimeException e = QueueApiHelper.translateError(result, detail);
                        if (e instanceof TaskAlreadyExistsException) {
                            if (taskqueueException == null) {
                                taskqueueException = e;
                            }
                            TaskAlreadyExistsException taee = (TaskAlreadyExistsException) taskqueueException;
                            taee.appendTaskName(options.getTaskName());
                        } else {
                            taskqueueException = e;
                        }
                    }
                }
            }
            if (taskqueueException != null) {
                throw taskqueueException;
            }
            return tasks;
        }
    };
}
Also used : TaskQueueAddRequest(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest) TaskQueueBulkAddResponse(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueBulkAddResponse) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) TaskQueueBulkAddRequest(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueBulkAddRequest) HashSet(java.util.HashSet)

Example 2 with TaskQueueAddRequest

use of com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method addActionsImpl.

// status
@SuppressWarnings("unused")
private void addActionsImpl(Status status, TaskQueueBulkAddRequest request) {
    if (request.getAddRequestCount() == 0) {
        return;
    }
    // The transactional tasks need to be associated with the txn.
    // When the txn is committed the tasks will be sent back over to
    // the taskqueue stub. We need to wipe out their transactions before sending
    // so that the tasks actually get added and we don't continue spinning
    // around in and infinite loop.
    List<TaskQueueAddRequest> addRequests = new ArrayList<>(request.getAddRequestCount());
    for (TaskQueueAddRequest addRequest : request.getAddRequestList()) {
        addRequests.add(addRequest.toBuilder().clearTransaction().clearDatastoreTransaction().build());
    }
    Transaction transaction;
    if (request.getAddRequestList().get(0).hasDatastoreTransaction()) {
        ByteString datastoreTransaction = request.getAddRequestList().get(0).getDatastoreTransaction();
        try {
            transaction = Transaction.parser().parseFrom(datastoreTransaction);
        } catch (InvalidProtocolBufferException e) {
            throw newError(ErrorCode.BAD_REQUEST, "Invalid transaction");
        }
    } else {
        transaction = toProto1(request.getAddRequest(0).getTransaction());
    }
    Profile profile = profiles.get(transaction.getApp());
    LiveTxn liveTxn = profile.getTxn(transaction.getHandle());
    liveTxn.addActions(addRequests);
}
Also used : TaskQueueAddRequest(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest) Transaction(com.google.apphosting.datastore.DatastoreV3Pb.Transaction) ByteString(com.google.protobuf.ByteString) ArrayList(java.util.ArrayList) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException)

Example 3 with TaskQueueAddRequest

use of com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest in project appengine-java-standard by GoogleCloudPlatform.

the class LocalDatastoreService method commit.

// status
@SuppressWarnings("unused")
public CommitResponse commit(Status status, final Transaction req) {
    Profile profile = profiles.get(req.getApp());
    checkNotNull(profile);
    CommitResponse response = new CommitResponse();
    globalLock.readLock().lock();
    // Synchronized so we can't commit and rollback at the same time.
    synchronized (profile) {
        LiveTxn liveTxn;
        try {
            liveTxn = profile.removeTxn(req.getHandle());
            try {
                if (liveTxn.isDirty()) {
                    response = commitImpl(liveTxn, profile);
                } else {
                    // cost of a read-only txn is 0
                    response.setCost(new Cost().setEntityWrites(0).setIndexWrites(0));
                }
            } catch (ApplicationException e) {
                // commit failed, re-add transaction so that it can be rolled back or reset.
                profile.addTxn(req.getHandle(), new LiveTxn(clock, liveTxn.allowMultipleEg, liveTxn.originalTransactionMode, true));
                throw e;
            }
        } finally {
            globalLock.readLock().unlock();
        }
        // taskqueue tasks become durable.
        for (TaskQueueAddRequest action : liveTxn.getActions()) {
            try {
                addActionImpl(action);
            } catch (ApplicationException e) {
                logger.log(Level.WARNING, "Transactional task: " + action + " has been dropped.", e);
            }
        }
    }
    return response;
}
Also used : ApplicationException(com.google.apphosting.api.ApiProxy.ApplicationException) TaskQueueAddRequest(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest) CommitResponse(com.google.apphosting.datastore.DatastoreV3Pb.CommitResponse) Cost(com.google.apphosting.datastore.DatastoreV3Pb.Cost)

Example 4 with TaskQueueAddRequest

use of com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest in project appengine-java-standard by GoogleCloudPlatform.

the class LocalTaskQueue method queryAndOwnTasks.

@LatencyPercentiles(latency50th = 8)
public TaskQueueQueryAndOwnTasksResponse queryAndOwnTasks(Status status, TaskQueueQueryAndOwnTasksRequest request) {
    String queueName = request.getQueueName().toStringUtf8();
    validateQueueName(queueName);
    // getQueueByName will throw UNKNOWN_QUEUE if the queue does not exist.
    DevQueue queue = getQueueByName(queueName);
    if (queue.getMode() != Mode.PULL) {
        throw new ApiProxy.ApplicationException(ErrorCode.INVALID_QUEUE_MODE_VALUE);
    }
    DevPullQueue pullQueue = (DevPullQueue) queue;
    List<TaskQueueAddRequest.Builder> results = pullQueue.queryAndOwnTasks(request.getLeaseSeconds(), request.getMaxTasks(), request.hasGroupByTag(), request.getTag().toByteArray());
    TaskQueueQueryAndOwnTasksResponse.Builder response = TaskQueueQueryAndOwnTasksResponse.newBuilder();
    for (TaskQueueAddRequest.Builder task : results) {
        TaskQueueQueryAndOwnTasksResponse.Task.Builder responseTask = response.addTaskBuilder().setTaskName(task.getTaskName()).setBody(task.getBody()).setEtaUsec(task.getEtaUsec());
        if (task.hasTag()) {
            responseTask.setTag(task.getTag());
        }
    // TODO: To keep track of retry count, we can replace TaskQueueAddRequest with
    // TaskQueueQueryTasksResponse to represent a task.
    }
    return response.build();
}
Also used : TaskQueueAddRequest(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest) ByteString(com.google.protobuf.ByteString) TaskQueueQueryAndOwnTasksResponse(com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueQueryAndOwnTasksResponse) LatencyPercentiles(com.google.appengine.tools.development.LatencyPercentiles)

Aggregations

TaskQueueAddRequest (com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueAddRequest)4 ByteString (com.google.protobuf.ByteString)3 ArrayList (java.util.ArrayList)2 TaskQueueBulkAddRequest (com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueBulkAddRequest)1 TaskQueueBulkAddResponse (com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueBulkAddResponse)1 TaskQueueQueryAndOwnTasksResponse (com.google.appengine.api.taskqueue.TaskQueuePb.TaskQueueQueryAndOwnTasksResponse)1 LatencyPercentiles (com.google.appengine.tools.development.LatencyPercentiles)1 ApplicationException (com.google.apphosting.api.ApiProxy.ApplicationException)1 CommitResponse (com.google.apphosting.datastore.DatastoreV3Pb.CommitResponse)1 Cost (com.google.apphosting.datastore.DatastoreV3Pb.Cost)1 Transaction (com.google.apphosting.datastore.DatastoreV3Pb.Transaction)1 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 HashSet (java.util.HashSet)1