Skip to content

Error using tracer with aioboto3  #10

Closed
@marcioemiranda

Description

@marcioemiranda

Hello Heitor,

I have a lambda that uses the tracer from aws_power_lambda_tools and the asyncio module. Everything runs fine with boto3, but if I use aioboto3 I get the following error:

Traceback (most recent call last):
  File "/opt/python/aws_lambda_powertools/tracing/tracer.py", line 152, in decorate
    raise err
  File "/opt/python/aws_lambda_powertools/tracing/tracer.py", line 144, in decorate
    response = lambda_handler(event, context)
  File "/opt/python/aws_lambda_powertools/logging/logger.py", line 157, in decorate
    return lambda_handler(event, context)
  File "/var/task/onExecuteCampaign/lambda_function.py", line 228, in lambda_handler
    raise e
  File "/var/task/onExecuteCampaign/lambda_function.py", line 225, in lambda_handler
    loop.run_until_complete(main(event, context))
  File "/var/lang/lib/python3.6/asyncio/base_events.py", line 488, in run_until_complete
    return future.result()
  File "/var/task/onExecuteCampaign/lambda_function.py", line 200, in main
    raise e
  File "/var/task/onExecuteCampaign/lambda_function.py", line 196, in main
    count_list = await asyncio.gather(*(process_segment(campaignId, segment) for segment in segments))
  File "/var/task/onExecuteCampaign/lambda_function.py", line 161, in process_segment
    raise e
  File "/var/task/onExecuteCampaign/lambda_function.py", line 158, in process_segment
    count_list  = await asyncio.gather(*(process_segment_partition(campaignId, segment,partition) for partition in range(num_partitions)))
  File "/var/task/onExecuteCampaign/lambda_function.py", line 140, in process_segment_partition
    raise e
  File "/var/task/onExecuteCampaign/lambda_function.py", line 119, in process_segment_partition
    Limit = pageSize
  File "/opt/python/aioboto3/resources.py", line 299, in do_action
    response = await action.async_call(self, *args, **kwargs)
  File "/opt/python/aioboto3/resources.py", line 67, in async_call
    response = await getattr(parent.meta.client, operation_name)(**params)
  File "/opt/python/aws_xray_sdk/ext/aiobotocore/patch.py", line 36, in _xray_traced_aiobotocore
    meta_processor=aws_meta_processor,
  File "/opt/python/aws_xray_sdk/core/async_recorder.py", line 101, in record_subsegment_async
    stack=stack,
  File "/opt/python/aws_xray_sdk/ext/boto_utils.py", line 57, in aws_meta_processor
    resp_meta.get('HTTPStatusCode'))
  File "/opt/python/aws_xray_sdk/core/models/entity.py", line 102, in put_http_meta
    self._check_ended()
  File "/opt/python/aws_xray_sdk/core/models/entity.py", line 283, in _check_ended
    raise AlreadyEndedException("Already ended segment and subsegment cannot be modified.")
aws_xray_sdk.core.exceptions.exceptions.AlreadyEndedException: Already ended segment and subsegment cannot be modified.

Here is the relevant snippet of code with aioboto3 (with python 3.6):

@tracer.capture_method
async def process_segment_partition(campaignId, segment, partition):
  ...
  async with aioboto3.resource('dynamodb') as dynamo_resource:

            # async table resource
            async_table = dynamo_resource.Table(environ['TABLE_NAME'])
            # query first page
            response = await async_table.query(
                KeyConditionExpression=Key('pk').eq(segmentPartitionId),
                Limit = pageSize
            )
  ...
  

async def process_segment(campaignId, segment):
    ...   
    await asyncio.gather(*(process_segment_partition(campaignId, segment,partition) for partition in range(num_partitions)))
    ...

# main loop implementation
async def main(event, context):
  ...
  await asyncio.gather(*(process_segment(campaignId, segment) for segment in segments))
  ...

@tracer.capture_lambda_handler
@logger_inject_lambda_context
def lambda_handler(event, context):
    
    try:
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main(event, context))
    except Exception as e:
        logger.exception(e)
        raise e
    finally:    
        loop.close()  

The code above raises the error mentioned.

If I just remove the aioboto3 part in the method process_segment_partition, it runs fine:

Using boto3:

@tracer.capture_method
async def process_segment_partition(campaignId, segment, partition):
    
    ...    
    response = table.query(
        KeyConditionExpression=Key('pk').eq(segmentPartitionId),
        Limit = pageSize
    )
    ...

Any ideas?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

Triage

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions