Skip to content

Commit 7ec98f9

Browse files
authored
Merge pull request #259 from Countly/user_props_on_sessions
User props on sessions
2 parents d7b3fe6 + 834571e commit 7ec98f9

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## 24.1.4
22

3+
* Updated user properties caching mechanism according to sessions.
34
* Cleaned up unused gradle dependencies from root build.gradle.
45

56
## 24.1.3

sdk-java/src/main/java/ly/count/sdk/java/Config.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ public class Config {
243243
protected String city = null;
244244
protected String country = null;
245245
protected boolean locationEnabled = true;
246+
protected boolean autoSendUserPropertiesOnSessions = true;
246247

247248
// TODO: storage limits & configuration
248249
// protected int maxRequestsStored = 0;
@@ -1480,4 +1481,14 @@ public String toString() {
14801481
return "DID " + id + " ( " + strategy + ")";
14811482
}
14821483
}
1484+
1485+
/**
1486+
* Disable automatic sending of user properties on session begin, update and end
1487+
*
1488+
* @return {@code this} instance for method chaining
1489+
*/
1490+
public Config disableAutoSendUserPropertiesOnSessions() {
1491+
this.autoSendUserPropertiesOnSessions = false;
1492+
return this;
1493+
}
14831494
}

sdk-java/src/main/java/ly/count/sdk/java/internal/InternalConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class InternalConfig extends Config {
3232
protected IdGenerator viewIdGenerator;
3333
protected IdGenerator eventIdGenerator;
3434
protected ViewIdProvider viewIdProvider;
35+
3536
/**
3637
* Shouldn't be used!
3738
*/
@@ -211,4 +212,8 @@ String[] getLocationParams() {
211212
boolean isLocationDisabled() {
212213
return !locationEnabled;
213214
}
215+
216+
boolean isAutoSendUserPropertiesOnSessions() {
217+
return autoSendUserPropertiesOnSessions;
218+
}
214219
}

sdk-java/src/main/java/ly/count/sdk/java/internal/SessionImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ Future<Boolean> begin(Long now) {
118118
}
119119

120120
this.consents = SDKCore.instance.consents;
121+
if (config.isAutoSendUserPropertiesOnSessions() && config.sdk.userProfile() != null) {
122+
config.sdk.module(ModuleUserProfile.class).saveInternal();
123+
}
121124

122125
if (pushOnChange) {
123126
Storage.pushAsync(config, this);
@@ -157,6 +160,9 @@ Future<Boolean> update(Long now) {
157160
}
158161

159162
this.consents = SDKCore.instance.consents;
163+
if (config.isAutoSendUserPropertiesOnSessions() && config.sdk.userProfile() != null) {
164+
config.sdk.module(ModuleUserProfile.class).saveInternal();
165+
}
160166

161167
Long duration = updateDuration(now);
162168

@@ -192,6 +198,9 @@ Future<Boolean> end(Long now, final Tasks.Callback<Boolean> callback, String did
192198
ended = now == null ? System.nanoTime() : now;
193199

194200
this.consents = SDKCore.instance.consents;
201+
if (config.isAutoSendUserPropertiesOnSessions() && config.sdk.userProfile() != null) {
202+
config.sdk.module(ModuleUserProfile.class).saveInternal();
203+
}
195204

196205
if (currentView != null) {
197206
currentView.stop(true);

sdk-java/src/test/java/ly/count/sdk/java/internal/SessionImplTests.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,81 @@ public void view_stopStartedAndNext() {
629629
ModuleViewsTests.validateView("next", 0.0, 2, 3, false, true, null, TestUtils.keysValues[1], TestUtils.keysValues[0]);
630630
}
631631

632+
/**
633+
* Validates that when session calls are made, if any user properties are set,
634+
* they are sent before sending that session call
635+
* Validated with all session calls: begin, update, end
636+
*
637+
* @throws InterruptedException if thread is interrupted
638+
*/
639+
@Test
640+
public void userPropsOnSessions() throws InterruptedException {
641+
Countly.instance().init(TestUtils.getConfigSessions(Config.Feature.UserProfiles));
642+
Countly.instance().userProfile().setProperty("name", "John Doe");
643+
Countly.instance().userProfile().setProperty("custom_key", "custom_value");
644+
645+
Countly.session().begin();
646+
Map<String, String>[] RQ = TestUtils.getCurrentRQ();
647+
UserEditorTests.validateUserDetailsRequestInRQ(TestUtils.map("user_details", TestUtils.json("name", "John Doe", "custom", TestUtils.map("custom_key", "custom_value"))), 0, 2);
648+
Assert.assertEquals("1", RQ[1].get("begin_session"));
649+
650+
Thread.sleep(2000); // wait for session to update
651+
Countly.instance().userProfile().save();
652+
RQ = TestUtils.getCurrentRQ();
653+
Assert.assertEquals(2, RQ.length); // Validate that user properties are flushed
654+
655+
Countly.instance().userProfile().setProperty("email", "john@doe.com");
656+
Countly.session().update();
657+
658+
RQ = TestUtils.getCurrentRQ();
659+
Assert.assertEquals(TestUtils.json("email", "john@doe.com"), RQ[2].get("user_details"));
660+
Assert.assertEquals("2", RQ[3].get("session_duration"));
661+
662+
Thread.sleep(2000); // wait for session to update
663+
Countly.instance().userProfile().save();
664+
RQ = TestUtils.getCurrentRQ();
665+
Assert.assertEquals(4, RQ.length); // Validate that user properties are flushed with update call
666+
667+
Countly.instance().userProfile().setProperty("done", "yes");
668+
Countly.session().end();
669+
670+
RQ = TestUtils.getCurrentRQ();
671+
Assert.assertEquals(TestUtils.json("custom", TestUtils.map("done", "yes")), RQ[4].get("user_details"));
672+
Assert.assertEquals("1", RQ[5].get("end_session"));
673+
}
674+
675+
/**
676+
* Validates that when session calls are made, if any user properties are set,
677+
* they are not packed because auto-send is disabled
678+
*
679+
* @throws InterruptedException if thread is interrupted
680+
*/
681+
@Test
682+
public void userPropsOnSessions_reversed() throws InterruptedException {
683+
Countly.instance().init(TestUtils.getConfigSessions(Config.Feature.UserProfiles).disableAutoSendUserPropertiesOnSessions());
684+
Countly.instance().userProfile().setProperty("name", "John Doe");
685+
Countly.instance().userProfile().setProperty("custom_key", "custom_value");
686+
687+
Countly.session().begin();
688+
Map<String, String>[] RQ = TestUtils.getCurrentRQ();
689+
Assert.assertEquals(1, RQ.length);
690+
Assert.assertEquals("1", RQ[0].get("begin_session"));
691+
692+
Thread.sleep(2000); // wait for session to update
693+
Countly.session().update();
694+
RQ = TestUtils.getCurrentRQ();
695+
696+
Assert.assertEquals(2, RQ.length);
697+
Assert.assertEquals("2", RQ[1].get("session_duration"));
698+
699+
Thread.sleep(2000);
700+
Countly.session().end();
701+
RQ = TestUtils.getCurrentRQ();
702+
703+
Assert.assertEquals(3, RQ.length);
704+
Assert.assertEquals("1", RQ[2].get("end_session"));
705+
}
706+
632707
private void validateNotEquals(int idOffset, BiFunction<SessionImpl, SessionImpl, Consumer<Long>> setter) {
633708
Countly.instance().init(TestUtils.getConfigSessions());
634709
long ts = TimeUtils.timestampMs();

0 commit comments

Comments
 (0)