Example #1
0
async def test_vacuum_with_multiple_containers(es_requester):
    async with es_requester as requester:

        # create another container, force to iterate differently
        _, status = await requester('POST',
                                    '/db',
                                    data=json.dumps({
                                        '@type': 'Container',
                                        'id': 'foobar'
                                    }))
        assert status == 200
        await add_content(requester, num_items=100)

        search = get_utility(ICatalogUtility)
        container, request, txn, tm = await setup_txn_on_container(requester)
        aiotask_context.set('request', request)

        vacuum = Vacuum(txn, tm, request, container)
        await vacuum.setup()
        await vacuum.check_missing()
        await vacuum.check_orphans()

        async def ___test():
            assert await search.get_doc_count(container) == 1010

        await run_with_retries(___test, requester)

        await tm.abort(txn=txn)
def get_log_context() -> Dict:
    log_context = context.get(LOG_CONTEXT)
    if log_context is None:
        log_context = {}
        context.set(LOG_CONTEXT, log_context)

    return log_context
Example #3
0
 async def __aenter__(self):
     try:
         self._existing_request = get_current_request()
     except RequestNotFound:
         self._existing_request = None
     aiotask_context.set('request', self.request)
     return self
    async def do_check(self, arguments, check_name):
        aiotask_context.set('request', self.request)
        first_run = True
        while arguments.continuous or first_run:
            if not first_run:
                await asyncio.sleep(arguments.sleep)
            else:
                first_run = False
            async for txn, tm, container in get_containers(self.request):
                try:
                    kwargs = {}
                    if container._p_oid in self.state:
                        kwargs = self.state[container._p_oid]
                    vacuum = self.vacuum_klass(
                        txn, tm, self.request, container, **kwargs)
                    await vacuum.setup()
                    func = getattr(vacuum, check_name)
                    await func()
                    if vacuum.last_tid > 0:
                        self.state[container._p_oid] = {
                            'last_tid': vacuum.last_tid
                        }
                    logger.warning(f'''Finished vacuuming with results:
Orphaned cleaned: {len(vacuum.orphaned)}
Missing added: {len(vacuum.missing)}
Out of date fixed: {len(vacuum.out_of_date)}
''')
                    await clean_orphan_indexes(container)
                except Exception:
                    logger.error('Error vacuuming', exc_info=True)
                finally:
                    await tm.abort(txn=txn)
Example #5
0
async def test_updates_out_of_data_es_entries(es_requester):
    async with es_requester as requester:
        await add_content(requester)
        await asyncio.sleep(1)

        container, request, txn, tm = await setup_txn_on_container(requester)
        aiotask_context.set('request', request)

        search = get_utility(ICatalogUtility)
        index_name = await search.get_container_index_name(container)
        await search.update_by_query({
            'script': {
                'lang': 'painless',
                'inline': "ctx._source.remove('tid')"
            }
        }, indexes=[index_name])

        async def _test():
            assert await search.get_doc_count(container) == 110

        await run_with_retries(_test, requester)

        await asyncio.sleep(1)

        vacuum = Vacuum(txn, tm, request, container)
        await vacuum.setup()
        await vacuum.check_missing()
        await vacuum.check_orphans()

        assert len(vacuum.orphaned) == 0
        assert len(vacuum.missing) == 0
        assert len(vacuum.out_of_date) == 110

        await tm.abort(txn=txn)
Example #6
0
 async def __aenter__(self):
     aiotask_context.set('request', self.request)
     if self.func:
         if hasattr(self.func, '__aenter__'):
             return await self.func.__aenter__()
         else:
             return await self.func()
Example #7
0
 async def __aenter__(self):
     aiotask_context.set('request', self.request)
     if self.func:
         if hasattr(self.func, '__aenter__'):
             return await self.func.__aenter__()
         else:
             return await self.func()
Example #8
0
 async def __aenter__(self):
     try:
         self._existing_request = get_current_request()
     except RequestNotFound:
         self._existing_request = None
     aiotask_context.set('request', self.request)
     await login(self.request, self.user)
     return self
Example #9
0
async def request_id(request, handler):
    _request_id = request.headers.get('X-Request-ID', None)
    if not _request_id:
        _request_id = str(uuid4())
        request['X-Request-ID'] = _request_id
        context.set('X-Request-ID', _request_id)
    response = await handler(request)
    response.headers['X-Request-ID'] = _request_id
    return response
