Skip to content

Commit

Permalink
fix(flask-caching): support v2.0 (DataDog#3882)
Browse files Browse the repository at this point in the history
## Description

flask-caching released version 2.0 which moves the cache client to a new library
called [`cachelib`](https://github.com/pallets-eco/cachelib).

Diff here: pallets-eco/flask-caching@v1.10.0...v2.0.0

This breaks our logic which collects tags for the redis client.

## Fix

It was noticed that both `_write_client` and `_read_client` use the same connection information
so we don't need to dynamically check for each.

Also [`_read_clients`](https://github.com/pallets-eco/flask-caching/blob/ac13e01baa11d65c68dcba64f99ccaafd9b5419c/src/flask_caching/backends/rediscache.py#L62) was moved to [`_read_client`](https://github.com/pallets-eco/cachelib/blob/13c8bf8db156dd06154f5e08e23bdd9e73480a5b/src/cachelib/redis.py#L29) when the logic was moved to `cachelib`.
  • Loading branch information
Kyle-Verhoog committed Jun 30, 2022
1 parent 22746a3 commit 94b0770
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 10 deletions.
22 changes: 14 additions & 8 deletions ddtrace/contrib/flask_cache/tracers.py
Expand Up @@ -3,6 +3,7 @@
"""

import logging
import typing

from ddtrace import config

Expand All @@ -14,6 +15,10 @@
from .utils import _resource_from_cache_prefix


if typing.TYPE_CHECKING:
from ddtrace import Span


log = logging.Logger(__name__)

DEFAULT_SERVICE = config.service or "flask-cache"
Expand Down Expand Up @@ -55,7 +60,8 @@ class TracedCache(cache_cls):
_datadog_service = service
_datadog_meta = meta

def __trace(self, cmd, write=False):
def __trace(self, cmd):
# type: (str, bool) -> Span
"""
Start a tracing with default attributes and tags
"""
Expand All @@ -68,7 +74,7 @@ def __trace(self, cmd, write=False):
# set analytics sample rate
s.set_tag(ANALYTICS_SAMPLE_RATE_KEY, config.flask_cache.get_analytics_sample_rate())
# add connection meta if there is one
client = _extract_client(self.cache, write=write)
client = _extract_client(self.cache)
if client is not None:
try:
s.set_tags(_extract_conn_tags(client))
Expand All @@ -91,7 +97,7 @@ def set(self, *args, **kwargs):
"""
Track ``set`` operation
"""
with self.__trace("flask_cache.cmd", write=True) as span:
with self.__trace("flask_cache.cmd") as span:
span.resource = _resource_from_cache_prefix("SET", self.config)
if len(args) > 0:
span.set_tag(COMMAND_KEY, args[0])
Expand All @@ -101,7 +107,7 @@ def add(self, *args, **kwargs):
"""
Track ``add`` operation
"""
with self.__trace("flask_cache.cmd", write=True) as span:
with self.__trace("flask_cache.cmd") as span:
span.resource = _resource_from_cache_prefix("ADD", self.config)
if len(args) > 0:
span.set_tag(COMMAND_KEY, args[0])
Expand All @@ -111,7 +117,7 @@ def delete(self, *args, **kwargs):
"""
Track ``delete`` operation
"""
with self.__trace("flask_cache.cmd", write=True) as span:
with self.__trace("flask_cache.cmd") as span:
span.resource = _resource_from_cache_prefix("DELETE", self.config)
if len(args) > 0:
span.set_tag(COMMAND_KEY, args[0])
Expand All @@ -121,7 +127,7 @@ def delete_many(self, *args, **kwargs):
"""
Track ``delete_many`` operation
"""
with self.__trace("flask_cache.cmd", write=True) as span:
with self.__trace("flask_cache.cmd") as span:
span.resource = _resource_from_cache_prefix("DELETE_MANY", self.config)
span.set_tag(COMMAND_KEY, list(args))
return super(TracedCache, self).delete_many(*args, **kwargs)
Expand All @@ -130,7 +136,7 @@ def clear(self, *args, **kwargs):
"""
Track ``clear`` operation
"""
with self.__trace("flask_cache.cmd", write=True) as span:
with self.__trace("flask_cache.cmd") as span:
span.resource = _resource_from_cache_prefix("CLEAR", self.config)
return super(TracedCache, self).clear(*args, **kwargs)

Expand All @@ -147,7 +153,7 @@ def set_many(self, *args, **kwargs):
"""
Track ``set_many`` operation
"""
with self.__trace("flask_cache.cmd", write=True) as span:
with self.__trace("flask_cache.cmd") as span:
span.resource = _resource_from_cache_prefix("SET_MANY", self.config)
if len(args) > 0:
span.set_tag(COMMAND_KEY, list(args[0].keys()))
Expand Down
9 changes: 7 additions & 2 deletions ddtrace/contrib/flask_cache/utils.py
Expand Up @@ -17,14 +17,19 @@ def _resource_from_cache_prefix(resource, cache):
return name.lower()


def _extract_client(cache, write=False):
def _extract_client(cache):
"""
Get the client from the cache instance according to the current operation
"""
client = getattr(cache, "_client", None)
if client is None:
# flask-caching has _read_clients & _write_client for the redis backend
client = getattr(cache, "_write_client" if write else "_read_clients", None)
# These use the same connection so just try to get a reference to one of them.
# flask-caching < 2.0.0 uses _read_clients so look for that one too.
for attr in ("_write_client", "_read_client", "_read_clients"):
client = getattr(cache, attr, None)
if client is not None:
break
return client


Expand Down
4 changes: 4 additions & 0 deletions releasenotes/notes/flask_caching-dc23b94171041b4f.yaml
@@ -0,0 +1,4 @@
---
fixes:
- |
flask_caching: fix redis tagging after the v2.0 release.

0 comments on commit 94b0770

Please sign in to comment.