コード例 #1
0
ファイル: wrappers.py プロジェクト: fredericlangevin/trytond
 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
コード例 #2
0
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)
コード例 #3
0
    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)
コード例 #4
0
    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)
コード例 #5
0
 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
コード例 #6
0
ファイル: cron.py プロジェクト: elat333/gw_tryton_docker
    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)
コード例 #7
0
    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
コード例 #8
0
    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)
コード例 #9
0
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
コード例 #10
0
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
コード例 #11
0
ファイル: dispatcher.py プロジェクト: mbehrle/trytond_coog
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