def run(self): self._prepare() self._logger.info('Running task {}.. (delay: {})'.format(self._task.id, self._executionDelay)) try: for i, retry in enumerate(transaction.attempts(self._config.task_max_tries)): with retry: self._logger.info('Task attempt #{}'.format(i)) if i > 0: self._prepare_retry() try: self._process_task() break except ConflictError: transaction.abort() except ClientDisconnected: self._logger.warning("Retrying for the {}th time in {} secs..".format(i + 1, seconds)) transaction.abort() time.sleep(i * 10) except TaskDelayed, e: self._logger.info("{} delayed by {} seconds".format(self._task, e.delaySeconds)) self._delayed = True self._executionDelay = 0 time.sleep(e.delaySeconds) flush_after_commit_queue(True) GenericMailer.flushQueue(True)
def download_release_from_pypi(db_or_root, package_name, release_name, filename): db = isinstance(db_or_root, DB) if db: conn = db_or_root.open() root = repository_root_factory(conn) else: root = db_or_root metadata = get_release_metadata(package_name, release_name) for attempt in transaction.attempts(): with attempt: if root[package_name] is None: root[package_name] = Package(package_name) release_ready_exists = release_name in root[package_name] if not release_ready_exists: root[package_name][release_name] = Release( release_name, release_name, metadata['info'], deserialize_metadata=True ) if filename not in root[package_name][release_name]: release = [release for release in metadata['releases'][release_name] if release['filename'] == filename][0] url = release['url'] md5_digest = release['md5_digest'] content = download_file(filename, url, md5_digest) if not content: transaction.abort() return None root[package_name][release_name][filename] = ReleaseFile(filename, content, md5_digest) if db: conn.close()
def invokeMethod(self, method, params): cfg = Config.getInstance() forced_conflicts = cfg.getForceConflicts() max_retries = cfg.getMaxRetries() result = None self._invokeMethodBefore() try: for i, retry in enumerate(transaction.attempts(max_retries)): with retry: if i > 0: # notify components that the request is being retried signals.before_retry.send() self._invokeMethodRetryBefore() try: try: result = processRequest(method, copy.deepcopy(params)) signals.after_process.send() except NoReportError as e: raise ServiceNoReportError(e.getMessage()) except (NoReportIndicoError, FormValuesError) as e: raise ServiceNoReportError(e.getMessage(), title=_("Error")) # Raise a conflict error if enabled. # This allows detecting conflict-related issues easily. if i < forced_conflicts: raise ConflictError transaction.commit() break except ConflictError: transaction.abort() except ClientDisconnected: transaction.abort() time.sleep(i) except DatabaseError: handle_sqlalchemy_database_error() break self._invokeMethodSuccess() except Exception as e: transaction.abort() if isinstance(e, CausedError): raise elif isinstance(e, ConstraintViolated): raise ProcessError, ('ERR-P0', e.message), sys.exc_info()[2] else: raise ProcessError('ERR-P0', 'Error processing method.') finally: # notify components that the request has ended DBMgr.getInstance().endRequest() return result
def invokeMethod(self, method, params): cfg = Config.getInstance() forced_conflicts = cfg.getForceConflicts() max_retries = cfg.getMaxRetries() result = None self._invokeMethodBefore() try: for i, retry in enumerate(transaction.attempts(max_retries)): with retry: if i > 0: # notify components that the request is being retried self._notify('requestRetry', i) self._invokeMethodRetryBefore() try: # Raise a conflict error if enabled. # This allows detecting conflict-related issues easily. if i < forced_conflicts: raise ConflictError try: result = processRequest(method, copy.deepcopy(params)) except NoReportError as e: raise ServiceNoReportError(e.getMsg()) except (NoReportIndicoError, FormValuesError) as e: raise ServiceNoReportError(e.getMessage(), title=_("Error")) transaction.commit() break except ConflictError: transaction.abort() except ClientDisconnected: transaction.abort() time.sleep(i) self._invokeMethodSuccess() except Exception as e: transaction.abort() if isinstance(e, CausedError): raise else: raise ProcessError('ERR-P0', 'Error processing method.') finally: # notify components that the request has ended self._notify('requestFinished') DBMgr.getInstance().endRequest() return result
def __call__(self, aw): """Perform the actual exporting""" if self.HTTP_POST != (request.method == 'POST'): raise HTTPAPIError( 'This action requires %s' % ('POST' if self.HTTP_POST else 'GET'), 405) if not self.GUEST_ALLOWED and not aw.getUser(): raise HTTPAPIError('Guest access to this resource is forbidden.', 403) method_name = self._getMethodName() func = getattr(self, method_name, None) extra_func = getattr(self, method_name + '_extra', None) if not func: raise NotImplementedError(method_name) if not self.COMMIT: is_response, resultList, complete, extra = self._perform( aw, func, extra_func) else: dbi = DBMgr.getInstance() try: for i, retry in enumerate(transaction.attempts(10)): with retry: if i > 0: dbi.abort() flush_after_commit_queue(False) GenericMailer.flushQueue(False) dbi.sync() try: is_response, resultList, complete, extra = self._perform( aw, func, extra_func) transaction.commit() flush_after_commit_queue(True) GenericMailer.flushQueue(True) break except ConflictError: transaction.abort() except ClientDisconnected: transaction.abort() time.sleep(i * 5) else: raise HTTPAPIError( 'An unresolvable database conflict has occured', 500) except Exception: transaction.abort() raise if is_response: return resultList return resultList, extra, complete, self.SERIALIZER_TYPE_MAP
def __call__(self, aw): """Perform the actual exporting""" if self.HTTP_POST != (request.method == 'POST'): raise HTTPAPIError('This action requires %s' % ('POST' if self.HTTP_POST else 'GET'), 405) if not self.GUEST_ALLOWED and not aw.getUser(): raise HTTPAPIError('Guest access to this resource is forbidden.', 403) method_name = self._getMethodName() func = getattr(self, method_name, None) extra_func = getattr(self, method_name + '_extra', None) if not func: raise NotImplementedError(method_name) if not self.COMMIT: is_response, resultList, complete, extra = self._perform(aw, func, extra_func) else: dbi = DBMgr.getInstance() try: for i, retry in enumerate(transaction.attempts(10)): with retry: if i > 0: dbi.abort() flush_after_commit_queue(False) GenericMailer.flushQueue(False) dbi.sync() try: is_response, resultList, complete, extra = self._perform(aw, func, extra_func) transaction.commit() flush_after_commit_queue(True) GenericMailer.flushQueue(True) break except ConflictError: transaction.abort() except ClientDisconnected: transaction.abort() time.sleep(i * 5) else: raise HTTPAPIError('An unresolvable database conflict has occured', 500) except Exception: transaction.abort() raise if is_response: return resultList return resultList, extra, complete, self.SERIALIZER_TYPE_MAP
def tm_tween(request): if 'repoze.tm.active' in request.environ: # don't handle txn mgmt if repoze.tm is in the WSGI pipeline return handler(request) try: for attempt in transaction.attempts(attempts): with attempt as t: # make_body_seekable will copy wsgi.input if necessary, # otherwise it will rewind the copy to position zero if attempts != 1: request.make_body_seekable() response = handler(request) if t.isDoomed(): raise AbortResponse(response) if commit_veto is not None: veto = commit_veto(request, response) if veto: raise AbortResponse(response) return response except AbortResponse: e = sys.exc_info()[1] # py2.5-py3 compat return e.response
def process(self, params): if request.method not in self.HTTP_VERBS: # Just to be sure that we don't get some crappy http verb we don't expect raise BadRequest cfg = Config.getInstance() forced_conflicts, max_retries, profile = cfg.getForceConflicts(), cfg.getMaxRetries(), cfg.getProfile() profile_name, res, textLog = '', '', [] self._startTime = datetime.now() # clear the context ContextManager.destroy() ContextManager.set('currentRH', self) g.rh = self #redirect to https if necessary if self._checkHttpsRedirect(): return self._responseUtil.make_redirect() DBMgr.getInstance().startRequest() textLog.append("%s : Database request started" % (datetime.now() - self._startTime)) Logger.get('requestHandler').info('[pid=%s] Request %s started' % ( os.getpid(), request)) try: for i, retry in enumerate(transaction.attempts(max_retries)): with retry: if i > 0: signals.before_retry.send() try: Logger.get('requestHandler').info('\t[pid=%s] from host %s' % (os.getpid(), request.remote_addr)) profile_name, res = self._process_retry(params, i, profile, forced_conflicts) signals.after_process.send() if i < forced_conflicts: # raise conflict error if enabled to easily handle conflict error case raise ConflictError transaction.commit() DBMgr.getInstance().endRequest(commit=False) break except (ConflictError, POSKeyError): transaction.abort() import traceback # only log conflict if it wasn't forced if i >= forced_conflicts: Logger.get('requestHandler').warning('Conflict in Database! (Request %s)\n%s' % (request, traceback.format_exc())) except ClientDisconnected: transaction.abort() Logger.get('requestHandler').warning('Client Disconnected! (Request {})'.format(request)) time.sleep(i) self._process_success() except Exception as e: transaction.abort() res = self._getMethodByExceptionName(e)(e) totalTime = (datetime.now() - self._startTime) textLog.append('{} : Request ended'.format(totalTime)) # log request timing if profile and totalTime > timedelta(0, 1) and os.path.isfile(profile_name): rep = Config.getInstance().getTempDir() stats = pstats.Stats(profile_name) stats.strip_dirs() stats.sort_stats('cumulative', 'time', 'calls') stats.dump_stats(os.path.join(rep, 'IndicoRequestProfile.log')) output = StringIO.StringIO() sys.stdout = output stats.print_stats(100) sys.stdout = sys.__stdout__ s = output.getvalue() f = file(os.path.join(rep, 'IndicoRequest.log'), 'a+') f.write('--------------------------------\n') f.write('URL : {}\n'.format(request.url)) f.write('{} : start request\n'.format(self._startTime)) f.write('params:{}'.format(params)) f.write('\n'.join(textLog)) f.write('\n') f.write('retried : {}\n'.format(10-retry)) f.write(s) f.write('--------------------------------\n\n') f.close() if profile and profile_name and os.path.exists(profile_name): os.remove(profile_name) if self._responseUtil.call: return self._responseUtil.make_call() # In case of no process needed, we should return empty string to avoid erroneous output # specially with getVars breaking the JS files. if not self._doProcess or res is None: return self._responseUtil.make_empty() return self._responseUtil.make_response(res)
def process(self, params): if request.method not in self.HTTP_VERBS: # Just to be sure that we don't get some crappy http verb we don't expect raise BadRequest cfg = Config.getInstance() forced_conflicts, max_retries, profile = cfg.getForceConflicts( ), cfg.getMaxRetries(), cfg.getProfile() profile_name, res, textLog = '', '', [] self._startTime = datetime.now() # clear the context ContextManager.destroy() ContextManager.set('currentRH', self) g.rh = self #redirect to https if necessary if self._checkHttpsRedirect(): return self._responseUtil.make_redirect() DBMgr.getInstance().startRequest() textLog.append("%s : Database request started" % (datetime.now() - self._startTime)) Logger.get('requestHandler').info('[pid=%s] Request %s started' % (os.getpid(), request)) try: for i, retry in enumerate(transaction.attempts(max_retries)): with retry: if i > 0: signals.before_retry.send() try: Logger.get('requestHandler').info( '\t[pid=%s] from host %s' % (os.getpid(), request.remote_addr)) profile_name, res = self._process_retry( params, i, profile, forced_conflicts) signals.after_process.send() if i < forced_conflicts: # raise conflict error if enabled to easily handle conflict error case raise ConflictError transaction.commit() DBMgr.getInstance().endRequest(commit=False) break except (ConflictError, POSKeyError): transaction.abort() import traceback # only log conflict if it wasn't forced if i >= forced_conflicts: Logger.get('requestHandler').warning( 'Conflict in Database! (Request %s)\n%s' % (request, traceback.format_exc())) except ClientDisconnected: transaction.abort() Logger.get('requestHandler').warning( 'Client Disconnected! (Request {})'.format( request)) time.sleep(i) self._process_success() except Exception as e: transaction.abort() res = self._getMethodByExceptionName(e)(e) totalTime = (datetime.now() - self._startTime) textLog.append('{} : Request ended'.format(totalTime)) # log request timing if profile and totalTime > timedelta( 0, 1) and os.path.isfile(profile_name): rep = Config.getInstance().getTempDir() stats = pstats.Stats(profile_name) stats.strip_dirs() stats.sort_stats('cumulative', 'time', 'calls') stats.dump_stats(os.path.join(rep, 'IndicoRequestProfile.log')) output = StringIO.StringIO() sys.stdout = output stats.print_stats(100) sys.stdout = sys.__stdout__ s = output.getvalue() f = file(os.path.join(rep, 'IndicoRequest.log'), 'a+') f.write('--------------------------------\n') f.write('URL : {}\n'.format(request.url)) f.write('{} : start request\n'.format(self._startTime)) f.write('params:{}'.format(params)) f.write('\n'.join(textLog)) f.write('\n') f.write('retried : {}\n'.format(10 - retry)) f.write(s) f.write('--------------------------------\n\n') f.close() if profile and profile_name and os.path.exists(profile_name): os.remove(profile_name) if self._responseUtil.call: return self._responseUtil.make_call() # In case of no process needed, we should return empty string to avoid erroneous output # specially with getVars breaking the JS files. if not self._doProcess or res is None: return self._responseUtil.make_empty() return self._responseUtil.make_response(res)
def wrapped_controller(*args, **kw): for attempt in transaction.attempts(3): with attempt: return controller(*args, **kw)
def process(self, params): if request.method not in HTTP_VERBS: # Just to be sure that we don't get some crappy http verb we don't expect raise BadRequest cfg = Config.getInstance() forced_conflicts, max_retries, profile = cfg.getForceConflicts( ), cfg.getMaxRetries(), cfg.getProfile() profile_name, res, textLog = '', '', [] self._startTime = datetime.now() # clear the context ContextManager.destroy() ContextManager.set('currentRH', self) g.rh = self #redirect to https if necessary if self._checkHttpsRedirect(): return self._responseUtil.make_redirect() if self.EVENT_FEATURE is not None: self._check_event_feature() DBMgr.getInstance().startRequest() textLog.append("%s : Database request started" % (datetime.now() - self._startTime)) Logger.get('requestHandler').info( u'Request started: %s %s [IP=%s] [PID=%s]', request.method, request.relative_url, request.remote_addr, os.getpid()) is_error_response = False try: for i, retry in enumerate(transaction.attempts(max_retries)): with retry: if i > 0: signals.before_retry.send() try: profile_name, res = self._process_retry( params, i, profile, forced_conflicts) signals.after_process.send() if i < forced_conflicts: # raise conflict error if enabled to easily handle conflict error case raise ConflictError if self.commit: transaction.commit() else: transaction.abort() DBMgr.getInstance().endRequest(commit=False) break except (ConflictError, POSKeyError): transaction.abort() import traceback # only log conflict if it wasn't forced if i >= forced_conflicts: Logger.get('requestHandler').warning( 'Database conflict') except ClientDisconnected: transaction.abort() Logger.get('requestHandler').warning( 'Client disconnected') time.sleep(i) except DatabaseError: handle_sqlalchemy_database_error() break self._process_success() except Exception as e: transaction.abort() res = self._getMethodByExceptionName(e)(e) if isinstance(e, HTTPException) and e.response is not None: res = e.response is_error_response = True totalTime = (datetime.now() - self._startTime) textLog.append('{} : Request ended'.format(totalTime)) # log request timing if profile and os.path.isfile(profile_name): rep = Config.getInstance().getTempDir() stats = pstats.Stats(profile_name) stats.strip_dirs() stats.sort_stats('cumulative', 'time', 'calls') stats.dump_stats(os.path.join(rep, 'IndicoRequestProfile.log')) output = StringIO.StringIO() sys.stdout = output stats.print_stats(100) sys.stdout = sys.__stdout__ s = output.getvalue() f = file(os.path.join(rep, 'IndicoRequest.log'), 'a+') f.write('--------------------------------\n') f.write('URL : {}\n'.format(request.url)) f.write('{} : start request\n'.format(self._startTime)) f.write('params:{}'.format(params)) f.write('\n'.join(textLog)) f.write(s) f.write('--------------------------------\n\n') f.close() if profile and profile_name and os.path.exists(profile_name): os.remove(profile_name) if self._responseUtil.call: return self._responseUtil.make_call() if is_error_response and isinstance( res, (current_app.response_class, Response)): # if we went through error handling code, responseUtil._status has been changed # so make_response() would fail return res # In case of no process needed, we should return empty string to avoid erroneous output # specially with getVars breaking the JS files. if not self._doProcess or res is None: return self._responseUtil.make_empty() return self._responseUtil.make_response(res)
def process(self, params): if request.method not in HTTP_VERBS: # Just to be sure that we don't get some crappy http verb we don't expect raise BadRequest cfg = Config.getInstance() forced_conflicts, max_retries, profile = cfg.getForceConflicts(), cfg.getMaxRetries(), cfg.getProfile() profile_name, res, textLog = '', '', [] self._startTime = datetime.now() # clear the context ContextManager.destroy() ContextManager.set('currentRH', self) g.rh = self #redirect to https if necessary if self._checkHttpsRedirect(): return self._responseUtil.make_redirect() if self.EVENT_FEATURE is not None: self._check_event_feature() DBMgr.getInstance().startRequest() textLog.append("%s : Database request started" % (datetime.now() - self._startTime)) Logger.get('requestHandler').info(u'Request started: %s %s [IP=%s] [PID=%s]', request.method, request.relative_url, request.remote_addr, os.getpid()) is_error_response = False try: for i, retry in enumerate(transaction.attempts(max_retries)): with retry: if i > 0: signals.before_retry.send() try: profile_name, res = self._process_retry(params, i, profile, forced_conflicts) signals.after_process.send() if i < forced_conflicts: # raise conflict error if enabled to easily handle conflict error case raise ConflictError if self.commit: transaction.commit() else: transaction.abort() DBMgr.getInstance().endRequest(commit=False) break except (ConflictError, POSKeyError): transaction.abort() import traceback # only log conflict if it wasn't forced if i >= forced_conflicts: Logger.get('requestHandler').warning('Database conflict') except ClientDisconnected: transaction.abort() Logger.get('requestHandler').warning('Client disconnected') time.sleep(i) except DatabaseError: handle_sqlalchemy_database_error() break self._process_success() except Exception as e: transaction.abort() res = self._getMethodByExceptionName(e)(e) if isinstance(e, HTTPException) and e.response is not None: res = e.response is_error_response = True totalTime = (datetime.now() - self._startTime) textLog.append('{} : Request ended'.format(totalTime)) # log request timing if profile and os.path.isfile(profile_name): rep = Config.getInstance().getTempDir() stats = pstats.Stats(profile_name) stats.sort_stats('cumulative', 'time', 'calls') stats.dump_stats(os.path.join(rep, 'IndicoRequestProfile.log')) output = StringIO.StringIO() sys.stdout = output stats.print_stats(100) sys.stdout = sys.__stdout__ s = output.getvalue() f = file(os.path.join(rep, 'IndicoRequest.log'), 'a+') f.write('--------------------------------\n') f.write('URL : {}\n'.format(request.url)) f.write('{} : start request\n'.format(self._startTime)) f.write('params:{}'.format(params)) f.write('\n'.join(textLog)) f.write(s) f.write('--------------------------------\n\n') f.close() if profile and profile_name and os.path.exists(profile_name): os.remove(profile_name) if self._responseUtil.call: return self._responseUtil.make_call() if is_error_response and isinstance(res, (current_app.response_class, Response)): # if we went through error handling code, responseUtil._status has been changed # so make_response() would fail return res # In case of no process needed, we should return empty string to avoid erroneous output # specially with getVars breaking the JS files. if not self._doProcess or res is None: return self._responseUtil.make_empty() return self._responseUtil.make_response(res)