Commit 10dd5c352f107cda96d2b85691724372fffdded1
1 parent
e8e2f211
Max entities for data subscription over WS
Showing
5 changed files
with
31 additions
and
24 deletions
... | ... | @@ -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: | ... | ... |