Skip to content

Commit 4767b81

Browse files
authored
Merge pull request #181 from Leanplum/oom2
Refactors request lists (unsent, to send, json encoding)
2 parents 271b137 + e256f9b commit 4767b81

File tree

3 files changed

+122
-28
lines changed

3 files changed

+122
-28
lines changed

AndroidSDKCore/src/main/java/com/leanplum/internal/Request.java

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -480,22 +480,71 @@ protected Void doInBackground(Void... params) {
480480
});
481481
}
482482

483-
private void sendRequests() {
483+
484+
static class RequestsWithEncoding {
485+
List<Map<String, Object>> unsentRequests;
486+
List<Map<String, Object>> requestsToSend;
487+
String jsonEncodedString;
488+
}
489+
490+
private RequestsWithEncoding getRequestsWithEncodedStringForErrors() {
484491
List<Map<String, Object>> unsentRequests = new ArrayList<>();
485492
List<Map<String, Object>> requestsToSend;
493+
String jsonEncodedRequestsToSend;
494+
495+
String uuid = UUID.randomUUID().toString();
496+
for (Map<String, Object> error : localErrors) {
497+
error.put(UUID_KEY, uuid);
498+
unsentRequests.add(error);
499+
}
500+
requestsToSend = unsentRequests;
501+
jsonEncodedRequestsToSend = jsonEncodeUnsentRequests(unsentRequests);
502+
503+
RequestsWithEncoding requestsWithEncoding = new RequestsWithEncoding();
504+
// for errors, we send all unsent requests so they are identical
505+
requestsWithEncoding.unsentRequests = unsentRequests;
506+
requestsWithEncoding.requestsToSend = requestsToSend;
507+
requestsWithEncoding.jsonEncodedString = jsonEncodedRequestsToSend;
508+
509+
return requestsWithEncoding;
510+
}
511+
512+
protected RequestsWithEncoding getRequestsWithEncodedStringStoredRequests() {
513+
List<Map<String, Object>> unsentRequests;
514+
List<Map<String, Object>> requestsToSend;
515+
String jsonEncodedRequestsToSend;
516+
517+
RequestsWithEncoding requestsWithEncoding = new RequestsWithEncoding();
518+
unsentRequests = getUnsentRequests();
519+
requestsToSend = removeIrrelevantBackgroundStartRequests(unsentRequests);
520+
jsonEncodedRequestsToSend = jsonEncodeUnsentRequests(unsentRequests);
521+
522+
requestsWithEncoding.unsentRequests = unsentRequests;
523+
requestsWithEncoding.requestsToSend = requestsToSend;
524+
requestsWithEncoding.jsonEncodedString = jsonEncodedRequestsToSend;
525+
526+
return requestsWithEncoding;
527+
}
528+
529+
private RequestsWithEncoding getRequestsWithEncodedString() {
530+
RequestsWithEncoding requestsWithEncoding;
486531
// Check if we have localErrors, if yes then we will send only errors to the server.
487532
if (localErrors.size() != 0) {
488-
String uuid = UUID.randomUUID().toString();
489-
for (Map<String, Object> error : localErrors) {
490-
error.put(UUID_KEY, uuid);
491-
unsentRequests.add(error);
492-
}
493-
requestsToSend = unsentRequests;
533+
requestsWithEncoding = getRequestsWithEncodedStringForErrors();
494534
} else {
495-
unsentRequests = getUnsentRequests();
496-
requestsToSend = removeIrrelevantBackgroundStartRequests(unsentRequests);
535+
requestsWithEncoding = getRequestsWithEncodedStringStoredRequests();
497536
}
498537

538+
return requestsWithEncoding;
539+
}
540+
541+
private void sendRequests() {
542+
RequestsWithEncoding requestsWithEncoding = getRequestsWithEncodedString();
543+
544+
List<Map<String, Object>> unsentRequests = requestsWithEncoding.unsentRequests;
545+
List<Map<String, Object>> requestsToSend = requestsWithEncoding.requestsToSend;
546+
String jsonEncodedString = requestsWithEncoding.jsonEncodedString;
547+
499548
if (requestsToSend.isEmpty()) {
500549
return;
501550
}
@@ -504,7 +553,7 @@ private void sendRequests() {
504553
if (!Request.attachApiKeys(multiRequestArgs)) {
505554
return;
506555
}
507-
multiRequestArgs.put(Constants.Params.DATA, jsonEncodeUnsentRequests(requestsToSend));
556+
multiRequestArgs.put(Constants.Params.DATA, jsonEncodedString);
508557
multiRequestArgs.put(Constants.Params.SDK_VERSION, Constants.LEANPLUM_VERSION);
509558
multiRequestArgs.put(Constants.Params.ACTION, Constants.Methods.MULTI);
510559
multiRequestArgs.put(Constants.Params.TIME, Double.toString(new Date().getTime() / 1000.0));
@@ -597,7 +646,7 @@ static void deleteSentRequests(int requestsCount) {
597646
}
598647
}
599648

600-
private static List<Map<String, Object>> getUnsentRequests() {
649+
public List<Map<String, Object>> getUnsentRequests() {
601650
List<Map<String, Object>> requestData;
602651

603652
synchronized (Request.class) {
@@ -654,7 +703,7 @@ private static List<Map<String, Object>> removeIrrelevantBackgroundStartRequests
654703
return relevantRequests;
655704
}
656705

657-
private static String jsonEncodeUnsentRequests(List<Map<String, Object>> requestData) {
706+
protected static String jsonEncodeUnsentRequests(List<Map<String, Object>> requestData) {
658707
Map<String, Object> data = new HashMap<>();
659708
data.put(Constants.Params.DATA, requestData);
660709
return JsonConverter.toJson(data);

AndroidSDKTests/src/test/java/com/leanplum/LeanplumTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,14 @@ public void testCrashes() throws Exception {
398398
LeanplumEventDataManager.init(Leanplum.getContext());
399399

400400
// Add two events to database.
401-
new Request("POST", Constants.Methods.GET_INBOX_MESSAGES, null).sendEventually();
402-
new Request("POST", Constants.Methods.LOG, null).sendEventually();
401+
Request request1 = new Request("POST", Constants.Methods.GET_INBOX_MESSAGES, null);
402+
Request request2 = new Request("POST", Constants.Methods.LOG, null);
403403

404+
request1.sendEventually();
405+
request2.sendEventually();
404406
// Get a number of events in the database.
405407
// Expectation: 2 events.
406-
Method getUnsentRequests = Request.class.getDeclaredMethod("getUnsentRequests");
407-
getUnsentRequests.setAccessible(true);
408-
List unsentRequests = (List) getUnsentRequests.invoke(Request.class);
408+
List unsentRequests = request1.getUnsentRequests();
409409
assertNotNull(unsentRequests);
410410
assertEquals(2, unsentRequests.size());
411411

@@ -427,7 +427,7 @@ public void testCrashes() throws Exception {
427427

428428
// Get a number of events in the database. Checks if ours two events still here.
429429
// Expectation: 2 events.
430-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
430+
unsentRequests = request1.getUnsentRequests();
431431
assertNotNull(unsentRequests);
432432
assertEquals(2, unsentRequests.size());
433433

@@ -444,7 +444,7 @@ public void onRequest(String httpMethod, String apiMethod, Map<String, Object> p
444444

445445
// Get a number of events in the database. Make sure we sent all events.
446446
// Expectation: 0 events.
447-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
447+
unsentRequests = request1.getUnsentRequests();
448448
assertNotNull(unsentRequests);
449449
assertEquals(0, unsentRequests.size());
450450

AndroidSDKTests/src/test/java/com/leanplum/internal/RequestTest.java

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,14 @@
3939

4040
import java.lang.reflect.InvocationTargetException;
4141
import java.lang.reflect.Method;
42+
import java.util.ArrayList;
4243
import java.util.HashMap;
4344
import java.util.List;
4445
import java.util.Map;
4546

47+
import static org.mockito.Mockito.spy;
48+
import static org.mockito.Mockito.when;
49+
4650
/**
4751
* @author Ben Marten
4852
*/
@@ -89,19 +93,17 @@ public void testRemoveIrrelevantBackgroundStartRequests() throws NoSuchMethodExc
8993
Method removeIrrelevantBackgroundStartRequests =
9094
Request.class.getDeclaredMethod("removeIrrelevantBackgroundStartRequests", List.class);
9195
removeIrrelevantBackgroundStartRequests.setAccessible(true);
92-
Method getUnsentRequests = Request.class.getDeclaredMethod("getUnsentRequests");
93-
getUnsentRequests.setAccessible(true);
9496

9597
// Invoke method with specific test data.
9698
// Expectation: No request returned.
97-
List unsentRequests = (List) getUnsentRequests.invoke(Request.class);
99+
List unsentRequests = request.getUnsentRequests();
98100
assertNotNull(unsentRequests);
99101
assertEquals(0, unsentRequests.size());
100102

101103
// Regular start request.
102104
// Expectation: One request returned.
103105
request.sendEventually();
104-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
106+
unsentRequests = request.getUnsentRequests();
105107
assertNotNull(unsentRequests);
106108
assertEquals(1, unsentRequests.size());
107109
Request.deleteSentRequests(unsentRequests.size());
@@ -116,7 +118,7 @@ public void testRemoveIrrelevantBackgroundStartRequests() throws NoSuchMethodExc
116118
put(Constants.Params.BACKGROUND, Boolean.toString(false));
117119
put("fg", "2");
118120
}}).sendEventually();
119-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
121+
unsentRequests = request.getUnsentRequests();
120122
assertNotNull(unsentRequests);
121123
assertEquals(2, unsentRequests.size());
122124
Request.deleteSentRequests(unsentRequests.size());
@@ -131,7 +133,7 @@ public void testRemoveIrrelevantBackgroundStartRequests() throws NoSuchMethodExc
131133
put(Constants.Params.BACKGROUND, Boolean.toString(false));
132134
put("fg", "1");
133135
}}).sendEventually();
134-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
136+
unsentRequests = request.getUnsentRequests();
135137
List unsentRequestsData =
136138
(List) removeIrrelevantBackgroundStartRequests.invoke(Request.class, unsentRequests);
137139
assertNotNull(unsentRequestsData);
@@ -153,7 +155,7 @@ public void testRemoveIrrelevantBackgroundStartRequests() throws NoSuchMethodExc
153155
put(Constants.Params.BACKGROUND, Boolean.toString(false));
154156
put("fg", "1");
155157
}}).sendEventually();
156-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
158+
unsentRequests = request.getUnsentRequests();
157159

