Commit 10dd5c352f107cda96d2b85691724372fffdded1

Authored by Andrii Shvaika
1 parent e8e2f211

Max entities for data subscription over WS

... ... @@ -128,6 +128,8 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
128 128 private long dynamicPageLinkRefreshInterval;
129 129 @Value("${server.ws.dynamic_page_link.refresh_pool_size:1}")
130 130 private int dynamicPageLinkRefreshPoolSize;
  131 + @Value("${server.ws.max_entities_per_data_subscription:1000}")
  132 + private int maxEntitiesPerDataSubscription;
131 133 @Value("${server.ws.max_entities_per_alarm_subscription:1000}")
132 134 private int maxEntitiesPerAlarmSubscription;
133 135
... ... @@ -220,7 +222,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
220 222 } else if (cmd.getTsCmd() != null) {
221 223 handleTimeSeriesCmd(theCtx, cmd.getTsCmd());
222 224 } else if (!theCtx.isInitialDataSent()) {
223   - EntityDataUpdate update = new EntityDataUpdate(theCtx.getCmdId(), theCtx.getData(), null);
  225 + EntityDataUpdate update = new EntityDataUpdate(theCtx.getCmdId(), theCtx.getData(), null, theCtx.getMaxEntitiesPerDataSubscription());
224 226 wsService.sendWsMsg(theCtx.getSessionId(), update);
225 227 theCtx.setInitialDataSent(true);
226 228 }
... ... @@ -298,7 +300,8 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
298 300
299 301 private TbEntityDataSubCtx createSubCtx(TelemetryWebSocketSessionRef sessionRef, EntityDataCmd cmd) {
300 302 Map<Integer, TbAbstractDataSubCtx> sessionSubs = subscriptionsBySessionId.computeIfAbsent(sessionRef.getSessionId(), k -> new HashMap<>());
301   - TbEntityDataSubCtx ctx = new TbEntityDataSubCtx(serviceId, wsService, entityService, localSubscriptionService, attributesService, stats, sessionRef, cmd.getCmdId());
  303 + TbEntityDataSubCtx ctx = new TbEntityDataSubCtx(serviceId, wsService, entityService, localSubscriptionService,
  304 + attributesService, stats, sessionRef, cmd.getCmdId(), maxEntitiesPerDataSubscription);
302 305 ctx.setAndResolveQuery(cmd.getQuery());
303 306 sessionSubs.put(cmd.getCmdId(), ctx);
304 307 return ctx;
... ... @@ -306,7 +309,8 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
306 309
307 310 private TbAlarmDataSubCtx createSubCtx(TelemetryWebSocketSessionRef sessionRef, AlarmDataCmd cmd) {
308 311 Map<Integer, TbAbstractDataSubCtx> sessionSubs = subscriptionsBySessionId.computeIfAbsent(sessionRef.getSessionId(), k -> new HashMap<>());
309   - TbAlarmDataSubCtx ctx = new TbAlarmDataSubCtx(serviceId, wsService, entityService, localSubscriptionService, attributesService, stats, alarmService, sessionRef, cmd.getCmdId(), maxEntitiesPerAlarmSubscription);
  312 + TbAlarmDataSubCtx ctx = new TbAlarmDataSubCtx(serviceId, wsService, entityService, localSubscriptionService,
  313 + attributesService, stats, alarmService, sessionRef, cmd.getCmdId(), maxEntitiesPerAlarmSubscription);
310 314 ctx.setAndResolveQuery(cmd.getQuery());
311 315 sessionSubs.put(cmd.getCmdId(), ctx);
312 316 return ctx;
... ... @@ -372,10 +376,10 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
372 376 });
373 377 EntityDataUpdate update;
374 378 if (!ctx.isInitialDataSent()) {
375   - update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null);
  379 + update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription());
376 380 ctx.setInitialDataSent(true);
377 381 } else {
378   - update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData());
  382 + update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData(), ctx.getMaxEntitiesPerDataSubscription());
379 383 }
380 384 wsService.sendWsMsg(ctx.getSessionId(), update);
381 385 if (subscribe) {
... ... @@ -422,10 +426,10 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
422 426 });
423 427 EntityDataUpdate update;
424 428 if (!ctx.isInitialDataSent()) {
425   - update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null);
  429 + update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription());