Example #10
0
async def test_task_context_child():
    aiotask_context.set("a", "b")

    async def child_task(a):
        aiotask_context.set("a", a)

    await asyncio.gather(*[child_task(i) for i in range(5)])

    a = aiotask_context.get("a")
    assert a == "b"
Example #11
0
async def request_id_middleware(request: web.Request, handler):
    request_id = request.headers.get(ID_HEADER)
    if not request_id or not ID_PATTERN.match(request_id):
        request_id = str(uuid4())
    request['request_id'] = request_id
    context.set('request_id', request_id)

    response = await handler(request)
    response.headers[ID_HEADER] = request_id
    return response
Example #12
0
    def user(self, value: User) -> None:
        """
        Sets the user on the current request. This is necessary to maintain
        compatibility with insanic.auth where the user property is
        set in the login and logout functions.

        Note that we also set the user on the task to give user context to any child tasks.
        """

        self._user = value
        aiotask_context.set(settings.TASK_CONTEXT_REQUEST_USER, dict(value))
Example #13
0
async def request_context_middleware(request: web.Request, handler: Callable) -> web.Response:
    """
    A Middleware that sets the current request's ID in the thread-local context, this helps in getting
    the unique ID of the current request in handlers.
    """
    x_request_id_header = "X-Request-ID"
    context.set(x_request_id_header, request.headers.get(x_request_id_header, str(uuid.uuid4())))

    response = await handler(request)
    response.headers[x_request_id_header] = context.get(x_request_id_header)

    return response
Example #14
0
 async def run(self):
     try:
         if self._request is not None:
             aiotask_context.set('request', self._request)
             async with managed_transaction(request=self._request,
                                            abort_when_done=False):
                 await self._func(*self._args or [], **self._kwargs or {})
         else:
             # if no request, we do it without transaction
             await self._func(*self._args or [], **self._kwargs or {})
     finally:
         aiotask_context.set('request', None)
Example #15
0
def test_gather_context_propagation():
    context.set("key", "value")

    @asyncio.coroutine
    def change_context():
        assert context.get("key") == "value"
        context.set("key", "what")
        context.set("other", "data")

    yield from asyncio.gather(change_context())
    assert context.get("key") == "what"
    assert context.get("other") == "data"
Example #16
0
    async def test_propagates_copy_of_context(self, event_loop):
        @asyncio.coroutine
        def adds_to_context():
            context.set('foo', 'bar')
            return True

        context.set('key', 'value')
        task = context.copying_task_factory(event_loop, adds_to_context())
        await task

        assert task.context == {'key': 'value', 'foo': 'bar'}
        assert context.get('foo') is None
Example #17
0
def dummy1(n_tasks):
    context.set("key", str(uuid.uuid4()))
    tasks = [
        asyncio.ensure_future(dummy2(id(asyncio.Task.current_task()), n))
        for n in range(n_tasks)
    ]
    results = yield from asyncio.gather(*tasks)
    info = defaultdict(list)
    for taskid, n, key in results:
        info[key].append([taskid, n])

    return info
Example #18
0
 async def run(self):
     try:
         if self._request is not None:
             aiotask_context.set('request', self._request)
             async with managed_transaction(
                     request=self._request, abort_when_done=False):
                 await self._func(*self._args or [], **self._kwargs or {})
         else:
             # if no request, we do it without transaction
             await self._func(*self._args or [], **self._kwargs or {})
     finally:
         aiotask_context.set('request', None)
Example #19
0
    async def initialize(self, app=None):
        # loop
        self.app = app
        while True:
            got_obj = False
            try:
                view = await self._queue.get()
                got_obj = True
                txn = get_transaction(view.request)
                tm = get_tm(view.request)
                if txn is None or (txn.status in (
                        Status.ABORTED, Status.COMMITTED, Status.CONFLICT) and
                        txn._db_conn is None):
                    txn = await tm.begin(view.request)
                else:
                    # still finishing current transaction, this connection
                    # will be cut off, so we need to wait until we no longer
                    # have an active transaction on the reqeust...
                    await self.add(view)
                    await asyncio.sleep(1)
                    continue

                try:
                    aiotask_context.set('request', view.request)
                    view_result = await view()
                    if isinstance(view_result, ErrorResponse):
                        await tm.commit(txn=txn)
                    elif isinstance(view_result, UnauthorizedResponse):
                        await tm.abort(txn=txn)
                    else:
                        await tm.commit(txn=txn)
                except Unauthorized:
                    await tm.abort(txn=txn)
                except Exception as e:
                    logger.error(
                        "Exception on writing execution",
                        exc_info=e)
                    await tm.abort(txn=txn)
            except (KeyboardInterrupt, MemoryError, SystemExit,
                    asyncio.CancelledError, GeneratorExit, RuntimeError):
                self._exceptions = True
                raise
            except Exception as e:  # noqa
                self._exceptions = True
                logger.error('Worker call failed', exc_info=e)
            finally:
                aiotask_context.set('request', None)
                if got_obj:
                    try:
                        view.request.execute_futures()
                    except AttributeError:
                        pass
                    self._queue.task_done()
