Skip to content

Supporting aiobotocore #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
terricain opened this issue Nov 10, 2017 · 3 comments · Fixed by #6
Closed

Supporting aiobotocore #5

terricain opened this issue Nov 10, 2017 · 3 comments · Fixed by #6
Assignees

Comments

@terricain
Copy link
Contributor

Back again with more async stuff 😄

I've been using the aiobotocore library which essentially wraps botocore and uses aiohttp to perform async http requests.

I was looking into patching parts of it so the SDK creates subsegments when queries to AWS are made.
I've gotten it to work but its a bit messy.

The following is based off the botocore patcher. (The injecting headers bit is exactly the same bar a different class needs patching)

    wrapt.wrap_function_wrapper(
        'aiobotocore.client',
        'AioBaseClient._make_api_call',
        _xray_traced_aiobotocore,
    )

async def _xray_traced_aiobotocore(wrapped, instance, args, kwargs):
    service = instance._service_model.metadata["endpointPrefix"]

    return await xray_recorder.record_subsegment_async(
        wrapped, instance, args, kwargs,
        name=service,
        namespace='aws',
        meta_processor=aws_meta_processor,
    )

When wrapt runs, the wrapped service is a coroutine which needs to be awaited.
Until its awaited, the injecting of headers wont run.

I created a copy of record_subsegment called record_subsegment_async which is also a coroutine and it runs return_value = await wrapped(*args, **kwargs) which during that the headers are injected and then the result is returned. After that everything else works.

I tried awaiting the wrapped function inside of _xray_traced_aiobotocore but when the headers are injected the subsegment hasn't begun as thats done inside of record_subsegment.

What would you reckon is the best way for solving this, I was thinking of subclassing xray_recorder but if there is a simpler way I'm up for that. Then another PR will come your way 😄.

@haotianw465
Copy link
Contributor

Feel free to add new interface for the recorder as you see fit. Right now the recorder has https://github.com/aws/aws-xray-sdk-python/blob/master/aws_xray_sdk/core/recorder.py#L287 capture function so that any normal function can be annotated to be recorded. Once you add a record_subsegment_async helper a new function capture_async can utilize this helper so that all async functions can be easily recorded.

You probably have to do some work around compat.py so that the new change doesn't break python2.7. You cannot do import asyncio on top of recorder.py.

@terricain
Copy link
Contributor Author

You cannot do import asyncio on top of recorder.py

Yeah I was thinking about that, in compat.py, what about a decorator that does the same as asyncio.coroutine but when asyncio isn't available then just be a passthrough decorator

@haotianw465
Copy link
Contributor

Yes that will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants