Skip to content

Conversation

@tathagat2241
Copy link
Contributor

Changes

  • Version Limit Enforcement: Added #enforceVersionLimit() method to ConfigurationCollection that automatically cleans up old versions on every save() operation
  • Asynchronous Execution: Cleanup runs via setImmediate() to avoid blocking the main save operation
  • Batch Deletion: Deletes old versions in batches of 25 (DynamoDB batch write limit) for optimal performance
  • Graceful Error Handling: Cleanup failures are logged but don't affect the main save operation
  • Comprehensive Testing: Added 8 new test cases covering all cleanup scenarios, edge cases, and error handling

Technical Details

  • Trigger: Cleanup runs automatically after each configuration create() (save)
  • Target: Keeps newest 500 versions, deletes older versions beyond this limit
  • Safety: Only affects Configuration entities (ElectroDB entity isolation via GSI)
  • Performance: Uses DynamoDB batch operations and parallel deletion with Promise.all()

Please ensure your pull request adheres to the following guidelines:

  • make sure to link the related issues in this description
  • when merging / squashing, make sure the fixed issue references are visible in the commits, for easy compilation of release notes

Related Issues

https://jira.corp.adobe.com/browse/SITES-37650

Thanks for contributing!

@github-actions
Copy link

This PR will trigger a minor release when merged.

this.log.info(`Enforcing configuration version limit: deleting ${deleteCount} old versions (current: ${allConfigs.length}, target: ${MAX_VERSIONS})`);

// Delete in batches (DynamoDB batch write limit is 25)
for (let i = 0; i < versionsToDelete.length; i += BATCH_SIZE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need batching.
I mean before pushing it to production , we must clean up manually (DB script) to reach to base line.
I don't want to do first clean up by service it self.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have create a new script to delete the versions before deploying to code. with this we will only keep 500 version and then whenever a new version is saved then it will check is the number is greater that 500 then it will remove the oldest version

const ids = batch.map((config) => config.getId());

// eslint-disable-next-line no-await-in-loop
await this.removeByIds(ids);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't we leave it async ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've simplified the implementation to remove batching since we'll typically only delete 1-2 versions in normal operation. The new code eliminates the loop entirely, so the eslint disable is no longer needed. The cleanup now does a single removeByIds call with all IDs at once."

@ravverma
Copy link
Contributor

@tathagat2241
I do not see , 4 week old configs considered..
are you suggesting to Keep only latest 500 versions ?

@tathagat2241
Copy link
Contributor Author

@ravverma, Yes, we will not be doing it for 4 weeks reason being there could be a instance that during 4 weeks only a few versions are created so it will default to keep 100 version, which I feel is a pretty low number. During the event like Adobe summit we do onboard a lot of new sites and during times like these just keeping 100 versions would not be safe.

So, decided to keep it simple and always store 500 version at every instance

});

// Verify Configuration entity is available
if (!dataAccess || !dataAccess.Configuration) {

Check notice

Code scanning / CodeQL

Unneeded defensive code Note

This guard always evaluates to false.

Copilot Autofix

AI 1 day ago

To fix the problem, remove the unneeded defensive check for !dataAccess in the conditional on line 73. Only the !dataAccess.Configuration check should remain, as that's the relevant error case. Specifically, change the code from:

if (!dataAccess || !dataAccess.Configuration) {

to:

if (!dataAccess.Configuration) {

No changes are needed elsewhere in the file, and no new imports or definitions are required.


Suggested changeset 1
packages/spacecat-shared-data-access/scripts/cleanup-old-configuration-versions.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/spacecat-shared-data-access/scripts/cleanup-old-configuration-versions.js b/packages/spacecat-shared-data-access/scripts/cleanup-old-configuration-versions.js
--- a/packages/spacecat-shared-data-access/scripts/cleanup-old-configuration-versions.js
+++ b/packages/spacecat-shared-data-access/scripts/cleanup-old-configuration-versions.js
@@ -70,7 +70,7 @@
     });
 
     // Verify Configuration entity is available
-    if (!dataAccess || !dataAccess.Configuration) {
+    if (!dataAccess.Configuration) {
       console.error('ERROR: Configuration entity is not available');
       console.error('   Troubleshooting:');
       console.error('   1. Ensure DYNAMO_TABLE_NAME is set correctly');
EOF
@@ -70,7 +70,7 @@
});

// Verify Configuration entity is available
if (!dataAccess || !dataAccess.Configuration) {
if (!dataAccess.Configuration) {
console.error('ERROR: Configuration entity is not available');
console.error(' Troubleshooting:');
console.error(' 1. Ensure DYNAMO_TABLE_NAME is set correctly');
Copilot is powered by AI and may make mistakes. Always verify output.
@tathagat2241 tathagat2241 deleted the feature/config-version-limit branch December 2, 2025 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants