Skip to content

Commit

Permalink
v1.7.0 - Improve Memory Management for LDV Full Recalculations (#636)
Browse files Browse the repository at this point in the history
* Actual fixes for #615 - this time with 100% better memory management! This involves a cutover to Database.Cursor as well as a DataWeave script
* Fixes #638 by addressing a classic DST issue in RollupDateLiteral. Slight cleanup of RollupFinalizer and RollupParentResetProcessor
  • Loading branch information
jamessimone authored Nov 5, 2024
1 parent c67a403 commit 63ed889
Show file tree
Hide file tree
Showing 65 changed files with 2,102 additions and 501 deletions.
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,13 @@ As well, don't miss [the Wiki](../../wiki), which includes even more info for co

## Deployment & Setup

<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfSEAA0">
<img alt="Deploy to Salesforce"
src="./media/deploy-package-to-prod.png">
<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfTvAAK">
<img alt="Deploy to Salesforce" src="./media/deploy-package-to-prod.png">
</a>

<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfSEAA0">
<img alt="Deploy to Salesforce Sandbox"
src="./media/deploy-package-to-sandbox.png">
<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008OfTvAAK">
<img alt="Deploy to Salesforce Sandbox" src="./media/deploy-package-to-sandbox.png">
</a>

<br/>
<br/>

Expand Down
2 changes: 1 addition & 1 deletion extra-tests/classes/InvocableDrivenTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private class InvocableDrivenTests {

@IsTest
static void shouldWorkWhenBatchedFromRefresh() {
Rollup.defaultControl = new RollupControl__mdt(MaxLookupRowsBeforeBatching__c = 1, IsRollupLoggingEnabled__c = true);
Rollup.defaultControl = new RollupControl__mdt(MaxLookupRowsBeforeBatching__c = 1);
// Driven by extra-tests/flows/Rollup_Integration_Multiple_Deferred_Case_Rollups.flow-meta.xml
Account acc = [SELECT Id FROM Account];
// Description and Subject both are referenced in the Flow
Expand Down
2 changes: 1 addition & 1 deletion extra-tests/classes/RollupCalcItemSorterTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private class RollupCalcItemSorterTests {
new Opportunity(StageName = 'One')
};

itemsToSort.sort(new RollupCalcItemSorter(new List<String>{ Opportunity.Name.getDescribe().getName(), Opportunity.StageName.getDescribe().getName() }));
itemsToSort.sort(new RollupCalcItemSorter(new List<String>{ Opportunity.Name.toString(), Opportunity.StageName.toString() }));

System.assertEquals(null, itemsToSort.get(0).StageName);
System.assertEquals('One', itemsToSort.get(1).StageName);
Expand Down
64 changes: 53 additions & 11 deletions extra-tests/classes/RollupCalculatorTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,8 @@ private class RollupCalculatorTests {
Rollup__mdt metadata = configureOrderByMetadata(new Rollup__mdt(), 'Name');
RollupCalculator calc = getCalculator(0, Rollup.Op.FIRST, Opportunity.Amount, Account.AnnualRevenue, metadata, lookupKey, Account.Id);
RollupState outerState = new RollupState();
RollupState.SObjectInfo info = new RollupState.SObjectInfo();
RollupState.SObjectInfo info = (RollupState.SObjectInfo) outerState.getState(lookupKey, metadata, RollupState.SObjectInfo.class);
info.setItem(new Opportunity(Name = 'a', Amount = 3));
outerState.setState(lookupKey, info);
calc.setState(outerState);

calc.performRollup(
Expand Down Expand Up @@ -724,17 +723,17 @@ private class RollupCalculatorTests {
static void mostRespectsStateValues() {
Account acc = [SELECT Id FROM Account];
Integer priorVal = 50;
RollupState.MostInfo info = new RollupState.MostInfo();
info.setLargestPointCounter(2);
RollupState outerState = new RollupState();
outerState.setState(acc.Id, info);
Rollup__mdt metaKey = new Rollup__mdt();
RollupState.MostInfo info = (RollupState.MostInfo) outerState.getState(acc.Id, metaKey, RollupState.MostInfo.class);
info.setValues(2, priorVal);

RollupCalculator calc = getCalculator(
priorVal,
Rollup.Op.MOST,
ContactPointAddress.PreferenceRank,
Account.AnnualRevenue,
new Rollup__mdt(),
metaKey,
acc.Id,
ContactPointAddress.ParentId
);
Expand Down Expand Up @@ -886,6 +885,49 @@ private class RollupCalculatorTests {
System.assertEquals(null, calc.getReturnValue());
}

@IsTest
static void correctlyAppliesStatefulSums() {
Rollup__mdt metaKey = new Rollup__mdt();
String accountKey = '0011g00003VDGbF002';
Integer value = 1;
RollupCalculator calc = getCalculator(null, Rollup.Op.SUM, Opportunity.Amount, Account.AnnualRevenue, metaKey, accountKey, Opportunity.AccountId);
RollupState outerState = new RollupState();
RollupState.GenericInfo info = (RollupState.GenericInfo) outerState.getState(accountKey, metaKey, RollupState.GenericInfo.class);
info.value = value;
calc.setState(outerState);

Opportunity one = new Opportunity(Id = '0066g00003VDGbF001', Amount = 5, AccountId = accountKey);
Opportunity two = new Opportunity(Id = '0066g00003VDGbF002', Amount = 5, AccountId = accountKey);

calc.performRollup(new List<Opportunity>{ one, two }, new Map<Id, SObject>());

System.assertEquals(one.Amount + two.Amount + value, calc.getReturnValue());
System.assertEquals(one.Amount + two.Amount + value, info.value);
}

@IsTest
static void doesNotResetParentValueWhenOnlyStatefulSumMatches() {
Rollup__mdt metaKey = new Rollup__mdt();
String accountKey = '0011g00003VDGbF002';
Integer value = 1;
RollupCalculator calc = getCalculator(null, Rollup.Op.SUM, Opportunity.Amount, Account.AnnualRevenue, metaKey, accountKey, Opportunity.AccountId);
RollupState outerState = new RollupState();
RollupState.GenericInfo info = (RollupState.GenericInfo) outerState.getState(accountKey, metaKey, RollupState.GenericInfo.class);
info.value = value;

calc.setState(outerState);
calc.setFullRecalc(true);
calc.setEvaluator(new RollupEvaluator.WhereFieldEvaluator('Amount = 0', Opportunity.SObjectType));

Opportunity one = new Opportunity(Id = '0066g00003VDGbF001', Amount = 5, AccountId = accountKey);
Opportunity two = new Opportunity(Id = '0066g00003VDGbF002', Amount = 5, AccountId = accountKey);

calc.performRollup(new List<Opportunity>{ one, two }, new Map<Id, SObject>());

System.assertEquals(value, calc.getReturnValue());
System.assertEquals(value, info.value);
}

// CONCAT tests

@IsTest
Expand Down Expand Up @@ -2177,23 +2219,23 @@ private class RollupCalculatorTests {

@IsTest
static void averageFactorsInBatchState() {
Rollup__mdt meta = new Rollup__mdt();
String lookupKey = RollupTestUtils.createId(Account.SObjectType);
RollupState.AverageInfo state = new RollupState.AverageInfo();
RollupState outerState = new RollupState();
RollupState.AverageInfo state = (RollupState.AverageInfo) outerState.getState(lookupKey, meta, RollupState.AverageInfo.class);
state.denominator = 15;
state.numerator = 75;
RollupCalculator calc = getCalculator(
state.numerator / state.denominator,
Rollup.Op.AVERAGE,
Opportunity.Amount,
Account.Description,
new Rollup__mdt(),
meta,
lookupKey,
Account.Id
);

RollupState outerState = new RollupState();
outerState.setState(lookupKey, state);
calc.setState(outerState);

calc.performRollup(
new List<SObject>{
new Opportunity(Amount = 15),
Expand Down
2 changes: 1 addition & 1 deletion extra-tests/classes/RollupCurrencyInfoTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ private class RollupCurrencyInfoTests {
);
List<OpportunityLineItem> olis = new List<OpportunityLineItem>{ oliToUpdate };

RollupCurrencyInfo.overrideDatedMultiCurrency(olis.getSObjectType().getDescribe().getName(), new List<String>{ 'Opportunity', 'CloseDate' });
RollupCurrencyInfo.overrideDatedMultiCurrency(olis.getSObjectType().toString(), new List<String>{ 'Opportunity', 'CloseDate' });
RollupCurrencyInfo.transform(olis, OpportunityLineItem.TotalPrice, eurPeriodOne.IsoCode, new List<RollupOrderBy__mdt>());

OpportunityLineItem oli = (OpportunityLineItem) RollupCurrencyInfo.getCalcItem(oliToUpdate, eurPeriodOne.IsoCode);
Expand Down
2 changes: 1 addition & 1 deletion extra-tests/classes/RollupEvaluatorTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,7 @@ private class RollupEvaluatorTests {

@IsTest
static void pascalCaseForFieldNamesIsNotRequired() {
String poorlyCasedFieldName = Opportunity.IsClosed.getDescribe().getName().toLowerCase();
String poorlyCasedFieldName = Opportunity.IsClosed.toString().toLowerCase();

Opportunity isClosedFalse = (Opportunity) JSON.deserialize('{ "IsClosed": false }', Opportunity.class);
OpportunityLineItem target = new OpportunityLineItem(Opportunity = isClosedFalse);
Expand Down
26 changes: 19 additions & 7 deletions extra-tests/classes/RollupFinalizerTests.cls
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
@IsTest
private class RollupFinalizerTests {
@TestSetup
static void setup() {
upsert new RollupSettings__c(IsEnabled__c = true);
insert new Account(Name = RollupFinalizerTests.class.getName());
public class ExampleFinalizerContext implements System.FinalizerContext {
public Id getAsyncApexJobId() {
return RollupTestUtils.createId(AsyncApexJob.SObjectType);
}

public String getRequestId() {
return System.Request.getCurrent().getRequestId();
}

public ParentJobResult getResult() {
return ParentJobResult.UNHANDLED_EXCEPTION;
}

public Exception getException() {
return new DmlException();
}
}

@IsTest
static void shouldGracefullyLogUnhandledException() {
RollupFinalizer.testResult = ParentJobResult.UNHANDLED_EXCEPTION;
System.FinalizerContext fc = new ExampleFinalizerContext();

Test.startTest();
new RollupFinalizer().execute(null);
new RollupFinalizer().execute(fc);
Test.stopTest();

System.assertEquals(true, RollupFinalizer.wasCalled);
System.assertEquals(true, RollupFinalizer.wasExceptionLogged);
}
}
4 changes: 2 additions & 2 deletions extra-tests/classes/RollupFlowFullRecalcTests.cls
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ private class RollupFlowFullRecalcTests {
List<Rollup.FlowInput> flowInputs = RollupTestUtils.prepareFlowTest(apps, 'REFRESH', 'SUM');
flowInputs[0].ultimateParentLookup = 'ParentId';
flowInputs[0].rollupToUltimateParent = true;
flowInputs[0].lookupFieldOnCalcItem = Application__c.ParentApplication__c.getDescribe().getName();
flowInputs[0].rollupFieldOnCalcItem = Application__c.Engagement_Score__c.getDescribe().getName();
flowInputs[0].lookupFieldOnCalcItem = Application__c.ParentApplication__c.toString();
flowInputs[0].rollupFieldOnCalcItem = Application__c.Engagement_Score__c.toString();
flowInputs[0].grandparentRelationshipFieldPath = RollupTestUtils.getRelationshipPath(
new List<Schema.SObjectField>{ Application__c.ParentApplication__c, ParentApplication__c.Account__c, Account.AnnualRevenue }
);
Expand Down
Loading

0 comments on commit 63ed889

Please sign in to comment.