Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.7.0 - Improve Memory Management for LDV Full Recalculations #636

Merged
merged 26 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6cab6e6
Fixes #619 by more carefully handling parentRecordIdForEmptyChildrenC…
jamessimone Sep 5, 2024
b4fefde
Fixes #615 by reducing the ongoing heap usage dedicated to subsequent…
jamessimone Sep 13, 2024
6ddc83f
Adds dataweave script to more performantly deserialize RollupState - …
jamessimone Sep 19, 2024
c2615d2
Cleaning up RollupState and tests
jamessimone Sep 20, 2024
8f444db
Stamping progress on RollupState endeavor
jamessimone Sep 25, 2024
09415aa
Adding some comments for @jongpie
jamessimone Oct 14, 2024
877e8bf
More state work plus cutover to using Database.Cursor
jamessimone Oct 17, 2024
4afa363
Making progress but only with single state.Body0__c field at the moment
jamessimone Oct 18, 2024
a7965f4
Partial cleanup now that everything is quote unquote working cc @jongpie
jamessimone Oct 18, 2024
ac91e77
More partial cleanup, with all unit tests passing
jamessimone Oct 25, 2024
db9f76e
Continued debugging
jamessimone Oct 25, 2024
3268419
Continuing to cleanup by ensuring RollupState__c is always cleared
jamessimone Oct 25, 2024
0e57c8a
Fixes issues with state related keys tracking
jamessimone Oct 31, 2024
f4a94f7
Branch cleanup, all tests passing
jamessimone Oct 31, 2024
b5a01dd
Continued pre-code review cleanup
jamessimone Oct 31, 2024
8a780ed
Actual fixes for #615 - this time with 100% better memory management!
jamessimone Oct 31, 2024
8eb8449
Adds explanatory comments to DataWeave script
jamessimone Oct 31, 2024
285e445
Bumping package version from Github Action
actions-user Oct 31, 2024
3c3971c
Re-use namespace-safe class names in a few tests
jamessimone Oct 31, 2024
a1226a5
A few other cleanup items
jamessimone Oct 31, 2024
95634f9
Bumping package version from Github Action
actions-user Oct 31, 2024
3f34ca0
Code review feedback from @jongpie
jamessimone Nov 1, 2024
bb8788d
Fixes #638 by addressing a classic DST issue in RollupDateLiteral. Sl…
jamessimone Nov 4, 2024
b776000
Bumping package version from Github Action
actions-user Nov 4, 2024
0a7781d
A few last pieces of cleanup
jamessimone Nov 5, 2024
e01f049
Bumping package version from Github Action
actions-user Nov 5, 2024
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
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