426 430 ctx.setInitialDataSent(true);
427 431 } else {
428   - update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData());
  432 + update = new EntityDataUpdate(ctx.getCmdId(), null, ctx.getData().getData(), ctx.getMaxEntitiesPerDataSubscription());
429 433 }
430 434 wsService.sendWsMsg(ctx.getSessionId(), update);
431 435 ctx.createSubscriptions(latestCmd.getKeys(), true);
... ... @@ -440,7 +444,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
440 444 }, wsCallBackExecutor);
441 445 } else {
442 446 if (!ctx.isInitialDataSent()) {
443   - EntityDataUpdate update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null);
  447 + EntityDataUpdate update = new EntityDataUpdate(ctx.getCmdId(), ctx.getData(), null, ctx.getMaxEntitiesPerDataSubscription());
444 448 wsService.sendWsMsg(ctx.getSessionId(), update);
445 449 ctx.setInitialDataSent(true);
446 450 }
... ...
... ... @@ -57,6 +57,7 @@ import java.util.List;
57 57 import java.util.Map;
58 58 import java.util.Optional;
59 59 import java.util.Set;
  60 +import java.util.concurrent.ConcurrentHashMap;
60 61 import java.util.concurrent.ExecutionException;
61 62 import java.util.concurrent.ScheduledFuture;
62 63 import java.util.function.Function;
... ... @@ -98,9 +99,9 @@ public abstract class TbAbstractDataSubCtx<T extends AbstractDataQuery<? extends
98 99 this.stats = stats;
99 100 this.sessionRef = sessionRef;
100 101 this.cmdId = cmdId;
101   - this.subToEntityIdMap = new HashMap<>();
102   - this.subToDynamicValueKeySet = new HashSet<>();
103   - this.dynamicValues = new HashMap<>();
  102 + this.subToEntityIdMap = new ConcurrentHashMap<>();
  103 + this.subToDynamicValueKeySet = ConcurrentHashMap.newKeySet();
  104 + this.dynamicValues = new ConcurrentHashMap<>();
104 105 }
105 106
106 107 public void setAndResolveQuery(T query) {
... ...
... ... @@ -15,13 +15,10 @@
15 15 */
16 16 package org.thingsboard.server.service.subscription;
17 17
18   -import lombok.AllArgsConstructor;
19   -import lombok.Data;
20 18 import lombok.Getter;
21 19 import lombok.Setter;
22 20 import lombok.extern.slf4j.Slf4j;
23 21 import org.thingsboard.server.common.data.id.EntityId;
24   -import org.thingsboard.server.common.data.page.PageData;
25 22 import org.thingsboard.server.common.data.query.EntityData;
26 23 import org.thingsboard.server.common.data.query.EntityDataQuery;
27 24 import org.thingsboard.server.common.data.query.EntityKey;
... ... @@ -38,8 +35,6 @@ import org.thingsboard.server.service.telemetry.cmd.v2.TimeSeriesCmd;
38 35 import org.thingsboard.server.service.telemetry.sub.TelemetrySubscriptionUpdate;
39 36
40 37 import java.util.ArrayList;
41   -import java.util.Arrays;
42   -import java.util.Collection;
43 38 import java.util.Collections;
44 39 import java.util.Comparator;
45 40 import java.util.HashMap;
... ... @@ -48,8 +43,6 @@ import java.util.List;
48 43 import java.util.Map;
49 44 import java.util.Optional;
50 45 import java.util.Set;
51   -import java.util.concurrent.ScheduledFuture;
52   -import java.util.function.Function;
53 46 import java.util.stream.Collectors;
54 47
55 48 @Slf4j
... ... @@ -63,11 +56,14 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx<EntityDataQuery> {
63 56 private boolean initialDataSent;
64 57 private TimeSeriesCmd curTsCmd;
65 58 private LatestValueCmd latestValueCmd;
  59 + @Getter
  60 + private final int maxEntitiesPerDataSubscription;
66 61
67 62 public TbEntityDataSubCtx(String serviceId, TelemetryWebSocketService wsService, EntityService entityService,
68 63 TbLocalSubscriptionService localSubscriptionService, AttributesService attributesService,
69   - SubscriptionServiceStatistics stats, TelemetryWebSocketSessionRef sessionRef, int cmdId) {
  64 + SubscriptionServiceStatistics stats, TelemetryWebSocketSessionRef sessionRef, int cmdId, int maxEntitiesPerDataSubscription) {
70 65 super(serviceId, wsService, entityService, localSubscriptionService, attributesService, stats, sessionRef, cmdId);
  66 + this.maxEntitiesPerDataSubscription = maxEntitiesPerDataSubscription;
71 67 }
72 68
73 69 @Override
... ... @@ -120,7 +116,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx<EntityDataQuery> {
120 116 if (!latestUpdate.isEmpty()) {
121 117 Map<EntityKeyType, Map<String, TsValue>> latestMap = Collections.singletonMap(keyType, latestUpdate);
122 118 entityData = new EntityData(entityId, latestMap, null);
123   - wsService.sendWsMsg(sessionId, new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData)));
  119 + wsService.sendWsMsg(sessionId, new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData), maxEntitiesPerDataSubscription));
