From 0d874828e42f45ca0679aaa02dd89e3386f0c022 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 23 Jan 2025 13:28:26 -0800 Subject: [PATCH] fix total message limit so it works --- app/celery/provider_tasks.py | 4 +++ app/celery/tasks.py | 2 +- app/delivery/send_to_providers.py | 11 ++++++-- app/notifications/validators.py | 27 +++++++------------ .../0414_change_total_message_limit.py | 8 +++--- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/app/celery/provider_tasks.py b/app/celery/provider_tasks.py index 3bdd2d9c0..a3ed1f9ef 100644 --- a/app/celery/provider_tasks.py +++ b/app/celery/provider_tasks.py @@ -14,6 +14,7 @@ from app.delivery import send_to_providers from app.enums import NotificationStatus from app.exceptions import NotificationTechnicalFailureException +from notifications_utils.clients.redis import total_limit_cache_key @notify_celery.task( @@ -41,6 +42,9 @@ def deliver_sms(self, notification_id): # Code branches off to send_to_providers.py send_to_providers.send_sms_to_provider(notification) + cache_key = total_limit_cache_key(notification.service_id) + redis_store.incr(cache_key) + except Exception as e: update_notification_status_by_id( notification_id, diff --git a/app/celery/tasks.py b/app/celery/tasks.py index 6fea63e1b..8b3d9a353 100644 --- a/app/celery/tasks.py +++ b/app/celery/tasks.py @@ -166,7 +166,7 @@ def process_row(row, template, job, service, sender_id=None): # Assuming the limit is annual, is it calendar year, fiscal year, MOU year? # Do we need a command to run to clear the redis value, or should it happen automatically? def __total_sending_limits_for_job_exceeded(service, job, job_id): - + print(hilite("ENTER __total_sending_limits_for_job_exceeded")) try: total_sent = check_service_over_total_message_limit(KeyType.NORMAL, service) if total_sent + job.notification_count > service.total_message_limit: diff --git a/app/delivery/send_to_providers.py b/app/delivery/send_to_providers.py index e41062b41..6d9961ab6 100644 --- a/app/delivery/send_to_providers.py +++ b/app/delivery/send_to_providers.py @@ -26,6 +26,7 @@ from app.exceptions import NotificationTechnicalFailureException from app.serialised_models import SerialisedService, SerialisedTemplate from app.utils import hilite, utc_now +from notifications_utils.clients.redis import total_limit_cache_key from notifications_utils.template import ( HTMLEmailTemplate, PlainTextEmailTemplate, @@ -118,8 +119,10 @@ def send_sms_to_provider(notification): } db.session.close() # no commit needed as no changes to objects have been made above + message_id = provider.send_sms(**send_sms_kwargs) - current_app.logger.info(f"got message_id {message_id}") + + update_notification_message_id(notification.id, message_id) except Exception as e: n = notification @@ -132,10 +135,14 @@ def send_sms_to_provider(notification): else: # Here we map the job_id and row number to the aws message_id n = notification - msg = f"Send to aws for job_id {n.job_id} row_number {n.job_row_number} message_id {message_id}" + msg = f"Send to AWS!!! for job_id {n.job_id} row_number {n.job_row_number} message_id {message_id}" current_app.logger.info(hilite(msg)) notification.billable_units = template.fragment_count + current_app.logger.info("GOING TO UPDATE NOTI TO SENDING") update_notification_to_sending(notification, provider) + + cache_key = total_limit_cache_key(service.id) + redis_store.incr(cache_key) return message_id diff --git a/app/notifications/validators.py b/app/notifications/validators.py index 51c77b577..da4b9b290 100644 --- a/app/notifications/validators.py +++ b/app/notifications/validators.py @@ -11,7 +11,7 @@ from app.notifications.process_notifications import create_content_for_notification from app.serialised_models import SerialisedTemplate from app.service.utils import service_allowed_to_send_to -from app.utils import get_public_notify_type_text +from app.utils import get_public_notify_type_text, hilite from notifications_utils import SMS_CHAR_COUNT_LIMIT from notifications_utils.clients.redis import ( rate_limit_cache_key, @@ -24,26 +24,13 @@ ) -def check_service_over_api_rate_limit(service, api_key): - if ( - current_app.config["API_RATE_LIMIT_ENABLED"] - and current_app.config["REDIS_ENABLED"] - ): - cache_key = rate_limit_cache_key(service.id, api_key.key_type) - rate_limit = service.rate_limit - interval = 60 - if redis_store.exceeded_rate_limit(cache_key, rate_limit, interval): - current_app.logger.info( - "service {} has been rate limited for throughput".format(service.id) - ) - raise RateLimitError(rate_limit, interval, api_key.key_type) - - def check_service_over_total_message_limit(key_type, service): + print(hilite("ENTER check_service_over_total_message_limit")) if key_type == KeyType.TEST or not current_app.config["REDIS_ENABLED"]: return 0 cache_key = total_limit_cache_key(service.id) + print(hilite(f"CACHE_KEY = {cache_key}")) service_stats = redis_store.get(cache_key) # Originally this was a daily limit check. It is now a free-tier limit check. @@ -53,17 +40,23 @@ def check_service_over_total_message_limit(key_type, service): # TODO # setting expiration to one year for now on the assume that the free tier # limit resets annually. + + # add column for actual charges to notifications and notifification_history table + # add service api to return total_message_limit and actual number of messages for service if service_stats is None: service_stats = 0 redis_store.set(cache_key, service_stats, ex=365*24*60*60) return service_stats - if int(service_stats) >= service.total_message_limit: + if int(service_stats) >= 5: + #if int(service_stats) >= service.total_message_limit: current_app.logger.warning( "service {} has been rate limited for total use sent {} limit {}".format( service.id, int(service_stats), service.total_message_limit ) ) raise TotalRequestsError(service.total_message_limit) + else: + print(hilite(f"TOTAL MESSAGE LIMIT {service.total_message_limit} CURRENT {service_stats}")) return int(service_stats) diff --git a/migrations/versions/0414_change_total_message_limit.py b/migrations/versions/0414_change_total_message_limit.py index 1ee9adb08..f4cb775d0 100644 --- a/migrations/versions/0414_change_total_message_limit.py +++ b/migrations/versions/0414_change_total_message_limit.py @@ -14,12 +14,10 @@ def upgrade(): - """ - This limit is only used - """ - op.execute("UPDATE services set total_message_limit=100000") + # TODO This needs updating when the agreement model is ready. We only want free tier at 100k + op.execute("UPDATE services set total_message_limit=100000 where total_message_limit=250000") def downgrade(): - op.execute("UPDATE services set total_message_limit=250000") + op.execute("UPDATE services set total_message_limit=250000 where total_message_limit=100000")