Example #20
0
def request_middleware(request) -> None:
    """
    Request middleware that runs on all requests. Tracks the
    request count and sets a correlation id to the asyncio task
    if included in the headers.

    :param request: The Request object.
    """
    try:
        request.app.metrics.REQUEST_COUNT.inc()
    except AttributeError:  # pragma: no cover
        pass
    aiotask_context.set(settings.TASK_CONTEXT_CORRELATION_ID, request.id)
Example #21
0
    async def initialize(self, app=None):
        # loop
        self.app = app
        while True:
            got_obj = False
            try:
                view = await self.queue.get()
                got_obj = True
                txn = get_transaction(view.request)
                tm = get_tm(view.request)
                if txn is None or (txn.status in (
                        Status.ABORTED, Status.COMMITTED, Status.CONFLICT) and
                        txn._db_conn is None):
                    txn = await tm.begin(view.request)
                else:
                    # still finishing current transaction, this connection
                    # will be cut off, so we need to wait until we no longer
                    # have an active transaction on the reqeust...
                    await self.add(view)
                    await asyncio.sleep(1)
                    continue

                try:
                    aiotask_context.set('request', view.request)
                    await view()
                    await tm.commit(txn=txn)
                except Exception as e:
                    logger.error(
                        "Exception on writing execution",
                        exc_info=e)
                    await tm.abort(txn=txn)
            except (RuntimeError, SystemExit, GeneratorExit, KeyboardInterrupt,
                    asyncio.CancelledError, KeyboardInterrupt):
                # dive, these errors mean we're exit(ing)
                self._exceptions = True
                return
            except Exception as e:  # noqa
                self._exceptions = True
                logger.error('Worker call failed', exc_info=e)
            finally:
                try:
                    aiotask_context.set('request', None)
                except (RuntimeError, ValueError):
                    pass
                if got_obj:
                    try:
                        view.request.execute_futures()
                    except AttributeError:
                        pass
                    self.queue.task_done()
Example #22
0
    async def test_inject_headers(self, extra_headers, loop):
        aiotask_context.set(settings.TASK_CONTEXT_REQUEST_USER,
                            {"some": "user"})

        headers = self.service._inject_headers(extra_headers)

        required_headers = [
            "date",
            "x-insanic-request-user",
            "x-insanic-request-id",
        ]

        for h in required_headers:
            assert h in headers.keys()
async def test_unindex_during_next_index(es_requester):
    async with es_requester as requester:
        await add_content(requester, 2)
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = get_utility(ICatalogUtility)
        index_manager = get_adapter(container, IIndexManager)
        work_index_name = await index_manager.start_migration()
        await search.create_index(work_index_name, index_manager)
        await tm.commit(txn=txn)
        container, request, txn, tm = await setup_txn_on_container(requester)
        keys = await container.async_keys()
        item = await container.async_get(keys[0])
        aiotask_context.set('request', request)
        await notify(ObjectRemovedEvent(item, container, item.id))
        request.execute_futures()
        await asyncio.sleep(1)
Example #24
0
 async def run(self, arguments, settings, app):
     aiotask_context.set('request', self.request)
     script = os.path.abspath(arguments.script)
     spec = importlib.util.spec_from_file_location("module.name", script)
     module = importlib.util.module_from_spec(spec)
     spec.loader.exec_module(module)
     if not hasattr(module, 'run'):
         logger.warn(f'Not `async def run()` function found in file {script}')
         return
     sig = inspect.signature(module.run)
     if 'container' in sig.parameters:
         async for txn, tm, container in get_containers(self.request):
             await module.run(container)
             await tm.commit(txn=txn)
     else:
         await lazy_apply(module.run, app)
