Skip to content

Commit 4d501ae

Browse files
committed
#2125 add throttling option for search index update after policy update
1 parent 3f8114f commit 4d501ae

File tree

9 files changed

+90
-16
lines changed

9 files changed

+90
-16
lines changed

deployment/helm/ditto/Chart.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ description: |
1616
A digital twin is a virtual, cloud based, representation of his real world counterpart
1717
(real world “Things”, e.g. devices like sensors, smart heating, connected cars, smart grids, EV charging stations etc).
1818
type: application
19-
version: 3.6.11 # chart version is effectively set by release-job
19+
version: 3.6.12 # chart version is effectively set by release-job
2020
appVersion: 3.6.11
2121
keywords:
2222
- iot-chart

deployment/helm/ditto/templates/thingssearch-deployment.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ spec:
201201
value: "{{ .Values.thingsSearch.config.mongodb.updaterPersistenceReadConcern }}"
202202
- name: UPDATER_PERSISTENCE_MONGO_DB_READ_PREFERENCE
203203
value: "{{ .Values.thingsSearch.config.mongodb.updaterPersistenceReadPreference }}"
204+
- name: POLICY_MODIFICATION_CAUSED_SEARCH_INDEX_UPDATE_THROTTLING_ENABLED
205+
value: "{{ .Values.thingsSearch.config.mongodb.PolicyModificationCausedSearchIndexUpdateThrottling.enabled }}"
206+
- name: POLICY_MODIFICATION_CAUSED_SEARCH_INDEX_UPDATE_THROTTLING_INTERVAL
207+
value: "{{ .Values.thingsSearch.config.mongodb.PolicyModificationCausedSearchIndexUpdateThrottling.interval }}"
208+
- name: POLICY_MODIFICATION_CAUSED_SEARCH_INDEX_UPDATE_THROTTLING_LIMIT
209+
value: "{{ .Values.thingsSearch.config.mongodb.PolicyModificationCausedSearchIndexUpdateThrottling.limit }}"
204210
- name: THINGS_SEARCH_UPDATER_STREAM_PERSISTENCE_WITH_ACKS_WRITE_CONCERN
205211
value: "{{ .Values.thingsSearch.config.mongodb.searchWithAcksWriteConcern }}"
206212
- name: THINGS_SEARCH_UPDATER_STREAM_POLICY_CACHE_SIZE

deployment/helm/ditto/values.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,14 @@ thingsSearch:
13761376
updaterPersistenceReadConcern: "local"
13771377
# updaterPersistenceReadPreference configures the MongoDB read preference for the "ThingUpdater"
13781378
updaterPersistenceReadPreference: "primaryPreferred"
1379+
# PolicyModificationCausedSearchIndexUpdateThrottling contains throttling configuration for the search Index update after a policy update
1380+
PolicyModificationCausedSearchIndexUpdateThrottling:
1381+
# enabled defines whether throttling should be applied for search Index update after a policy update.
1382+
enabled: false
1383+
# The time window within which the throttling limit applies.
1384+
interval: 1s
1385+
# The maximum number of updates allowed within each throttling interval.
1386+
limit: 100
13791387
# updater contains configuration for the "Things Updater" of things-search service
13801388
updater:
13811389
# activityCheckInterval configures to keep thing updaters for that amount of time in memory when no update did happen:

thingsearch/service/src/main/java/org/eclipse/ditto/thingsearch/service/common/config/DefaultSearchPersistenceConfig.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import javax.annotation.concurrent.Immutable;
1919

20+
import org.eclipse.ditto.base.service.config.ThrottlingConfig;
2021
import org.eclipse.ditto.internal.utils.config.ConfigWithFallback;
2122
import org.eclipse.ditto.internal.utils.config.DittoConfigError;
2223
import org.eclipse.ditto.internal.utils.persistence.mongo.config.MongoDbConfig;
@@ -35,6 +36,7 @@ public final class DefaultSearchPersistenceConfig implements SearchPersistenceCo
3536

3637
private final ReadPreference readPreference;
3738
private final ReadConcern readConcern;
39+
private final ThrottlingConfig policyModificationCausedSearchIndexUpdateThrottling;
3840

3941

4042
private DefaultSearchPersistenceConfig(final ConfigWithFallback config) {
@@ -56,6 +58,7 @@ private DefaultSearchPersistenceConfig(final ConfigWithFallback config) {
5658
readConcernString);
5759
return new DittoConfigError(msg);
5860
});
61+
policyModificationCausedSearchIndexUpdateThrottling = ThrottlingConfig.of(config);
5962
}
6063

