UNOMI-557: Optimize the profile update during segment deletion (#433)
* UNOMI-557: Optimize the profile update during segment deletion
* UNOMI-557: Optimize the profile update during segment deletion
* UNOMI-557: Optimize the profile update during segment deletion
* UNOMI-557: Optimize the profile update during segment deletion
* UNOMI-557: Optimize the profile update during segment deletion
diff --git a/itests/src/test/java/org/apache/unomi/itests/SegmentIT.java b/itests/src/test/java/org/apache/unomi/itests/SegmentIT.java
index 221f975..1eb0371 100644
--- a/itests/src/test/java/org/apache/unomi/itests/SegmentIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/SegmentIT.java
@@ -162,6 +162,45 @@
}
@Test
+ public void testProfileEngagedSegmentAddedRemoved() throws InterruptedException {
+ Condition segmentSearchCondition = new Condition();
+ segmentSearchCondition.setConditionType(definitionsService.getConditionType("profilePropertyCondition"));
+ segmentSearchCondition.setParameter("propertyName", "segments");
+ segmentSearchCondition.setParameter("comparisonOperator", "equals");
+ segmentSearchCondition.setParameter("propertyValue", "add-delete-segment-test");
+
+ // create Profile
+ Profile profile = new Profile();
+ profile.setItemId("test_profile_id");
+ profile.setProperty("age", 42);
+ profileService.save(profile);
+ persistenceService.refreshIndex(Profile.class, null);
+
+ keepTrying("Profile should not be engaged in the segment yet", () -> persistenceService.query(segmentSearchCondition, null, Profile.class),
+ profiles -> profiles.size() == 0, 1000, 20);
+
+ // create the segment
+ Metadata segmentMetadata = new Metadata("add-delete-segment-test");
+ Segment segment = new Segment(segmentMetadata);
+ Condition segmentCondition = new Condition(definitionsService.getConditionType("profilePropertyCondition"));
+ segmentCondition.setParameter("propertyName", "properties.age");
+ segmentCondition.setParameter("comparisonOperator", "exists");
+ segment.setCondition(segmentCondition);
+ segmentService.setSegmentDefinition(segment);
+
+ // insure the profile that did the past event condition is correctly engaged in the segment.
+ keepTrying("Profile should be engaged in the segment", () -> persistenceService.query(segmentSearchCondition, null, Profile.class),
+ profiles -> profiles.size() == 1, 1000, 20);
+
+ // delete the segment
+ segmentService.removeSegmentDefinition("add-delete-segment-test", false);
+
+ // insure the profile is not engaged anymore after segment deleted
+ keepTrying("Profile should not be engaged in the segment anymore after the segment have been deleted", () -> persistenceService.query(segmentSearchCondition, null, Profile.class),
+ profiles -> profiles.size() == 0, 1000, 20);
+ }
+
+ @Test
public void testSegmentWithPastEventCondition() throws InterruptedException {
// create Profile
Profile profile = new Profile();
diff --git a/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java
index dc1333b..90fda2b 100644
--- a/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java
+++ b/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java
@@ -391,21 +391,7 @@
segmentCondition.setParameter("propertyName", "segments");
segmentCondition.setParameter("comparisonOperator", "equals");
segmentCondition.setParameter("propertyValue", segmentId);
-
- List<Profile> previousProfiles = persistenceService.query(segmentCondition, null, Profile.class);
- long updatedProfileCount = 0;
- long profileRemovalStartTime = System.currentTimeMillis();
- if (batchSegmentProfileUpdate && previousProfiles.size() > 0) {
- batchUpdateProfilesSegment(segmentId, previousProfiles, false);
- } else {
- for (Profile profileToRemove : previousProfiles) {
- Map<String, Object> sourceMap = buildPropertiesMapForUpdateSegment(profileToRemove, segmentId, false);
- persistenceService.update(profileToRemove, null, Profile.class, sourceMap);
- }
- }
-
- updatedProfileCount += previousProfiles.size();
- logger.info("Removed segment from {} profiles in {} ms", updatedProfileCount, System.currentTimeMillis() - profileRemovalStartTime);
+ updateProfilesSegment(segmentCondition, segmentId, false, false);
// update impacted segments
for (Segment segment : impactedSegments) {
@@ -1088,15 +1074,15 @@
profilesToRemoveSubConditions.add(notNewSegmentCondition);
profilesToRemoveCondition.setParameter("subConditions", profilesToRemoveSubConditions);
- updatedProfileCount += updateProfilesSegment(profilesToAddCondition, segmentId, true);
- updatedProfileCount += updateProfilesSegment(profilesToRemoveCondition, segmentId, false);
+ updatedProfileCount += updateProfilesSegment(profilesToAddCondition, segmentId, true, sendProfileUpdateEventForSegmentUpdate);
+ updatedProfileCount += updateProfilesSegment(profilesToRemoveCondition, segmentId, false, sendProfileUpdateEventForSegmentUpdate);
} else {
- updatedProfileCount += updateProfilesSegment(segmentCondition, segmentId, false);
+ updatedProfileCount += updateProfilesSegment(segmentCondition, segmentId, false, sendProfileUpdateEventForSegmentUpdate);
}
logger.info("{} profiles updated in {}ms", updatedProfileCount, System.currentTimeMillis() - updateProfilesForSegmentStartTime);
}
- private long updateProfilesSegment(Condition profilesToUpdateCondition, String segmentId, boolean isAdd) {
+ private long updateProfilesSegment(Condition profilesToUpdateCondition, String segmentId, boolean isAdd, boolean sendProfileUpdateEvent) {
long updatedProfileCount = 0;
PartialList<Profile> profiles = persistenceService.query(profilesToUpdateCondition, null, Profile.class, 0, segmentUpdateBatchSize, "10m");
@@ -1110,7 +1096,7 @@
persistenceService.update(profileToUpdate, null, Profile.class, sourceMap);
}
}
- if (sendProfileUpdateEventForSegmentUpdate)
+ if (sendProfileUpdateEvent)
sendProfileUpdatedEvent(profiles.getList());
updatedProfileCount += profiles.size();