def _Dynamic_AddActions(self, request, response, request_id=None): """Associates the creation of one or more tasks with a transaction. Args: request: A taskqueue_service_pb.TaskQueueBulkAddRequest containing the tasks that should be created when the transaction is comitted. response: A taskqueue_service_pb.TaskQueueBulkAddResponse. request_id: A string specifying the request ID. """ # These are not used, but they are required for the method signature. del response, request_id transaction = request.add_request_list()[0].transaction() txn_actions = self.__tx_actions[transaction.handle()] if ((len(txn_actions) + request.add_request_size()) > _MAX_ACTIONS_PER_TXN): raise apiproxy_errors.ApplicationError( datastore_pb.Error.BAD_REQUEST, 'Too many messages, maximum allowed %s' % _MAX_ACTIONS_PER_TXN) new_actions = [] for add_request in request.add_request_list(): clone = taskqueue_service_pb.TaskQueueAddRequest() clone.CopyFrom(add_request) clone.clear_transaction() new_actions.append(clone) txn_actions.extend(new_actions)
def add(self, app_id, http_data): """ Adds a single task to the task queue. Args: app_id: The application ID. http_data: The payload containing the protocol buffer request. Returns: A tuple of a encoded response, error code, and error detail. """ # Just call bulk add with one task. request = taskqueue_service_pb.TaskQueueAddRequest(http_data) request.set_app_id(app_id) response = taskqueue_service_pb.TaskQueueAddResponse() bulk_request = taskqueue_service_pb.TaskQueueBulkAddRequest() bulk_response = taskqueue_service_pb.TaskQueueBulkAddResponse() bulk_request.add_add_request().CopyFrom(request) self.__bulk_add(bulk_request, bulk_response) if bulk_response.taskresult_size() == 1: result = bulk_response.taskresult(0).result() else: err_code = taskqueue_service_pb.TaskQueueServiceError.INTERNAL_ERROR return (response.Encode(), err_code, "Task did not receive a task response.") if result != taskqueue_service_pb.TaskQueueServiceError.OK: return (response.Encode(), result, "Task did not get an OK status.") elif bulk_response.taskresult(0).has_chosen_task_name(): response.set_chosen_task_name( bulk_response.taskresult(0).chosen_task_name()) return (response.Encode(), 0, "")
def _Dynamic_AddAction(self, request, void): self.__ValidateTransaction(request.transaction()) if len(self.__tx_actions) >= _MAX_ACTIONS_PER_TXN: raise apiproxy_errors.ApplicationError( datastore_pb.Error.BAD_REQUEST, 'Too many messages, maximum allowed %s' % _MAX_ACTIONS_PER_TXN) clone = taskqueue_service_pb.TaskQueueAddRequest() clone.CopyFrom(request) clone.clear_transaction() self.__tx_actions.append(clone)
def get_transaction_metadata(self, app, txid): """ Fetch transaction state. Args: app: A string specifying an application ID. txid: An integer specifying a transaction ID. Returns: A dictionary containing transaction state. """ select = """ SELECT namespace, operation, path, start_time, is_xg, in_progress, entity, task FROM transactions WHERE txid_hash = %(txid_hash)s """ parameters = {'txid_hash': tx_partition(app, txid)} try: results = self.session.execute(select, parameters) except dbconstants.TRANSIENT_CASSANDRA_ERRORS: message = 'Exception while inserting entities in a transaction' logging.exception(message) raise AppScaleDBConnectionError(message) metadata = {'puts': {}, 'deletes': [], 'tasks': [], 'reads': set()} for result in results: if result.operation == TxnActions.START: metadata['start'] = result.start_time metadata['is_xg'] = result.is_xg metadata['in_progress'] = set() if metadata['in_progress'] is not None: metadata['in_progress'] = set( struct.unpack('q' * int(len(result.in_progress) / 8), result.in_progress)) if result.operation == TxnActions.MUTATE: key = create_key(app, result.namespace, result.path) if result.entity is None: metadata['deletes'].append(key) else: metadata['puts'][key.Encode()] = result.entity if result.operation == TxnActions.GET: group_key = create_key(app, result.namespace, result.path) metadata['reads'].add(group_key.Encode()) if result.operation == TxnActions.ENQUEUE_TASK: service_id, version_id, task_pb = result.task.split('_', 2) task_metadata = { 'service_id': service_id, 'version_id': version_id, 'task': taskqueue_service_pb.TaskQueueAddRequest(task_pb) } metadata['tasks'].append(task_metadata) return metadata
def _Dynamic_AddActions(self, request, _): """Associates the creation of one or more tasks with a transaction. Args: request: A taskqueue_service_pb.TaskQueueBulkAddRequest containing the tasks that should be created when the transaction is comitted. """ if ((len(self.__tx_actions) + request.add_request_size()) > _MAX_ACTIONS_PER_TXN): raise apiproxy_errors.ApplicationError( datastore_pb.Error.BAD_REQUEST, 'Too many messages, maximum allowed %s' % _MAX_ACTIONS_PER_TXN) new_actions = [] for add_request in request.add_request_list(): clone = taskqueue_service_pb.TaskQueueAddRequest() clone.CopyFrom(add_request) clone.clear_transaction() new_actions.append(clone) self.__tx_actions.extend(new_actions)
def add(self, source_info, http_data): """ Adds a single task to the task queue. Args: source_info: A dictionary containing the application, module, and version ID that is sending this request. http_data: The payload containing the protocol buffer request. Returns: A tuple of a encoded response, error code, and error detail. """ # Just call bulk add with one task. request = taskqueue_service_pb.TaskQueueAddRequest(http_data) request.set_app_id(source_info['app_id']) response = taskqueue_service_pb.TaskQueueAddResponse() bulk_request = taskqueue_service_pb.TaskQueueBulkAddRequest() bulk_response = taskqueue_service_pb.TaskQueueBulkAddResponse() bulk_request.add_add_request().CopyFrom(request) try: self.__bulk_add(source_info, bulk_request, bulk_response) except TransientError as error: return '', TaskQueueServiceError.TRANSIENT_ERROR, str(error) except QueueNotFound as error: return '', TaskQueueServiceError.UNKNOWN_QUEUE, str(error) if bulk_response.taskresult_size() == 1: result = bulk_response.taskresult(0).result() else: return (response.Encode(), TaskQueueServiceError.INTERNAL_ERROR, "Task did not receive a task response.") if result != TaskQueueServiceError.OK: return (response.Encode(), result, "Task did not get an OK status.") elif bulk_response.taskresult(0).has_chosen_task_name(): response.set_chosen_task_name( bulk_response.taskresult(0).chosen_task_name()) return (response.Encode(), 0, "")