Cache provider lookups for 2 seconds

For every email or text message we send we have to work out which
provider to send it with. Every time we do this we go and load the list
of providers from the database.

For emails, the result will always be the same.

For text messages the result is randomly chosen to balance the load
between the providers.

For international text messages the result is always the same (we only
have one international text message provider).

This commit adds an in-memory cache with a 2 second TTL so that we’re
not fetching the providers from the database every time, which should
speed things up a bit.

This does mean that, for text messages, the random choice will ‘stick’
for two seconds on each instance, before being re-chosen. I think this
is  OK because it will even out to the same distribution over time.

I really don’t like having to clear the cache in the tests, so would
welcome suggestions on a better way of doing this…
This commit is contained in:
Chris Hill-Scott
2020-12-23 15:33:27 +00:00
parent a2bb775b6f
commit 51b7192750
2 changed files with 26 additions and 1 deletions

View File

@@ -47,6 +47,23 @@ def test_provider_to_use_should_return_random_provider(mocker, notify_db_session
assert ret.get_name() == 'mmg'
def test_provider_to_use_should_cache_repeated_calls(mocker, notify_db_session):
mock_choices = mocker.patch(
'app.delivery.send_to_providers.random.choices',
wraps=send_to_providers.random.choices,
)
send_to_providers.provider_cache.clear()
results = [
send_to_providers.provider_to_use('sms', international=False)
for _ in range(10)
]
assert all(result == results[0] for result in results)
assert len(mock_choices.call_args_list) == 1
def test_provider_to_use_should_only_return_mmg_for_international(mocker, notify_db_session):
mmg = get_provider_details_by_identifier('mmg')
mock_choices = mocker.patch('app.delivery.send_to_providers.random.choices', return_value=[mmg])
@@ -73,6 +90,8 @@ def test_provider_to_use_raises_if_no_active_providers(mocker, restore_provider_
mmg = get_provider_details_by_identifier('mmg')
mmg.active = False
send_to_providers.provider_cache.clear()
with pytest.raises(Exception):
send_to_providers.provider_to_use('sms', international=True)
@@ -624,6 +643,7 @@ def test_should_send_sms_to_international_providers(
international=True,
reply_to_text=sample_template.service.get_default_sms_sender()
)
send_to_providers.provider_cache.clear()
send_to_providers.send_sms_to_provider(
notification_uk
)
@@ -674,6 +694,7 @@ def test_should_handle_sms_sender_and_prefix_message(
template = create_template(service, content='bar')
notification = create_notification(template, reply_to_text=sms_sender)
send_to_providers.provider_cache.clear()
send_to_providers.send_sms_to_provider(notification)
mmg_client.send_sms.assert_called_once_with(