Added max size of queue per websocket

This commit is contained in:
Andrew Shvayka 2018-11-23 13:17:36 +02:00
parent a4faa317a6
commit cd1947663e
2 changed files with 22 additions and 10 deletions

View File

@ -75,6 +75,8 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr
private int maxSessionsPerRegularUser; private int maxSessionsPerRegularUser;
@Value("${server.ws.limits.max_sessions_per_public_user:0}") @Value("${server.ws.limits.max_sessions_per_public_user:0}")
private int maxSessionsPerPublicUser; private int maxSessionsPerPublicUser;
@Value("${server.ws.limits.max_queue_per_ws_session:1000}")
private int maxMsgQueuePerSession;
@Value("${server.ws.limits.max_updates_per_session:}") @Value("${server.ws.limits.max_updates_per_session:}")
private String perSessionUpdatesConfiguration; private String perSessionUpdatesConfiguration;
@ -119,7 +121,7 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr
if (!checkLimits(session, sessionRef)) { if (!checkLimits(session, sessionRef)) {
return; return;
} }
internalSessionMap.put(internalSessionId, new SessionMetaData(session, sessionRef)); internalSessionMap.put(internalSessionId, new SessionMetaData(session, sessionRef, maxMsgQueuePerSession));
externalSessionMap.put(externalSessionId, internalSessionId); externalSessionMap.put(externalSessionId, internalSessionId);
processInWebSocketService(sessionRef, SessionEvent.onEstablished()); processInWebSocketService(sessionRef, SessionEvent.onEstablished());
log.info("[{}][{}][{}] Session is opened", sessionRef.getSecurityCtx().getTenantId(), externalSessionId, session.getId()); log.info("[{}][{}][{}] Session is opened", sessionRef.getSecurityCtx().getTenantId(), externalSessionId, session.getId());
@ -181,26 +183,35 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr
} }
} }
private static class SessionMetaData implements SendHandler { private class SessionMetaData implements SendHandler {
private final WebSocketSession session; private final WebSocketSession session;
private final RemoteEndpoint.Async asyncRemote; private final RemoteEndpoint.Async asyncRemote;
private final TelemetryWebSocketSessionRef sessionRef; private final TelemetryWebSocketSessionRef sessionRef;
private volatile boolean isSending = false; private volatile boolean isSending = false;
private final Queue<String> msgQueue;
private Queue<String> msgQueue = new LinkedBlockingQueue<>(); SessionMetaData(WebSocketSession session, TelemetryWebSocketSessionRef sessionRef, int maxMsgQueuePerSession) {
SessionMetaData(WebSocketSession session, TelemetryWebSocketSessionRef sessionRef) {
super(); super();
this.session = session; this.session = session;
Session nativeSession = ((NativeWebSocketSession) session).getNativeSession(Session.class); Session nativeSession = ((NativeWebSocketSession) session).getNativeSession(Session.class);
this.asyncRemote = nativeSession.getAsyncRemote(); this.asyncRemote = nativeSession.getAsyncRemote();
this.sessionRef = sessionRef; this.sessionRef = sessionRef;
this.msgQueue = new LinkedBlockingQueue<>(maxMsgQueuePerSession);
} }
public synchronized void sendMsg(String msg) { synchronized void sendMsg(String msg) {
if (isSending) { if (isSending) {
try {
msgQueue.add(msg); msgQueue.add(msg);
} catch (RuntimeException e){
log.trace("[{}] Session closed due to queue error", session.getId(), e);
try {
close(sessionRef, CloseStatus.POLICY_VIOLATION.withReason("Max pending updates limit reached!"));
} catch (IOException ioe) {
log.trace("[{}] Session transport error", session.getId(), ioe);
}
}
} else { } else {
isSending = true; isSending = true;
sendMsgInternal(msg); sendMsgInternal(msg);

View File

@ -40,6 +40,7 @@ server:
max_sessions_per_customer: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_CUSTOMER:0}" max_sessions_per_customer: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_CUSTOMER:0}"
max_sessions_per_regular_user: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_REGULAR_USER:0}" max_sessions_per_regular_user: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_REGULAR_USER:0}"
max_sessions_per_public_user: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_PUBLIC_USER:0}" max_sessions_per_public_user: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_PUBLIC_USER:0}"
max_queue_per_ws_session: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_QUEUE_PER_WS_SESSION:500}"
max_subscriptions_per_tenant: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_TENANT:0}" max_subscriptions_per_tenant: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_TENANT:0}"
max_subscriptions_per_customer: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_CUSTOMER:0}" max_subscriptions_per_customer: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_CUSTOMER:0}"
max_subscriptions_per_regular_user: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_REGULAR_USER:0}" max_subscriptions_per_regular_user: "${TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_REGULAR_USER:0}"