def _handle_network_transfer_operation(self, file_operation): '''By locking we mantain the following invariant: if the EventQueue tries to abort this operation due to a conflicting operation, then EventQueue waits until this operation either aborts or completes. This preserves the ordering of execution for the conflicting operations - that is, the EventQueue doesn't emit the conflicting operation while this one is still working.''' with file_operation.lock: if not file_operation.is_aborted(): self.logger.debug(u"Starting child process to handle file operation: %s", file_operation) try: self._spawn_child(file_operation) self.input_queue.put(('FileOperation',file_operation)) except Exception as e: self.logger.error(u"Could not spawn a child process: %r" % e) raise OperationRejection(file_operation) else: self.logger.debug(u"Got an already aborted operation, giving up: %s", file_operation) return if file_operation.verb == 'UPLOAD': status = PStatuses.UPLOADING else: status = PStatuses.DOWNLOADING self.__send_percentage(file_operation, status, 0) termination = False max_retry = 3 while not termination: message, content = self.communicationQueue.get() # self.logger.debug('Worker send back %s with content %s' % (message, content)) if message == 'result': CryptoUtils.clean_env(file_operation, self.logger) if content == 'completed': self.__send_percentage(file_operation, status, 100) self.__on_operation_complete(file_operation) termination = True elif content == 'interrupted': self.logger.debug(u"Child has been terminated by Software Operation: %s", file_operation) file_operation.abort() termination = True elif content == 'failed': self.logger.error(u"Child has been terminated, Assuming failure for operation: %s", file_operation) max_retry -= 1 if max_retry == 0: raise OperationRejection(file_operation) self.input_queue.put(('FileOperation',file_operation)) elif message == 'percentage': self.__send_percentage(file_operation, status, content) elif message == 'log': level, msg = content self.child_logger[level](msg) elif message == 'ShuttingDown': self.logger.debug("Get a shutting down message from process") termination = True elif message == 'DIED': file_operation.reject() self.child=None termination = True self.logger.debug('Quit from _handle_network_transfer_operation method')
def _handle_upload_file_operation(self, operation): try: success = self._handle_network_transfer_operation(operation) if success: CryptoUtils.clean_env(operation, self.logger) self.logger.debug(u"Operation has been completed " "successfully: %s" % operation) self.logger.info(u'Synchronized pathname: %s "%s", which ' 'will be persisted after a commit' % (operation.verb, operation.pathname)) operation.notify_pathname_status_change(PStatuses.UPLOADED, {'percentage': 100}) operation.complete() except Exception as e: self.logger.error(u"Error while uploading: %r." " Rejecting the operation: %s" % (e, operation)) operation.reject()