124 120 }
125 121 }
126 122
... ... @@ -163,7 +159,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx<EntityDataQuery> {
163 159 Map<String, TsValue[]> tsMap = new HashMap<>();
164 160 tsUpdate.forEach((key, tsValue) -> tsMap.put(key, tsValue.toArray(new TsValue[tsValue.size()])));
165 161 entityData = new EntityData(entityId, null, tsMap);
166   - wsService.sendWsMsg(sessionId, new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData)));
  162 + wsService.sendWsMsg(sessionId, new EntityDataUpdate(cmdId, null, Collections.singletonList(entityData), maxEntitiesPerDataSubscription));
167 163 }
168 164 }
169 165
... ... @@ -207,7 +203,7 @@ public class TbEntityDataSubCtx extends TbAbstractDataSubCtx<EntityDataQuery> {
207 203 );
208 204 }
209 205 }
210   - wsService.sendWsMsg(sessionRef.getSessionId(), new EntityDataUpdate(cmdId, data, null));
  206 + wsService.sendWsMsg(sessionRef.getSessionId(), new EntityDataUpdate(cmdId, data, null, maxEntitiesPerDataSubscription));
211 207 subIdsToCancel.forEach(subId -> localSubscriptionService.cancelSubscription(getSessionId(), subId));
212 208 subsToAdd.forEach(localSubscriptionService::addSubscription);
213 209 }
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.service.telemetry.cmd.v2;
18 18 import com.fasterxml.jackson.annotation.JsonCreator;
19 19 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
20 20 import com.fasterxml.jackson.annotation.JsonProperty;
  21 +import lombok.Getter;
21 22 import org.thingsboard.server.common.data.page.PageData;
22 23 import org.thingsboard.server.common.data.query.EntityData;
23 24 import org.thingsboard.server.service.telemetry.sub.SubscriptionErrorCode;
... ... @@ -27,8 +28,12 @@ import java.util.List;
27 28
28 29 public class EntityDataUpdate extends DataUpdate<EntityData> {
29 30
30   - public EntityDataUpdate(int cmdId, PageData<EntityData> data, List<EntityData> update) {
  31 + @Getter
  32 + private long allowedEntities;
  33 +
  34 + public EntityDataUpdate(int cmdId, PageData<EntityData> data, List<EntityData> update, long allowedEntities) {
31 35 super(cmdId, data, update, SubscriptionErrorCode.NO_ERROR.getCode(), null);
  36 + this.allowedEntities = allowedEntities;
32 37 }
33 38
34 39 public EntityDataUpdate(int cmdId, int errorCode, String errorMsg) {
... ...
... ... @@ -50,7 +50,8 @@ server:
50 50 refresh_interval: "${TB_SERVER_WS_DYNAMIC_PAGE_LINK_REFRESH_INTERVAL_SEC:60}"
51 51 refresh_pool_size: "${TB_SERVER_WS_DYNAMIC_PAGE_LINK_REFRESH_POOL_SIZE:1}"
52 52 max_per_user: "${TB_SERVER_WS_DYNAMIC_PAGE_LINK_MAX_PER_USER:10}"
53   - max_entities_per_alarm_subscription: "${TB_SERVER_WS_MAX_ENTITIES_PER_ALARM_SUBSCRIPTION:1000}"
  53 + max_entities_per_data_subscription: "${TB_SERVER_WS_MAX_ENTITIES_PER_DATA_SUBSCRIPTION:10000}"
  54 + max_entities_per_alarm_subscription: "${TB_SERVER_WS_MAX_ENTITIES_PER_ALARM_SUBSCRIPTION:10000}"
54 55 rest:
55 56 limits:
56 57 tenant:
... ...