Description
When redis and aioredis==1.3.1 is used together, newrelic tries to pickup the redis.asyncio.Redis as that of aioredis and throws the traceback as mentioned ๐๐ผ
aioredis==2.0.1 works fine.
Expected Behavior
Ideally, this hook should not be called, since the call is for redis.asyncio
Traceback (most recent call last):
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 408, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 84, in __call__
return await self.app(scope, receive, send)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/newrelic/api/asgi_application.py", line 363, in nr_async_asgi
return await coro
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/newrelic/common/async_proxy.py", line 148, in __next__
return self.send(None)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/newrelic/common/async_proxy.py", line 120, in send
return self.__wrapped__.send(value)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/fastapi/applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/newrelic/api/asgi_application.py", line 363, in nr_async_asgi
return await coro
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/newrelic/common/async_proxy.py", line 148, in __next__
return self.send(None)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/newrelic/common/async_proxy.py", line 120, in send
return self.__wrapped__.send(value)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/applications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "<string>", line 5, in wrapper
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/middleware/errors.py", line 186, in __call__
raise exc
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "<string>", line 5, in wrapper
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/routing.py", line 762, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/routing.py", line 782, in app
await route.handle(scope, receive, send)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/routing.py", line 297, in handle
await self.app(scope, receive, send)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/routing.py", line 77, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
raise exc
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/starlette/routing.py", line 72, in app
response = await func(request)
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/fastapi/routing.py", line 299, in app
raise e
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/fastapi/routing.py", line 294, in app
raw_response = await run_endpoint_function(
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
return await dependant.call(**values)
File "/Users/sanketdasgupta/work/fynd/stormbreaker/main.py", line 42, in read_root
value = await app.state.redis2.get("example_key")
File "/Users/sanketdasgupta/.pyenv/versions/quick-poc/lib/python3.9/site-packages/newrelic/hooks/datastore_aioredis.py", line 67, in _nr_wrapper_AioRedis_method_
if isinstance(instance._pool_or_conn, _RedisBuffer):
AttributeError: 'Redis' object has no attribute '_pool_or_conn'
Steps to Reproduce
import os
from fastapi import FastAPI
import redis.asyncio as aredis
import aioredis
from contextlib import asynccontextmanager
import newrelic.agent
# Initialize New Relic agent
newrelic.agent.initialize()
# Initialize FastAPI app
# New Relic application wrapper
# app = newrelic.agent.WSGIApplicationWrapper(app)
# New Relic transaction naming
# @newrelic.agent.transaction(name="FastAPI Server Transaction")
async def startup_event():
# Connect to Redis using aioredis
redis_url = os.getenv("REDIS_URL", "redis://localhost:6379")
app.state.redis = await aioredis.create_redis_pool(redis_url, encoding="utf-8")
app.state.redis2 = await aredis.from_url(redis_url, encoding="utf-8")
@asynccontextmanager
async def lifespan(app: FastAPI):
# Load the ML model
await startup_event()
yield
# Clean up the ML models and release the resources
app.state.redis.close()
await app.state.redis.wait_closed()
app = FastAPI(lifespan=lifespan)
@app.get("/")
async def read_root():
keys = ["all_countries_dict"]
# Example route using the initialized Redis connection
value = await app.state.redis2.get("example_key")
value = await app.state.redis.get("example_key")
value = await app.state.redis2.mget(*keys)
value = await app.state.redis2.mget(keys)
value = await app.state.redis.mget(*keys)
return {"message": "Hello, FastAPI!", "redis_value": value}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8001)
Description When
redis
andaioredis==1.3.1
is used together, newrelic tries to pickup theredis.asyncio.Redis
as that of aioredis and throws the traceback as mentioned ๐๐ผaioredis==2.0.1
works fine.Expected Behavior Ideally, this hook should not be called, since the call is for
redis.asyncio
Troubleshooting or NR Diag results
Steps to Reproduce
Your Environment
Additional context Note: Only happens with aioredis==1.3.1, works fine with
aioredis==2.0.1