6164
/**
@@ -80,6 +83,11 @@ public ReadConcern readConcern() {
8083
return readConcern;
8184
}
8285

86+
@Override
87+
public ThrottlingConfig getPolicyModificationCausedSearchIndexUpdateThrottling() {
88+
return policyModificationCausedSearchIndexUpdateThrottling;
89+
}
90+
8391
@Override
8492
public boolean equals(final Object o) {
8593
if (this == o) {
@@ -89,19 +97,23 @@ public boolean equals(final Object o) {
8997
return false;
9098
}
9199
final DefaultSearchPersistenceConfig that = (DefaultSearchPersistenceConfig) o;
92-
return readPreference == that.readPreference && readConcern == that.readConcern;
100+
return readPreference == that.readPreference
101+
&& readConcern == that.readConcern
102+
&& Objects.equals(
103+
policyModificationCausedSearchIndexUpdateThrottling, that.policyModificationCausedSearchIndexUpdateThrottling);
93104
}
94105

95106
@Override
96107
public int hashCode() {
97-
return Objects.hash(readPreference, readConcern);
108+
return Objects.hash(readPreference, readConcern, policyModificationCausedSearchIndexUpdateThrottling);
98109
}
99110

100111
@Override
101112
public String toString() {
102113
return getClass().getSimpleName() + " [" +
103114
"readPreference=" + readPreference +
104115
", readConcern=" + readConcern +
116+
", policyModificationCausedSearchIndexUpdateThrottling=" + policyModificationCausedSearchIndexUpdateThrottling +
105117
"]";
106118
}
107119
}

thingsearch/service/src/main/java/org/eclipse/ditto/thingsearch/service/common/config/SearchPersistenceConfig.java

+9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import javax.annotation.concurrent.Immutable;
1616

17+
import org.eclipse.ditto.base.service.config.ThrottlingConfig;
1718
import org.eclipse.ditto.internal.utils.config.KnownConfigValue;
1819
import org.eclipse.ditto.internal.utils.persistence.mongo.config.ReadConcern;
1920
import org.eclipse.ditto.internal.utils.persistence.mongo.config.ReadPreference;
@@ -38,6 +39,14 @@ public interface SearchPersistenceConfig {
3839
*/
3940
ReadConcern readConcern();
4041

42+
/**
43+
* Returns the {@code ThrottlingConfig} for the policy update after search Index update.
44+
*
45+
* @return the policy update ThrottlingConfig.
46+
* @since 3.7.0
47+
*/
48+
ThrottlingConfig getPolicyModificationCausedSearchIndexUpdateThrottling();
49+
4150
/**
4251
* An enumeration of known config path expressions and their associated default values for {@code SearchPersistenceConfig}.
4352
*/

thingsearch/service/src/main/java/org/eclipse/ditto/thingsearch/service/persistence/write/impl/MongoThingsSearchUpdaterPersistence.java

+24-13
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.bson.BsonString;
3232
import org.bson.Document;
3333
import org.bson.conversions.Bson;
34+
import org.eclipse.ditto.base.service.config.ThrottlingConfig;
3435
import org.eclipse.ditto.policies.api.PolicyTag;
3536
import org.eclipse.ditto.policies.model.PolicyId;
3637
import org.eclipse.ditto.things.model.ThingId;
@@ -58,8 +59,11 @@ public final class MongoThingsSearchUpdaterPersistence implements ThingsSearchUp
5859

5960
private final MongoCollection<Document> collection;
6061

62+
private final ThrottlingConfig PolicyModificationCausedSearchIndexUpdateThrottling;
63+
6164
private MongoThingsSearchUpdaterPersistence(final MongoDatabase database,
62-
final SearchPersistenceConfig updaterPersistenceConfig) {
65+
final SearchPersistenceConfig updaterPersistenceConfig) {
66+
this.PolicyModificationCausedSearchIndexUpdateThrottling = updaterPersistenceConfig.getPolicyModificationCausedSearchIndexUpdateThrottling();
6367

6468
collection = database.getCollection(PersistenceConstants.THINGS_COLLECTION_NAME)
6569
.withReadConcern(updaterPersistenceConfig.readConcern().getMongoReadConcern())
@@ -106,18 +110,25 @@ public Source<PolicyReferenceTag, NotUsed> getPolicyReferenceTags(final Map<Poli
106110
.append(PersistenceConstants.FIELD_POLICY_ID, new BsonInt32(1))
107111
.append(PersistenceConstants.FIELD_REFERENCED_POLICIES, new BsonInt32(1)));
108112

109-
return Source.fromPublisher(publisher)
110-
.mapConcat(doc -> {
111-
final ThingId thingId = ThingId.of(doc.getString(PersistenceConstants.FIELD_ID));
112-
final Collection<PolicyId> referencedPolicyIds = referencedPolicyIds(doc);
113-
return referencedPolicyIds.stream()
114-
.map(referencedPolicyId -> Optional.ofNullable(policyRevisions.get(referencedPolicyId))
115-
.map(revision -> PolicyTag.of(referencedPolicyId, revision))
116-
.map(policyTag -> PolicyReferenceTag.of(thingId, policyTag))
117-
.orElse(null))
118-
.filter(Objects::nonNull)
119-
.toList();
120-
});
113+
114+
final Source<Document, NotUsed> throttledSource = PolicyModificationCausedSearchIndexUpdateThrottling.isEnabled()
115+
? Source.fromPublisher(publisher).throttle(
116+
PolicyModificationCausedSearchIndexUpdateThrottling.getLimit(),
117+
PolicyModificationCausedSearchIndexUpdateThrottling.getInterval()
118+
)
119+
: Source.fromPublisher(publisher);
120+
121+
return throttledSource.mapConcat(doc -> {
122+
final ThingId thingId = ThingId.of(doc.getString(PersistenceConstants.FIELD_ID));
123+
final Collection<PolicyId> referencedPolicyIds = referencedPolicyIds(doc);
124+
return referencedPolicyIds.stream()
125+
.map(referencedPolicyId -> Optional.ofNullable(policyRevisions.get(referencedPolicyId))
126+
.map(revision -> PolicyTag.of(referencedPolicyId, revision))
127+
.map(policyTag -> PolicyReferenceTag.of(thingId, policyTag))
128+
.orElse(null))
129+
.filter(Objects::nonNull)
130+
.toList();
131+
});
121132
}
122133