158160
assertNotNull(unsentRequests);
159161
unsentRequestsData =
@@ -176,7 +178,7 @@ public void testRemoveIrrelevantBackgroundStartRequests() throws NoSuchMethodExc
176178
put(Constants.Params.BACKGROUND, Boolean.toString(true));
177179
put("bg", "2");
178180
}}).sendEventually();
179-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
181+
unsentRequests = request.getUnsentRequests();
180182
assertNotNull(unsentRequests);
181183
unsentRequestsData =
182184
(List) removeIrrelevantBackgroundStartRequests.invoke(Request.class, unsentRequests);
@@ -198,12 +200,55 @@ public void testRemoveIrrelevantBackgroundStartRequests() throws NoSuchMethodExc
198200
put(Constants.Params.BACKGROUND, Boolean.toString(true));
199201
put("bg", "2");
200202
}}).sendEventually();
201-
unsentRequests = (List) getUnsentRequests.invoke(Request.class);
203+
unsentRequests = request.getUnsentRequests();
202204
unsentRequestsData =
203205
(List) removeIrrelevantBackgroundStartRequests.invoke(Request.class, unsentRequests);
204206
assertNotNull(unsentRequestsData);
205207
assertEquals(3, unsentRequestsData.size());
206208
Request.deleteSentRequests(unsentRequests.size());
207209
LeanplumEventDataManagerTest.setDatabaseToNull();
208210
}
211+
212+
// Given a list of unsent requests
213+
// we want to get the list of strings to send
214+
// We should get back the correct list of requests to send
215+
@Test
216+
public void testJsonEncodeUnsentRequests() {
217+
List<Map<String, Object>> requests = mockRequests(4);
218+
219+
Request realRequest = new Request("POST", Constants.Methods.START, null);
220+
Request request = spy(realRequest);
221+
when(request.getUnsentRequests()).thenReturn(requests);
222+
223+
Request.RequestsWithEncoding requestsWithEncoding = request.getRequestsWithEncodedStringStoredRequests();
224+
225+
assertEquals(4, requestsWithEncoding .unsentRequests.size());
226+
assertEquals(4, requestsWithEncoding .requestsToSend.size());
227+
final String expectedJson = "{\"data\":[{\"0\":\"testData\"},{\"1\":\"testData\"},{\"2\":\"testData\"},{\"3\":\"testData\"}]}";
228+
assertEquals(expectedJson, requestsWithEncoding.jsonEncodedString);
229+
}
230+
231+
// Given a list of requests
232+
// we want to encode to a JSON String
233+
// The String should have the expected format
234+
@Test
235+
public void testGetRequestsWithEncodedStringStoredRequests() {
236+
List<Map<String, Object>> requests = mockRequests(4);
237+
String json = Request.jsonEncodeUnsentRequests(requests);
238+
239+
final String expectedJson = "{\"data\":[{\"0\":\"testData\"},{\"1\":\"testData\"},{\"2\":\"testData\"},{\"3\":\"testData\"}]}";
240+
assertEquals(json, expectedJson);
241+
}
242+
243+
private List<Map<String, Object>> mockRequests(int requestSize) {
244+
List<Map<String, Object>> requests = new ArrayList<>();
245+
246+
for (int i=0; i < requestSize; i++) {
247+
Map<String, Object> request = new HashMap<String, Object>();
248+
request.put(Integer.toString(i), "testData");
249+
requests.add(request);
250+
}
251+
return requests;
252+
}
253+
209254
}

0 commit comments

Comments
 (0)