Example #25
0
    async def run(self, arguments, settings, app):
        aiotask_context.set('request', self.request)
        if arguments.task_id is not None:
            task = arguments.task_id
            payload_config = False
        else:
            if hasattr(arguments, 'payload') and arguments.payload is not None:
                task = arguments.payload
                task = json.loads(task)
            else:
                task = os.environ.get('PAYLOAD', '{}')
                logger.warning(f"Task to do: \n {task}")
                task = json.loads(task)
            payload_config = True
        tags = []
        if arguments.tags:
            tags = json.loads(arguments.tags)

        logger.warning("Tasks available: \n")
        for k, v in settings.get('hive_tasks', {}).items():
            logger.warning(f"{k}: {v}")
        task_obj = None
        root_obj = get_utility(IApplication, name='root')
        if payload_config is False:
            elements = task.split('/')[1:]
            db_obj = await root_obj.async_get(elements[0])
            if IDatabase.providedBy(db_obj):
                tm = self.request._tm = db_obj.get_transaction_manager()
                tm.request = self.request
                self.request._db_id = elements[0]
                self.request._txn = txn = await tm.begin(self.request)
                container_obj = await db_obj.async_get(elements[1])
                if IContainer.providedBy(container_obj):
                    guillotina_execution = await navigate_to(
                        container_obj, '/'.join(elements[2:]))
                    if IExecution.providedBy(guillotina_execution):
                        task_obj = TaskObject(
                            data=guillotina_execution.get_task_payload())
                await tm.abort(txn=txn)
        elif payload_config is True:
            task_obj = TaskObject(data=task)

        if task_obj is None:
            raise NoTaskFunctionDefinedError()
        logger.warning("Ready to run")
        return await task_obj.run(self.request, tags, root_obj)
Example #26
0
 async def run(self, arguments, settings, app):
     aiotask_context.set('request', self.request)
     script = os.path.abspath(arguments.script)
     spec = importlib.util.spec_from_file_location("module.name", script)
     module = importlib.util.module_from_spec(spec)
     spec.loader.exec_module(module)
     if not hasattr(module, 'run'):
         logger.warn(
             f'Not `async def run()` function found in file {script}')
         return
     sig = inspect.signature(module.run)
     if 'container' in sig.parameters:
         async for txn, tm, container in get_containers(self.request):
             await module.run(container)
             await tm.commit(txn=txn)
     else:
         await lazy_apply(module.run, app)
Example #27
0
async def test_unindex_during_next_index(es_requester):
    async with es_requester as requester:
        await add_content(requester, 2)
        container, request, txn, tm = await setup_txn_on_container(requester)
        search = getUtility(ICatalogUtility)
        migrator = Migrator(search, container, force=True, request=request)
        next_index_version, work_index_name = await migrator.create_next_index(
        )
        await search.install_mappings_on_index(work_index_name)
        await search.activate_next_index(container,
                                         next_index_version,
                                         request=request)
        await tm.commit(txn=txn)
        container, request, txn, tm = await setup_txn_on_container(requester)
        keys = await container.async_keys()
        item = await container.async_get(keys[0])
        aiotask_context.set('request', request)
        await notify(ObjectRemovedEvent(item, container, item.id))
        request.execute_futures()
        await asyncio.sleep(1)
Example #28
0
 async def _handle(self, request, retries=0):
     aiotask_context.set('request', request)
     try:
         return await super()._handle(request)
     except (ConflictError, TIDConflictError) as e:
         if app_settings.get('conflict_retry_attempts', 3) > retries:
             label = 'DB Conflict detected'
             if isinstance(e, TIDConflictError):
                 label = 'TID Conflict Error detected'
             tid = getattr(getattr(request, '_txn', None), '_tid', 'not issued')
             logger.debug(
                 f'{label}, retrying request, tid: {tid}, retries: {retries + 1})',
                 exc_info=True)
             request._retry_attempt = retries + 1
             request.clear_futures()
             return await self._handle(request, retries + 1)
         logger.error(
             'Exhausted retry attempts for conflict error on tid: {}'.format(
                 getattr(getattr(request, '_txn', None), '_tid', 'not issued')
             ))
         return HTTPConflict()
Example #29
0
 async def _handle(self, request, retries=0):
     aiotask_context.set('request', request)
     try:
         return await super()._handle(request)
     except (ConflictError, TIDConflictError) as e:
         if app_settings.get('conflict_retry_attempts', 3) > retries:
             label = 'DB Conflict detected'
             if isinstance(e, TIDConflictError):
                 label = 'TID Conflict Error detected'
             tid = getattr(getattr(request, '_txn', None), '_tid', 'not issued')
             logger.debug(
                 f'{label}, retrying request, tid: {tid}, retries: {retries + 1})',
                 exc_info=True)
             request._retry_attempt = retries + 1
             request.clear_futures()
             return await self._handle(request, retries + 1)
         logger.error(
             'Exhausted retry attempts for conflict error on tid: {}'.format(
                 getattr(getattr(request, '_txn', None), '_tid', 'not issued')
             ))
         return HTTPConflict()