123134
private Collection<PolicyId> referencedPolicyIds(final Document doc) {

thingsearch/service/src/main/resources/search.conf

+13
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,19 @@ ditto {
299299
# read concern is one of: default, local, majority, linearizable, snapshot, available
300300
readConcern = ${ditto.mongodb.options.readConcern}
301301
readConcern = ${?UPDATER_PERSISTENCE_MONGO_DB_READ_CONCERN}
302+
# PolicyModificationCausedSearchIndexUpdateThrottling contains throttling configuration for the search Index update after a policy update
303+
policyModificationCausedSearchIndexUpdateThrottling {
304+
# enabled defines whether throttling should be applied for search Index update after a policy update.
305+
enabled = false
306+
enabled = ${?POLICY_MODIFICATION_CAUSED_SEARCH_INDEX_UPDATE_THROTTLING_ENABLED}
307+
# The interval at which updates are throttled (e.g., every 1 second)
308+
interval = 1s
309+
interval = ${?POLICY_MODIFICATION_CAUSED_SEARCH_INDEX_UPDATE_THROTTLING_INTERVAL}
310+
311+
# Maximum number of updates allowed per interval (e.g., 100 updates per second)
312+
limit = 100
313+
limit = ${?POLICY_MODIFICATION_CAUSED_SEARCH_INDEX_UPDATE_THROTTLING_LIMIT}
314+
}
302315
}
303316
}
304317

thingsearch/service/src/test/java/org/eclipse/ditto/thingsearch/service/common/config/DefaultSearchPersistenceConfigTest.java

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package org.eclipse.ditto.thingsearch.service.common.config;
1414

1515
import org.assertj.core.api.JUnitSoftAssertions;
16+
import org.eclipse.ditto.base.service.config.ThrottlingConfig;
1617
import org.eclipse.ditto.internal.utils.persistence.mongo.config.ReadConcern;
1718
import org.eclipse.ditto.internal.utils.persistence.mongo.config.ReadPreference;
1819
import org.junit.BeforeClass;
@@ -62,6 +63,10 @@ public void underTestReturnsDefaultValuesIfBaseConfigWasEmpty() {
6263
.isEqualTo(ReadPreference.ofReadPreference(
6364
(String) SearchPersistenceConfig.ConfigValue.READ_PREFERENCE.getDefaultValue())
6465
.orElseThrow());
66+
67+
softly.assertThat(underTest.getPolicyModificationCausedSearchIndexUpdateThrottling())
68+
.as("Throttling Config should have default values")
69+
.isEqualTo(ThrottlingConfig.of(ConfigFactory.empty()));
6570
}
6671

6772
@Test
@@ -75,6 +80,10 @@ public void underTestReturnsValuesOfConfigFile() {
7580
softly.assertThat(underTest.readPreference())
7681
.as(SearchPersistenceConfig.ConfigValue.READ_PREFERENCE.getConfigPath())
7782
.isEqualTo(ReadPreference.SECONDARY_PREFERRED);
83+
84+
softly.assertThat(underTest.getPolicyModificationCausedSearchIndexUpdateThrottling())
85+
.as("Throttling Config should match the configuration file")
86+
.isNotNull();
7887
}
7988

8089
}

thingsearch/service/src/test/resources/updater-persistence-test.conf

+6
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,10 @@ persistence {
33
readPreference = secondaryPreferred
44
# read concern is one of: default, local, majority, linearizable, snapshot, available
55
readConcern = available
6+
7+
policyModificationCausedSearchIndexUpdateThrottling {
8+
enabled = false
9+
interval = 1s
10+
limit = 100
11+
}
612
}

0 commit comments

Comments
 (0)