mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-23 15:57:23 -04:00
fix set and get in redis_client
This commit is contained in:
@@ -116,10 +116,10 @@ def registration_continue():
|
|||||||
|
|
||||||
def get_invite_data_from_redis(state):
|
def get_invite_data_from_redis(state):
|
||||||
|
|
||||||
invite_data = json.loads(redis_client.raw_get(f"invitedata-{state}"))
|
invite_data = json.loads(redis_client.get(f"invitedata-{state}"))
|
||||||
user_email = redis_client.raw_get(f"user_email-{state}").decode("utf8")
|
user_email = redis_client.get(f"user_email-{state}").decode("utf8")
|
||||||
user_uuid = redis_client.raw_get(f"user_uuid-{state}").decode("utf8")
|
user_uuid = redis_client.get(f"user_uuid-{state}").decode("utf8")
|
||||||
invited_user_email_address = redis_client.raw_get(
|
invited_user_email_address = redis_client.get(
|
||||||
f"invited_user_email_address-{state}"
|
f"invited_user_email_address-{state}"
|
||||||
).decode("utf8")
|
).decode("utf8")
|
||||||
return invite_data, user_email, user_uuid, invited_user_email_address
|
return invite_data, user_email, user_uuid, invited_user_email_address
|
||||||
@@ -163,7 +163,7 @@ def set_up_your_profile():
|
|||||||
state = request.args.get("state")
|
state = request.args.get("state")
|
||||||
login_gov_error = request.args.get("error")
|
login_gov_error = request.args.get("error")
|
||||||
|
|
||||||
if redis_client.raw_get(f"invitedata-{state}") is None:
|
if redis_client.get(f"invitedata-{state}") is None:
|
||||||
access_token = sign_in._get_access_token(code, state)
|
access_token = sign_in._get_access_token(code, state)
|
||||||
debug_msg("Got the access token for login.gov")
|
debug_msg("Got the access token for login.gov")
|
||||||
user_email, user_uuid = sign_in._get_user_email_and_uuid(access_token)
|
user_email, user_uuid = sign_in._get_user_email_and_uuid(access_token)
|
||||||
@@ -195,7 +195,7 @@ def set_up_your_profile():
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
form.validate_on_submit()
|
form.validate_on_submit()
|
||||||
and redis_client.raw_get(f"invitedata-{state}") is not None
|
and redis_client.get(f"invitedata-{state}") is not None
|
||||||
):
|
):
|
||||||
invite_data, user_email, user_uuid, invited_user_email_address = (
|
invite_data, user_email, user_uuid, invited_user_email_address = (
|
||||||
get_invite_data_from_redis(state)
|
get_invite_data_from_redis(state)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ def activate_user(user_id):
|
|||||||
user = User.from_id(user_id)
|
user = User.from_id(user_id)
|
||||||
|
|
||||||
# TODO add org invites back in the new way
|
# TODO add org invites back in the new way
|
||||||
# organization_id = redis_client.raw_get(
|
# organization_id = redis_client.get(
|
||||||
# f"organization-invite-{user.email_address}"
|
# f"organization-invite-{user.email_address}"
|
||||||
# )
|
# )
|
||||||
# user_api_client.add_user_to_organization(
|
# user_api_client.add_user_to_organization(
|
||||||
|
|||||||
@@ -133,19 +133,13 @@ class RedisClient:
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def raw_set(self, key, value, ex=None, px=None, nx=False, xx=False):
|
|
||||||
self.redis_store.set(key, value, ex, px, nx, xx)
|
|
||||||
|
|
||||||
def set(
|
def set(
|
||||||
self, key, value, ex=None, px=None, nx=False, xx=False, raise_exception=False
|
self, key, value, ex=None, px=None, nx=False, xx=False, raise_exception=False
|
||||||
):
|
):
|
||||||
key = prepare_value(key)
|
key = prepare_value(key)
|
||||||
value = prepare_value(value)
|
value = prepare_value(value)
|
||||||
if self.active:
|
if self.active:
|
||||||
try:
|
self.redis_store.set(key, value, ex, px, nx, xx)
|
||||||
self.redis_store.set(key, value, ex, px, nx, xx)
|
|
||||||
except Exception as e:
|
|
||||||
self.__handle_exception(e, raise_exception, "set", key)
|
|
||||||
|
|
||||||
def incr(self, key, raise_exception=False):
|
def incr(self, key, raise_exception=False):
|
||||||
key = prepare_value(key)
|
key = prepare_value(key)
|
||||||
@@ -155,16 +149,10 @@ class RedisClient:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.__handle_exception(e, raise_exception, "incr", key)
|
self.__handle_exception(e, raise_exception, "incr", key)
|
||||||
|
|
||||||
def raw_get(self, key):
|
|
||||||
return self.redis_store.get(key)
|
|
||||||
|
|
||||||
def get(self, key, raise_exception=False):
|
def get(self, key, raise_exception=False):
|
||||||
key = prepare_value(key)
|
key = prepare_value(key)
|
||||||
if self.active:
|
if self.active:
|
||||||
try:
|
return self.redis_store.get(key)
|
||||||
return self.redis_store.get(key)
|
|
||||||
except Exception as e:
|
|
||||||
self.__handle_exception(e, raise_exception, "get", key)
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
113
poetry.lock
generated
113
poetry.lock
generated
@@ -85,6 +85,17 @@ charset-normalizer = ["charset-normalizer"]
|
|||||||
html5lib = ["html5lib"]
|
html5lib = ["html5lib"]
|
||||||
lxml = ["lxml"]
|
lxml = ["lxml"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bidict"
|
||||||
|
version = "0.23.1"
|
||||||
|
description = "The bidirectional mapping library for Python."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5"},
|
||||||
|
{file = "bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "black"
|
name = "black"
|
||||||
version = "24.4.2"
|
version = "24.4.2"
|
||||||
@@ -887,6 +898,24 @@ redis = ">=2.7.6"
|
|||||||
dev = ["coverage", "pre-commit", "pytest", "pytest-mock"]
|
dev = ["coverage", "pre-commit", "pytest", "pytest-mock"]
|
||||||
tests = ["coverage", "pytest", "pytest-mock"]
|
tests = ["coverage", "pytest", "pytest-mock"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flask-socketio"
|
||||||
|
version = "5.3.6"
|
||||||
|
description = "Socket.IO integration for Flask applications"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
files = [
|
||||||
|
{file = "Flask-SocketIO-5.3.6.tar.gz", hash = "sha256:bb8f9f9123ef47632f5ce57a33514b0c0023ec3696b2384457f0fcaa5b70501c"},
|
||||||
|
{file = "Flask_SocketIO-5.3.6-py3-none-any.whl", hash = "sha256:9e62d2131842878ae6bfdd7067dfc3be397c1f2b117ab1dc74e6fe74aad7a579"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
Flask = ">=0.9"
|
||||||
|
python-socketio = ">=5.0.2"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flask-talisman"
|
name = "flask-talisman"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -1049,6 +1078,17 @@ setproctitle = ["setproctitle"]
|
|||||||
testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"]
|
testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"]
|
||||||
tornado = ["tornado (>=0.2)"]
|
tornado = ["tornado (>=0.2)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h11"
|
||||||
|
version = "0.14.0"
|
||||||
|
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
|
||||||
|
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "html5lib"
|
name = "html5lib"
|
||||||
version = "1.1"
|
version = "1.1"
|
||||||
@@ -1641,6 +1681,7 @@ files = [
|
|||||||
{file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"},
|
{file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"},
|
||||||
{file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"},
|
{file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"},
|
||||||
{file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"},
|
{file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"},
|
||||||
|
{file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"},
|
||||||
{file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"},
|
{file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -2384,6 +2425,25 @@ files = [
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
cli = ["click (>=5.0)"]
|
cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-engineio"
|
||||||
|
version = "4.9.1"
|
||||||
|
description = "Engine.IO server and client for Python"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
files = [
|
||||||
|
{file = "python_engineio-4.9.1-py3-none-any.whl", hash = "sha256:f995e702b21f6b9ebde4e2000cd2ad0112ba0e5116ec8d22fe3515e76ba9dddd"},
|
||||||
|
{file = "python_engineio-4.9.1.tar.gz", hash = "sha256:7631cf5563086076611e494c643b3fa93dd3a854634b5488be0bba0ef9b99709"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
simple-websocket = ">=0.10.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
asyncio-client = ["aiohttp (>=3.4)"]
|
||||||
|
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
|
||||||
|
docs = ["sphinx"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-json-logger"
|
name = "python-json-logger"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
@@ -2412,6 +2472,26 @@ text-unidecode = ">=1.3"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
unidecode = ["Unidecode (>=1.1.1)"]
|
unidecode = ["Unidecode (>=1.1.1)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-socketio"
|
||||||
|
version = "5.11.2"
|
||||||
|
description = "Socket.IO server and client for Python"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "python-socketio-5.11.2.tar.gz", hash = "sha256:ae6a1de5c5209ca859dc574dccc8931c4be17ee003e74ce3b8d1306162bb4a37"},
|
||||||
|
{file = "python_socketio-5.11.2-py3-none-any.whl", hash = "sha256:b9f22a8ff762d7a6e123d16a43ddb1a27d50f07c3c88ea999334f2f89b0ad52b"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
bidict = ">=0.21.0"
|
||||||
|
python-engineio = ">=4.8.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
asyncio-client = ["aiohttp (>=3.4)"]
|
||||||
|
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
|
||||||
|
docs = ["sphinx"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2024.1"
|
version = "2024.1"
|
||||||
@@ -2766,6 +2846,23 @@ numpy = ">=1.14,<3"
|
|||||||
docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"]
|
docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"]
|
||||||
test = ["pytest", "pytest-cov"]
|
test = ["pytest", "pytest-cov"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simple-websocket"
|
||||||
|
version = "1.0.0"
|
||||||
|
description = "Simple WebSocket server and client for Python"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
files = [
|
||||||
|
{file = "simple-websocket-1.0.0.tar.gz", hash = "sha256:17d2c72f4a2bd85174a97e3e4c88b01c40c3f81b7b648b0cc3ce1305968928c8"},
|
||||||
|
{file = "simple_websocket-1.0.0-py3-none-any.whl", hash = "sha256:1d5bf585e415eaa2083e2bcf02a3ecf91f9712e7b3e6b9fa0b461ad04e0837bc"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
wsproto = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "six"
|
name = "six"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
@@ -2943,6 +3040,20 @@ MarkupSafe = ">=2.1.1"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
watchdog = ["watchdog (>=2.3)"]
|
watchdog = ["watchdog (>=2.3)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wsproto"
|
||||||
|
version = "1.2.0"
|
||||||
|
description = "WebSockets state-machine based protocol implementation"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7.0"
|
||||||
|
files = [
|
||||||
|
{file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"},
|
||||||
|
{file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
h11 = ">=0.9.0,<1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wtforms"
|
name = "wtforms"
|
||||||
version = "3.1.2"
|
version = "3.1.2"
|
||||||
@@ -3001,4 +3112,4 @@ files = [
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.12.2"
|
python-versions = "^3.12.2"
|
||||||
content-hash = "e96b87c048826ecb23d826c45b516aee60532cd2677a22332dc86fef498a411d"
|
content-hash = "ce5863177e0d58f7e4affdb2d7c4a23721a6eb3199183cd92874c0315c0d6afa"
|
||||||
|
|||||||
@@ -1893,26 +1893,22 @@ def app_with_socketio():
|
|||||||
(
|
(
|
||||||
SERVICE_ONE_ID,
|
SERVICE_ONE_ID,
|
||||||
{"start_date": "2024-01-01", "days": 7},
|
{"start_date": "2024-01-01", "days": 7},
|
||||||
{"service_id": SERVICE_ONE_ID, "start_date": "2024-01-01", "days": 7}
|
{"service_id": SERVICE_ONE_ID, "start_date": "2024-01-01", "days": 7},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
SERVICE_TWO_ID,
|
SERVICE_TWO_ID,
|
||||||
{"start_date": "2023-06-01", "days": 7},
|
{"start_date": "2023-06-01", "days": 7},
|
||||||
{"service_id": SERVICE_TWO_ID, "start_date": "2023-06-01", "days": 7}
|
{"service_id": SERVICE_TWO_ID, "start_date": "2023-06-01", "days": 7},
|
||||||
),
|
),
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
def test_fetch_daily_stats(
|
def test_fetch_daily_stats(
|
||||||
app_with_socketio, mocker,
|
app_with_socketio, mocker, service_id, date_range, expected_call_args
|
||||||
service_id,
|
|
||||||
date_range,
|
|
||||||
expected_call_args
|
|
||||||
):
|
):
|
||||||
app, socketio = app_with_socketio
|
app, socketio = app_with_socketio
|
||||||
|
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
"app.main.views.dashboard.get_stats_date_range",
|
"app.main.views.dashboard.get_stats_date_range", return_value=date_range
|
||||||
return_value=date_range
|
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_service_api = mocker.patch(
|
mock_service_api = mocker.patch(
|
||||||
@@ -1920,9 +1916,9 @@ def test_fetch_daily_stats(
|
|||||||
return_value={
|
return_value={
|
||||||
date_range["start_date"]: {
|
date_range["start_date"]: {
|
||||||
"email": {"delivered": 0, "failure": 0, "requested": 0},
|
"email": {"delivered": 0, "failure": 0, "requested": 0},
|
||||||
"sms": {"delivered": 0, "failure": 1, "requested": 1}
|
"sms": {"delivered": 0, "failure": 1, "requested": 1},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
client = SocketIOTestClient(app, socketio)
|
client = SocketIOTestClient(app, socketio)
|
||||||
@@ -1930,22 +1926,22 @@ def test_fetch_daily_stats(
|
|||||||
connected = client.is_connected()
|
connected = client.is_connected()
|
||||||
assert connected, "Client should be connected"
|
assert connected, "Client should be connected"
|
||||||
|
|
||||||
client.emit('fetch_daily_stats', service_id)
|
client.emit("fetch_daily_stats", service_id)
|
||||||
|
|
||||||
received = client.get_received()
|
received = client.get_received()
|
||||||
assert received, "Should receive a response message"
|
assert received, "Should receive a response message"
|
||||||
assert received[0]['name'] == 'daily_stats_update'
|
assert received[0]["name"] == "daily_stats_update"
|
||||||
assert received[0]['args'][0] == {
|
assert received[0]["args"][0] == {
|
||||||
date_range["start_date"]: {
|
date_range["start_date"]: {
|
||||||
"email": {"delivered": 0, "failure": 0, "requested": 0},
|
"email": {"delivered": 0, "failure": 0, "requested": 0},
|
||||||
"sms": {"delivered": 0, "failure": 1, "requested": 1}
|
"sms": {"delivered": 0, "failure": 1, "requested": 1},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mock_service_api.assert_called_once_with(
|
mock_service_api.assert_called_once_with(
|
||||||
service_id,
|
service_id,
|
||||||
start_date=expected_call_args["start_date"],
|
start_date=expected_call_args["start_date"],
|
||||||
days=expected_call_args["days"]
|
days=expected_call_args["days"],
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
client.disconnect()
|
client.disconnect()
|
||||||
|
|||||||
@@ -64,8 +64,6 @@ def test_should_not_raise_exception_if_raise_set_to_false(
|
|||||||
):
|
):
|
||||||
mock_logger = mocker.patch("flask.Flask.logger")
|
mock_logger = mocker.patch("flask.Flask.logger")
|
||||||
|
|
||||||
assert failing_redis_client.get("get_key") is None
|
|
||||||
assert failing_redis_client.set("set_key", "set_value") is None
|
|
||||||
assert failing_redis_client.incr("incr_key") is None
|
assert failing_redis_client.incr("incr_key") is None
|
||||||
assert failing_redis_client.exceeded_rate_limit("rate_limit_key", 100, 100) is False
|
assert failing_redis_client.exceeded_rate_limit("rate_limit_key", 100, 100) is False
|
||||||
assert failing_redis_client.delete("delete_key") is None
|
assert failing_redis_client.delete("delete_key") is None
|
||||||
@@ -73,8 +71,6 @@ def test_should_not_raise_exception_if_raise_set_to_false(
|
|||||||
assert failing_redis_client.delete_by_pattern("pattern") == 0
|
assert failing_redis_client.delete_by_pattern("pattern") == 0
|
||||||
|
|
||||||
assert mock_logger.mock_calls == [
|
assert mock_logger.mock_calls == [
|
||||||
call.exception("Redis error performing get on get_key"),
|
|
||||||
call.exception("Redis error performing set on set_key"),
|
|
||||||
call.exception("Redis error performing incr on incr_key"),
|
call.exception("Redis error performing incr on incr_key"),
|
||||||
call.exception("Redis error performing rate-limit-pipeline on rate_limit_key"),
|
call.exception("Redis error performing rate-limit-pipeline on rate_limit_key"),
|
||||||
call.exception("Redis error performing delete on delete_key"),
|
call.exception("Redis error performing delete on delete_key"),
|
||||||
|
|||||||
Reference in New Issue
Block a user