Skip to content

Commit 4af5c03

Browse files
authored
fix(QueueableProcess): Updates Queueable Process (#345)
To Fix a logic, order-of-operations error, and to capture the results of the sub-class' execute method
1 parent 1e34e3f commit 4af5c03

13 files changed

Lines changed: 1088 additions & 49 deletions

force-app/main/default/classes/ULID/README.md

Lines changed: 459 additions & 0 deletions
Large diffs are not rendered by default.

force-app/main/default/classes/ULID/ULID.cls

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
*/
1212
public with sharing class ULID {
1313
/**
14-
* This character set is the complete list of allowed characters in
14+
* @description This character set is the complete list of allowed characters in
1515
* a ULID string. It intentionally does not include characters that
1616
* may be ambiguously read, such as i, l, o, and u characters.
1717
*/
18-
private static final List<String> CHARACTERSET = new List<String>{
18+
private static final List<String> CHARACTER_SET = new List<String>{
1919
'0',
2020
'1',
2121
'2',
@@ -50,23 +50,22 @@ public with sharing class ULID {
5050
'Z'
5151
};
5252
// Calculate this once per transaction to avoid unnecessary math
53-
private static final Long CHARACTERSETSIZE = CHARACTERSET.size();
54-
// This is equal to 2^48-1 and represents the max timestamp
55-
// allowed in a ULID string
53+
private static final Long CHARACTER_SET_SIZE = CHARACTER_SET.size();
54+
// This is equal to 2^48-1 and represents the max timestamp allowed in a ULID string
5655
// private static final Long MAXTIME = 281474976710655L;
5756
// This is the number of digits to encode the timestamp into.
58-
private static final Long TIMELENGTH = 10;
57+
private static final Long TIME_LENGTH = 10;
5958
// This is the number of digits of random character to generate
60-
private static final Integer RANDOMLENGTH = 16;
59+
private static final Integer RANDOM_LENGTH = 16;
6160

6261
/**
6362
* @description Generates a ULID string according to spec.
6463
* https://github.com/ulid/spec
6564
* @return `String`
6665
*/
6766
public static String generate() {
68-
return encodeTimestamp(DateTime.now().getTime(), TIMELENGTH) +
69-
generateRandomString(RANDOMLENGTH);
67+
return encodeTimestamp(Datetime.now().getTime(), TIME_LENGTH) +
68+
generateRandomString(RANDOM_LENGTH);
7069
}
7170

7271
/**
@@ -76,13 +75,14 @@ public with sharing class ULID {
7675
* @param timeLength how many characters of the timestamp to encode
7776
* @return `String`
7877
*/
78+
@SuppressWarnings('PMD.UnusedLocalVariable')
7979
private static String encodeTimestamp(Long dtSeed, Long timeLength) {
8080
Long modulo;
8181
String retString = '';
8282
for (Long l = timeLength; timeLength > 0; timeLength--) {
83-
modulo = Math.mod(dtSeed, CHARACTERSETSIZE);
84-
retString = CHARACTERSET[modulo.intValue()] + retString;
85-
dtSeed = (dtSeed - modulo) / CHARACTERSETSIZE;
83+
modulo = Math.mod(dtSeed, CHARACTER_SET_SIZE);
84+
retString = CHARACTER_SET[modulo.intValue()] + retString;
85+
dtSeed = (dtSeed - modulo) / CHARACTER_SET_SIZE;
8686
}
8787
return retString;
8888
}
@@ -108,7 +108,7 @@ public with sharing class ULID {
108108
* @return `String`
109109
*/
110110
private static String fetchRandomCharacterFromCharacterSet() {
111-
Long rand = Math.mod(Math.abs(Crypto.getRandomLong()), CHARACTERSETSIZE);
112-
return CHARACTERSET[rand.intValue()];
111+
Long rand = Math.mod(Math.abs(Crypto.getRandomLong()), CHARACTER_SET_SIZE);
112+
return CHARACTER_SET[rand.intValue()];
113113
}
114114
}

force-app/main/default/classes/polyfills/tests/PolyfillsTests.cls

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ private class PolyfillsTests {
162162
(List<Contact>) SObjectFactory.createSObjects(
163163
new Contact(AccountId = acct.Id),
164164
5,
165-
false
165+
null,
166+
false,
167+
true
166168
)
167169
);
168170
}

force-app/main/default/classes/queueable process/EnqueueNextQueueableProcessStep.cls

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,17 @@ public with sharing class EnqueueNextQueueableProcessStep implements System.Fina
6868
switch on context.getResult() {
6969
when SUCCESS {
7070
if (this.processSteps.size() > 0) {
71+
// Remove the first element from the list - this was constructed using the .then() method.
7172
QueueableProcess nextProcessStep = this.processSteps.remove(0);
73+
// Set the remaining steps on the next process step.
7274
nextProcessStep.processSteps = this.processSteps;
75+
// Set the dataPassthrough on the next process step.
7376
nextProcessStep.dataPassthrough = dataPassthrough;
77+
// Set the queueableContextHistory on the next process step.
7478
nextProcessStep.queueableContextHistory = this.queueableContextHistory;
79+
// Set the finalizerContextHistory on the next process step.
7580
nextProcessStep.finalizerContextHistory = this.finalizerContextHistory;
81+
// Enqueue the next process step.
7682
System.enqueueJob(nextProcessStep);
7783
}
7884
}

force-app/main/default/classes/queueable process/QueueableProcess.cls

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ public abstract class QueueableProcess implements Queueable, Database.AllowsCall
6161

6262
/**
6363
* @description This must be implemented by extending classes. Developers - implement this method with the work you
64-
* want executed asynchronously.
64+
* want executed asynchronously. The returned Object will be passed as dataPassthrough to the next step.
65+
*
66+
* @return Object - data to pass through to the next step in the process
6567
*/
66-
abstract public void execute();
68+
abstract public Object execute();
6769

6870
/**
6971
* @description this is a default implementation of an handleError method. It's called by the finalizer if the
@@ -85,23 +87,23 @@ public abstract class QueueableProcess implements Queueable, Database.AllowsCall
8587
*/
8688
public virtual void execute(QueueableContext context) {
8789
// if the queueableContextHistory is null, initialize it.
88-
if (this.queueableContextHistory == null) {
89-
this.queueableContextHistory = new List<QueueableContext>();
90-
}
90+
this.queueableContextHistory = this.queueableContextHistory ??
91+
new List<QueueableContext>();
9192
this.queueableContextHistory.add(context);
9293

94+
// Call the abstract method `execute` and capture its return value as the dataPassthrough for the next step.
95+
Object nextDataPassthrough = execute();
96+
9397
// create a new instance of the finalizer class. Note that we're passing in the list of remaining steps and the
94-
// passthrough data.
98+
// returned data from execute() as the passthrough data for the next step.
9599
Finalizer nextStep = new EnqueueNextQueueableProcessStep(
96100
this.processSteps,
97-
this.dataPassthrough,
101+
nextDataPassthrough,
98102
this.queueableContextHistory,
99103
this.finalizerContextHistory
100104
);
101105
// Attach the finalizer to system context. This will take care of enqueueing the next QueueableProcess step in
102106
// the nextStep.
103107
System.attachFinalizer(nextStep);
104-
// invoke the abstract method `execute`. see the comment above.
105-
execute();
106108
}
107109
}

0 commit comments

Comments
 (0)