mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-15 01:32:20 -05:00
Correct the daily limits cache.
Last year we had an issue with the daily limit cache and the query that was populating it. As a result we have not been checking the daily limit properly. This PR should correct all that. The daily limit cache is not being incremented in app.notifications.process_notifications.persist_notification, this method is and should always be the only method used to create a notification. We increment the daily limit cache is redis is enabled (and it is always enabled for production) and the key type for the notification is team or normal. We check if the daily limit is exceed in many places: - app.celery.tasks.process_job - app.v2.notifications.post_notifications.post_notification - app.v2.notifications.post_notifications.post_precompiled_letter_notification - app.service.send_notification.send_one_off_notification - app.service.send_notification.send_pdf_letter_notification If the daily limits cache is not found, set the cache to 0 with an expiry of 24 hours. The daily limit cache key is service_id-yyy-mm-dd-count, so each day a new cache is created. The best thing about this PR is that the app.service_dao.fetch_todays_total_message_count query has been removed. This query was not performant and had been wrong for ages.
This commit is contained in:
@@ -14,7 +14,6 @@ from notifications_utils.recipients import (
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
from app import redis_store
|
||||
from app.dao import services_dao
|
||||
from app.dao.service_email_reply_to_dao import dao_get_reply_to_by_id
|
||||
from app.dao.service_letter_contact_dao import dao_get_letter_contact_by_id
|
||||
from app.dao.service_sms_sender_dao import dao_get_service_sms_senders_by_id
|
||||
@@ -63,8 +62,9 @@ def check_service_over_daily_message_limit(key_type, service):
|
||||
cache_key = daily_limit_cache_key(service.id)
|
||||
service_stats = redis_store.get(cache_key)
|
||||
if not service_stats:
|
||||
service_stats = services_dao.fetch_todays_total_message_count(service.id)
|
||||
redis_store.set(cache_key, service_stats, ex=3600)
|
||||
# first message of the day, set the cache to 0 and the expiry to 24 hours
|
||||
service_stats = 0
|
||||
redis_store.set(cache_key, service_stats, ex=86400)
|
||||
if int(service_stats) >= service.message_limit:
|
||||
current_app.logger.info(
|
||||
"service {} has been rate limited for daily use sent {} limit {}".format(
|
||||
@@ -73,10 +73,24 @@ def check_service_over_daily_message_limit(key_type, service):
|
||||
raise TooManyRequestsError(service.message_limit)
|
||||
|
||||
|
||||
def get_service_daily_limit_cache_value(key_type, service):
|
||||
if key_type != KEY_TYPE_TEST and current_app.config['REDIS_ENABLED']:
|
||||
cache_key = daily_limit_cache_key(service.id)
|
||||
service_stats = redis_store.get(cache_key)
|
||||
if not service_stats:
|
||||
# first message of the day, set the cache to 0 and the expiry to 24 hours
|
||||
service_stats = 0
|
||||
redis_store.set(cache_key, service_stats, ex=86400)
|
||||
return 0
|
||||
else:
|
||||
return int(service_stats)
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def check_rate_limiting(service, api_key):
|
||||
check_service_over_api_rate_limit(service, api_key)
|
||||
# Reduce queries to the notifications table
|
||||
# check_service_over_daily_message_limit(api_key.key_type, service)
|
||||
check_service_over_daily_message_limit(api_key.key_type, service)
|
||||
|
||||
|
||||
def check_template_is_for_notification_type(notification_type, template_type):
|
||||
|
||||
Reference in New Issue
Block a user