#34212 closed Bug (fixed)

Redis cache client uses a read connection for incr operation

Reported by: Ilari Sahi Owned by: Leo Tom
Component: Core (Cache system) Version: 4.1
Severity: Normal Keywords: redis cache incr
Cc: Daniyal Abbasi, Nick Pope Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

RedisCacheClient uses a read only connection for the incr operation:
https://github.com/django/django/blob/main/django/core/cache/backends/redis.py#L133

However, it is a write operation, at least according to Amazon ElastiCache Redis server. redis-py raises a ReadOnlyError exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.10/site-packages/django/views/generic/base.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/django/utils/decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/ratelimit/decorators.py", line 18, in _wrapped
    ratelimited = is_ratelimited(request=request, group=group, fn=fn,
  File "/usr/local/lib/python3.10/site-packages/ratelimit/core.py", line 119, in is_ratelimited
    usage = get_usage(request, group, fn, key, rate, method, increment)
  File "/usr/local/lib/python3.10/site-packages/ratelimit/core.py", line 205, in get_usage
    count = cache.incr(cache_key)
  File "/usr/local/lib/python3.10/site-packages/django/core/cache/backends/redis.py", line 214, in incr
    return self._cache.incr(key, delta)
  File "/usr/local/lib/python3.10/site-packages/django/core/cache/backends/redis.py", line 136, in incr
    return client.incr(key, delta)
  File "/usr/local/lib/python3.10/site-packages/redis/commands/core.py", line 1852, in incrby
    return self.execute_command("INCRBY", name, amount)
  File "/usr/local/lib/python3.10/site-packages/redis/client.py", line 1258, in execute_command
    return conn.retry.call_with_retry(
  File "/usr/local/lib/python3.10/site-packages/redis/retry.py", line 46, in call_with_retry
    return do()
  File "/usr/local/lib/python3.10/site-packages/redis/client.py", line 1259, in <lambda>
    lambda: self._send_command_parse_response(
  File "/usr/local/lib/python3.10/site-packages/redis/client.py", line 1235, in _send_command_parse_response
    return self.parse_response(conn, command_name, **options)
  File "/usr/local/lib/python3.10/site-packages/redis/client.py", line 1275, in parse_response
    response = connection.read_response()
  File "/usr/local/lib/python3.10/site-packages/redis/connection.py", line 827, in read_response
    raise response

Exception Type: ReadOnlyError at ...
Exception Value: You can't write against a read only replica.

In incr-function, get_client should be called with write argument as True.

Change History (6)

comment:1 by Mariusz Felisiak, 17 months ago

Cc: Daniyal Abbasi Nick Pope added
Triage Stage: UnreviewedAccepted

Good catch!

comment:2 by Leo Tom, 17 months ago

Owner: changed from nobody to Leo Tom
Status: newassigned

comment:4 by Mariusz Felisiak, 17 months ago

Needs tests: set

comment:5 by Mariusz Felisiak, 17 months ago

Needs tests: unset
Triage Stage: AcceptedReady for checkin

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 17 months ago

Resolution: fixed
Status: assignedclosed

In a1bcdc94:

Fixed #34212 -- Made RedisCacheClient.incr() use write connection.

Co-authored-by: Sin-Woo Bang <sinwoobang@…>

Note: See TracTickets for help on using tickets.
Back to Top