Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions charon/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import logging
import uuid
import time

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -82,13 +83,33 @@ def invalidate_paths(
The default value is 3000 which is the maximum number in official doc:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#InvalidationLimits
"""
logger.debug("[CloudFront] Creating invalidation for paths: %s", paths)
real_paths = [paths]
# Split paths into batches by batch_size
if batch_size:
real_paths = [paths[i:i + batch_size] for i in range(0, len(paths), batch_size)]
results = []
current_invalidation = {}
for batch_paths in real_paths:
while (current_invalidation and
'InProgress' == current_invalidation.get('Status', '')):
time.sleep(5)
try:
result = self.check_invalidation(distr_id, current_invalidation.get('Id'))
if result:
current_invalidation = {
'Id': result.get('Id', None),
'Status': result.get('Status', None)
}
logger.debug("Check invalidation: %s", current_invalidation)
except Exception as err:
logger.warning(
"[CloudFront] Error occurred while checking invalidation status during"
" creating invalidation, invalidation: %s, error: %s",
current_invalidation, err
)
break
if current_invalidation:
results.append(current_invalidation)
caller_ref = str(uuid.uuid4())
logger.debug(
"Processing invalidation for batch with ref %s, size: %s",
Expand All @@ -107,15 +128,17 @@ def invalidate_paths(
)
if response:
invalidation = response.get('Invalidation', {})
results.append({
current_invalidation = {
'Id': invalidation.get('Id', None),
'Status': invalidation.get('Status', None)
})
}
except Exception as err:
logger.error(
"[CloudFront] Error occurred while creating invalidation"
" for paths %s, error: %s", batch_paths, err
)
if current_invalidation:
results.append(current_invalidation)
return results

def check_invalidation(self, distr_id: str, invalidation_id: str) -> dict:
Expand Down
11 changes: 10 additions & 1 deletion tests/test_cfclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,23 @@ def test_get_distribution_id(self):
dist_id = self.cf_client.get_dist_id_by_domain("notexists.redhat.com")
self.assertIsNone(dist_id)

def test_invalidate_paths(self):
def test_invalidate_paths_single(self):
dist_id = self.cf_client.get_dist_id_by_domain("maven.repository.redhat.com")
result = self.cf_client.invalidate_paths(dist_id, ["/*"])
self.assertEqual(len(result), 1)
self.assertTrue(result[0]['Id'])
self.assertEqual('completed', str.lower(result[0]['Status']))
status = self.cf_client.invalidate_paths("noexists_id", ["/*"])
self.assertFalse(status)

def test_invalidate_paths_multi(self):
dist_id = self.cf_client.get_dist_id_by_domain("maven.repository.redhat.com")
result = self.cf_client.invalidate_paths(dist_id, ["/1", "/2", "/3"], batch_size=1)
self.assertEqual(len(result), 3)
for r in result:
self.assertTrue(r['Id'])
self.assertEqual('completed', str.lower(r['Status']))

@pytest.mark.skip(reason="""
Because current moto 5.0.3 has not implemented the get_invalidation(),
this test will fail. Will enable it when the it is implemented in future moto
Expand Down