def wrapper(request, pool, *args, **kwargs): DatabaseOperationalError = backend.get('DatabaseOperationalError') readonly_ = readonly # can not modify non local if readonly_ is None: if request.method in {'POST', 'PUT', 'DELETE', 'PATCH'}: readonly_ = False else: readonly_ = True context = {'_request': request.context} for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(pool.database_name, 0, readonly=readonly_, context=context) as transaction: try: result = func(request, pool, *args, **kwargs) except DatabaseOperationalError: if count and not readonly_: transaction.rollback() continue logger.error('%s', request, exc_info=True) raise except Exception: logger.error('%s', request, exc_info=True) raise # Need to commit to unlock SQLite database transaction.commit() while transaction.tasks: task_id = transaction.tasks.pop() run_task(pool, task_id) return result
def run(options): db_name = options.database_name pool = Pool(db_name) with Transaction().start(db_name, 0, readonly=True): pool.init() with Transaction().start(db_name, 0) as transaction: local = { 'pool': pool, 'transaction': transaction, } if sys.stdin.isatty(): console = Console(local, histsize=options.histsize) banner = "Tryton %s, Python %s on %s" % (__version__, sys.version, sys.platform) kwargs = {} if sys.version_info >= (3, 6): kwargs['exitmsg'] = '' console.interact(banner=banner, **kwargs) else: console = InteractiveConsole(local) console.runcode(sys.stdin.read()) transaction.rollback() while transaction.tasks: task_id = transaction.tasks.pop() run_task(pool, task_id)
def run(cls, db_name): transaction = Transaction() logger.info('cron started for "%s"', db_name) now = datetime.datetime.now() retry = config.getint('database', 'retry') with transaction.start(db_name, 0, context={'_skip_warnings': True}): transaction.database.lock(transaction.connection, cls._table) crons = cls.search(['OR', ('next_call', '<=', now), ('next_call', '=', None), ]) for cron in crons: name = '<Cron %s@%s %s>' % (cron.id, db_name, cron.method) logger.info("%s started", name) for count in range(retry, -1, -1): if count != retry: time.sleep(0.02 * (retry - count)) try: with processing(name): cron.run_once() cron.next_call = cron.compute_next_call(now) cron.save() transaction.commit() except Exception as e: transaction.rollback() if (isinstance(e, backend.DatabaseOperationalError) and count): continue logger.error('%s failed', name, exc_info=True) break while transaction.tasks: task_id = transaction.tasks.pop() run_task(db_name, task_id) logger.info('cron finished for "%s"', db_name)
def run(cls, db_name): DatabaseOperationalError = backend.get('DatabaseOperationalError') logger.info('cron started for "%s"', db_name) now = datetime.datetime.now() retry = config.getint('database', 'retry') with Transaction().start(db_name, 0) as transaction: transaction.database.lock(transaction.connection, cls._table) crons = cls.search([ 'OR', ('next_call', '<=', now), ('next_call', '=', None), ]) for cron in crons: logger.info("Run cron %s", cron.id) for count in range(retry, -1, -1): if count != retry: time.sleep(0.02 * (retry - count)) try: cron.run_once() cron.next_call = cron.compute_next_call(now) cron.save() transaction.commit() except Exception as e: transaction.rollback() if isinstance(e, DatabaseOperationalError) and count: continue logger.error('Running cron %s', cron.id, exc_info=True) break while transaction.tasks: task_id = transaction.tasks.pop() run_task(db_name, task_id) logger.info('cron finished for "%s"', db_name)
def wrapper(request, pool, *args, **kwargs): nonlocal user, context readonly_ = readonly # can not modify non local if readonly_ is None: if request.method in {'POST', 'PUT', 'DELETE', 'PATCH'}: readonly_ = False else: readonly_ = True if context is None: context = {} else: context = context.copy() context['_request'] = request.context if user == 'request': user = request.user_id retry = config.getint('database', 'retry') for count in range(retry, -1, -1): if count != retry: time.sleep(0.02 * (retry - count)) with Transaction().start(pool.database_name, user, readonly=readonly_, context=context) as transaction: try: result = func(request, pool, *args, **kwargs) except backend.DatabaseOperationalError: if count and not readonly_: transaction.rollback() continue logger.error('%s', request, exc_info=True) raise except Exception: logger.error('%s', request, exc_info=True) raise # Need to commit to unlock SQLite database transaction.commit() while transaction.tasks: task_id = transaction.tasks.pop() run_task(pool, task_id) return result
def run(cls, db_name): now = datetime.datetime.now() with Transaction().start(db_name, 0) as transaction: transaction.database.lock(transaction.connection, cls._table) crons = cls.search([ ('number_calls', '!=', 0), ('next_call', '<=', datetime.datetime.now()), ]) for cron in crons: try: next_call = cron.next_call number_calls = cron.number_calls first = True while next_call < now and number_calls != 0: if first or cron.repeat_missed: try: cron.run_once() except Exception: transaction.rollback() cron.send_error_message() next_call += cls.get_delta(cron) if number_calls > 0: number_calls -= 1 first = False cron.next_call = next_call cron.number_calls = number_calls if not number_calls: cron.active = False cron.save() transaction.commit() except Exception: transaction.rollback() logger.error('Running cron %s', cron.id, exc_info=True) while transaction.tasks: task_id = transaction.tasks.pop() run_task(db_name, task_id)
def __call__(self, *args, **kwargs): from trytond.rpc import RPC from trytond.tools import is_instance_method from trytond.transaction import Transaction from trytond.worker import run_task if self._name in self._object.__rpc__: rpc = self._object.__rpc__[self._name] elif self._name in getattr(self._object, '_buttons', {}): rpc = RPC(readonly=False, instantiate=0) else: raise TypeError('%s is not callable' % self._name) with Transaction().start(self._config.database_name, self._config.user, readonly=rpc.readonly) as transaction: args, kwargs, transaction.context, transaction.timestamp = \ rpc.convert(self._object, *args, **kwargs) meth = getattr(self._object, self._name) if (rpc.instantiate is None or not is_instance_method(self._object, self._name)): result = rpc.result(meth(*args, **kwargs)) else: assert rpc.instantiate == 0 inst = args.pop(0) if hasattr(inst, self._name): result = rpc.result(meth(inst, *args, **kwargs)) else: result = [ rpc.result(meth(i, *args, **kwargs)) for i in inst ] transaction.commit() while transaction.tasks: task_id = transaction.tasks.pop() run_task(self._config.database_name, task_id) return result
def run(cls, db_name): logger.info('cron started for "%s"', db_name) now = datetime.datetime.now() with Transaction().start(db_name, 0) as transaction: transaction.database.lock(transaction.connection, cls._table) crons = cls.search(['OR', ('next_call', '<=', now), ('next_call', '=', None), ]) for cron in crons: logger.info("Run cron %s", cron.id) try: cron.run_once() cron.next_call = cron.compute_next_call(now) cron.save() transaction.commit() except Exception: transaction.rollback() logger.error('Running cron %s', cron.id, exc_info=True) while transaction.tasks: task_id = transaction.tasks.pop() run_task(db_name, task_id) logger.info('cron finished for "%s"', db_name)
def _dispatch(request, pool, *args, **kwargs): # AKE: perf analyzer hooks try: PerfLog().on_enter() except Exception: perf_logger.exception('on_enter failed') obj, method = get_object_method(request, pool) if method in obj.__rpc__: rpc = obj.__rpc__[method] else: abort(HTTPStatus.FORBIDDEN) user = request.user_id session = None if request.authorization.type == 'session': session = request.authorization.get('session') if rpc.fresh_session and session: context = {'_request': request.context} if not security.check_timeout( pool.database_name, user, session, context=context): abort(http.client.UNAUTHORIZED) log_message = '%s.%s(*%s, **%s) from %s@%s%s' username = request.authorization.username if isinstance(username, bytes): username = username.decode('utf-8') log_args = (obj, method, args, kwargs, username, request.remote_addr, request.path) logger.debug(log_message, *log_args) # JCA: log slow RPC if slow_threshold >= 0: slow_msg = '%s.%s (%s s)' slow_args = (obj, method) slow_start = time.time() # JCA: Format parameters if format_json_parameters and logger.isEnabledFor(logging.DEBUG): try: for line in json.dumps(args, indent=2, sort_keys=True, cls=DEBUGEncoder).split('\n'): logger.debug('Parameters: %s' % line) except Exception: logger.debug('Could not format parameters in log', exc_info=True) user = request.user_id # AKE: add session and token to transaction context token = None if request.authorization.type == 'token': token = { 'key': request.authorization.get('token'), 'user': user, 'party': request.authorization.get('party_id'), } # AKE: perf analyzer hooks try: PerfLog().on_execute(user, session, request.rpc_method, args, kwargs) except Exception: perf_logger.exception('on_execute failed') retry = config.getint('database', 'retry') for count in range(retry, -1, -1): if count != retry: time.sleep(0.02 * (retry - count)) with Transaction().start(pool.database_name, user, readonly=rpc.readonly) as transaction: try: c_args, c_kwargs, transaction.context, transaction.timestamp \ = rpc.convert(obj, *args, **kwargs) # AKE: add session to transaction context transaction.context.update({ 'session': session, 'token': token, }) transaction.context['_request'] = request.context meth = getattr(obj, method) # AKE: perf analyzer hooks try: wrapped_meth = profile(meth) except Exception: perf_logger.exception('profile failed') else: meth = wrapped_meth if (rpc.instantiate is None or not is_instance_method(obj, method)): result = rpc.result(meth(*c_args, **c_kwargs)) else: assert rpc.instantiate == 0 inst = c_args.pop(0) if hasattr(inst, method): result = rpc.result(meth(inst, *c_args, **c_kwargs)) else: result = [ rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst ] except backend.DatabaseOperationalError: if count and not rpc.readonly: transaction.rollback() continue logger.error(log_message, *log_args, exc_info=True) # JCA: log slow RPC if slow_threshold >= 0: slow_args += (str(time.time() - slow_start), ) log_exception(slow_logger.error, slow_msg, *slow_args) raise except (ConcurrencyException, UserError, UserWarning, LoginException): logger.debug(log_message, *log_args, exc_info=True) # JCA: log slow RPC if slow_threshold >= 0: slow_args += (str(time.time() - slow_start), ) log_exception(slow_logger.debug, slow_msg, *slow_args) raise except Exception: logger.error(log_message, *log_args, exc_info=True) # JCA: log slow RPC if slow_threshold >= 0: slow_args += (str(time.time() - slow_start), ) log_exception(slow_logger.error, slow_msg, *slow_args) raise # Need to commit to unlock SQLite database transaction.commit() while transaction.tasks: task_id = transaction.tasks.pop() run_task(pool, task_id) if session: context = {'_request': request.context} security.reset(pool.database_name, session, context=context) # JCA: Allow to format json result if format_json_result and logger.isEnabledFor(logging.DEBUG): try: for line in json.dumps(result, indent=2, sort_keys=True, cls=DEBUGEncoder).split('\n'): logger.debug('Result: %s' % line) except Exception: logger.debug('Could not format parameters in log', exc_info=True) else: logger.debug('Result: %s', result) # JCA: log slow RPC if slow_threshold >= 0: slow_diff = time.time() - slow_start slow_args += (str(slow_diff), ) if slow_diff > slow_threshold: slow_logger.info(slow_msg, *slow_args) else: slow_logger.debug(slow_msg, *slow_args) # AKE: perf analyzer hooks try: PerfLog().on_leave(result) except Exception: perf_logger.exception('on_leave failed') response = app.make_response(request, result) if rpc.readonly and rpc.cache: response.headers.extend(rpc.cache.headers()) return response
def _dispatch(request, pool, *args, **kwargs): obj, method = get_object_method(request, pool) if method in obj.__rpc__: rpc = obj.__rpc__[method] else: abort(HTTPStatus.FORBIDDEN) user = request.user_id session = None if request.authorization.type == 'session': session = request.authorization.get('session') if rpc.fresh_session and session: context = {'_request': request.context} if not security.check_timeout( pool.database_name, user, session, context=context): abort(HTTPStatus.UNAUTHORIZED) log_message = '%s.%s(*%s, **%s) from %s@%s%s' username = request.authorization.username if isinstance(username, bytes): username = username.decode('utf-8') log_args = (obj, method, args, kwargs, username, request.remote_addr, request.path) logger.debug(log_message, *log_args) retry = config.getint('database', 'retry') for count in range(retry, -1, -1): if count != retry: time.sleep(0.02 * (retry - count)) with Transaction().start(pool.database_name, user, readonly=rpc.readonly) as transaction: try: c_args, c_kwargs, transaction.context, transaction.timestamp \ = rpc.convert(obj, *args, **kwargs) transaction.context['_request'] = request.context meth = getattr(obj, method) if (rpc.instantiate is None or not is_instance_method(obj, method)): result = rpc.result(meth(*c_args, **c_kwargs)) else: assert rpc.instantiate == 0 inst = c_args.pop(0) if hasattr(inst, method): result = rpc.result(meth(inst, *c_args, **c_kwargs)) else: result = [ rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst ] except backend.DatabaseOperationalError: if count and not rpc.readonly: transaction.rollback() continue logger.error(log_message, *log_args, exc_info=True) raise except (ConcurrencyException, UserError, UserWarning, LoginException): logger.debug(log_message, *log_args, exc_info=True) raise except Exception: logger.error(log_message, *log_args, exc_info=True) raise # Need to commit to unlock SQLite database transaction.commit() while transaction.tasks: task_id = transaction.tasks.pop() run_task(pool, task_id) if session: context = {'_request': request.context} security.reset(pool.database_name, session, context=context) logger.debug('Result: %s', result) response = app.make_response(request, result) if rpc.readonly and rpc.cache: response.headers.extend(rpc.cache.headers()) return response
def _dispatch(request, pool, *args, **kwargs): # AKE: perf analyzer hooks try: PerfLog().on_enter() except Exception: perf_logger.exception('on_enter failed') DatabaseOperationalError = backend.get('DatabaseOperationalError') obj, method = get_object_method(request, pool) if method in obj.__rpc__: rpc = obj.__rpc__[method] else: abort(HTTPStatus.FORBIDDEN) user = request.user_id session = None if request.authorization.type == 'session': session = request.authorization.get('session') if rpc.fresh_session and session: context = {'_request': request.context} if not security.check_timeout( pool.database_name, user, session, context=context): abort(http.client.UNAUTHORIZED) log_message = '%s.%s(*%s, **%s) from %s@%s/%s' username = request.authorization.username if isinstance(username, bytes): username = username.decode('utf-8') log_args = (obj, method, args, kwargs, username, request.remote_addr, request.path) logger.info(log_message, *log_args) # JCA: log slow RPC if slow_threshold >= 0: slow_msg = '%s.%s (%s s)' slow_args = (obj, method) slow_start = time.time() user = request.user_id # AKE: add session to transaction context token, session = None, None if request.authorization.type == 'session': session = request.authorization.get('session') elif request.authorization.type == 'token': token = { 'key': request.authorization.get('token'), 'user': user, 'party': request.authorization.get('party_id'), } # AKE: perf analyzer hooks try: PerfLog().on_execute(user, session, request.rpc_method, args, kwargs) except Exception: perf_logger.exception('on_execute failed') for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(pool.database_name, user, readonly=rpc.readonly) as transaction: try: c_args, c_kwargs, transaction.context, transaction.timestamp \ = rpc.convert(obj, *args, **kwargs) # AKE: add session to transaction context transaction.context.update({ 'session': session, 'token': token, }) transaction.context['_request'] = request.context meth = getattr(obj, method) # AKE: perf analyzer hooks try: wrapped_meth = profile(meth) except Exception: perf_logger.exception('profile failed') else: meth = wrapped_meth if (rpc.instantiate is None or not is_instance_method(obj, method)): result = rpc.result(meth(*c_args, **c_kwargs)) else: assert rpc.instantiate == 0 inst = c_args.pop(0) if hasattr(inst, method): result = rpc.result(meth(inst, *c_args, **c_kwargs)) else: result = [ rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst ] except DatabaseOperationalError: if count and not rpc.readonly: transaction.rollback() continue logger.error(log_message, *log_args, exc_info=True) # JCA: log slow RPC if slow_threshold >= 0: slow_args += (str(time.time() - slow_start), ) log_exception(slow_logger.error, slow_msg, *slow_args) raise except (ConcurrencyException, UserError, UserWarning, LoginException): logger.debug(log_message, *log_args, exc_info=True) # JCA: log slow RPC if slow_threshold >= 0: slow_args += (str(time.time() - slow_start), ) log_exception(slow_logger.debug, slow_msg, *slow_args) raise except Exception: logger.error(log_message, *log_args, exc_info=True) # JCA: log slow RPC if slow_threshold >= 0: slow_args += (str(time.time() - slow_start), ) log_exception(slow_logger.error, slow_msg, *slow_args) raise # Need to commit to unlock SQLite database transaction.commit() if request.authorization.type == 'session': # AKE: moved all session ops to security script security.reset_user_session(pool.database_name, user, request.authorization.get('session')) while transaction.tasks: task_id = transaction.tasks.pop() run_task(pool, task_id) if session: context = {'_request': request.context} security.reset(pool.database_name, session, context=context) logger.debug('Result: %s', result) # JCA: log slow RPC if slow_threshold >= 0: slow_diff = time.time() - slow_start slow_args += (str(slow_diff), ) if slow_diff > slow_threshold: slow_logger.info(slow_msg, *slow_args) else: slow_logger.debug(slow_msg, *slow_args) # AKE: perf analyzer hooks try: PerfLog().on_leave(result) except Exception: perf_logger.exception('on_leave failed') return result