Example #30
0
    def __init__(self, *args, **kwargs):
        """
        Initialize the session, called by the underlying framework telepot
        :param args: Used by telepot
        :param kwargs: Used by telepot
        """

        # Call superclasses superclass, allowing callback queries to be processed
        super(_Session, self).__init__(include_callback_query=True,
                                       *args,
                                       **kwargs)

        # Extract the user of the default arguments
        self.user = User(args[0][1]['from'])

        # Create dictionary to use as persistent storage
        # Load data from persistent storage
        if _Session.database is not None:

            self.storage = _Session.load_user_data(self.user_id)

        else:
            self.storage = dict()

        self.callback = None
        self.query_callback = {}
        self.query_id = None
        self.last_sent = None
        self.gen = None
        self.gen_is_async = None

        # Prepare dequeue to store sent messages' IDs
        _context.set(
            "history",
            deque(maxlen=_config_value(
                "bot", "max_history_entries", default=10)))

        logger.info("User {} connected".format(self.user))
Example #31
0
 async def handle(self, message):
     payload = message.get('payload') or {}
     if not isinstance(payload, str):
         payload = ujson.dumps(payload)
     headers = dict(self.request.headers)
     headers.update(message.get('headers') or {})
     request = await self.clone_request(message['method'],
                                        message['endpoint'], payload,
                                        headers)
     try:
         aiotask_context.set('request', request)
         if self.eager_commit:
             try:
                 result = await self._handle(request, message)
             except Exception as err:
                 await request._tm.abort()
                 result = self._gen_result(
                     generate_error_response(err, request, 'ViewError'))
         else:
             result = await self._handle(request, message)
         return result
     finally:
         aiotask_context.set('request', self.request)
Example #32
0
async def test_adds_missing_elasticsearch_entry(es_requester):
    async with es_requester as requester:
        await add_content(requester)

        search = get_utility(ICatalogUtility)
        container, request, txn, tm = await setup_txn_on_container(requester)
        aiotask_context.set('request', request)

        async def _test():
            assert await search.get_doc_count(container) == 110

        await run_with_retries(_test, requester)

        for key in await container.async_keys():
            ob = await container.async_get(key)
            await search.remove(container, [ob], request=request)

        async def __test():
            assert await search.get_doc_count(container) == 0

        await run_with_retries(__test, requester)

        vacuum = Vacuum(txn, tm, request, container)
        await vacuum.setup()
        await vacuum.check_missing()
        await vacuum.check_orphans()

        assert len(vacuum.orphaned) == 0
        assert len(vacuum.out_of_date) == 0
        assert len(vacuum.missing) == 110

        async def ___test():
            assert await search.get_doc_count(container) == 110

        await run_with_retries(___test, requester)

        await tm.abort(txn=txn)
Example #33
0
async def my_coro_2():
    context.set("request_id", str(uuid.uuid4()))
    await asyncio.gather(asyncio.ensure_future(my_coro(0)),
                         asyncio.wait_for(my_coro(1), 1),
                         asyncio.shield(asyncio.wait_for(my_coro(2), 1)),
                         my_coro(3))
Example #34
0
 async def __aexit__(self, *args):
     if self.func and hasattr(self.func, '__aexit__'):
         return await self.func.__aexit__(*args)
     aiotask_context.set('request', self.original)
Example #35
0
 def change_context():
     assert context.get("key") == "value"
     context.set("key", "what")
     context.set("other", "data")
Example #36
0
 async def __aexit__(self, *args):
     logout(self.request)
     aiotask_context.set('request', self._existing_request)
     # make sure to close out connection
     await self.abort()
Example #37
0
async def set_request_id(request):
    request_id = request.headers.get('X-Request-ID') or str(uuid.uuid4())
    context.set("X-Request-ID", request_id)
Example #38
0
 async def get_proxy(self):
     proxy = ctx.get('_nameko_rpc_proxy', None)
     if not proxy:
         proxy = await super(SanicNamekoClusterRpcProxy, self).get_proxy()
         ctx.set('_nameko_rpc_proxy', proxy)
     return proxy
Example #39
0
async def main2():
    context.set('lol', NeedClose())
    try:
        await asyncio.gather(k(), asyncio.sleep(2))
    except asyncio.CancelledError:
        pass