Commit 3f97bb682a04c25a64a221b07fc6f4a048a99ede

Authored by Sergey Matvienko
1 parent 193c0ce6

executors: names added, shutdownNow for some executors to prevent memory leaks d…

…uring lifecycle (mostly affects the test runner JVM)
@@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.beans.factory.annotation.Value; 23 import org.springframework.beans.factory.annotation.Value;
24 import org.springframework.context.annotation.Lazy; 24 import org.springframework.context.annotation.Lazy;
25 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
  26 +import org.thingsboard.common.util.ThingsBoardExecutors;
26 import org.thingsboard.common.util.ThingsBoardThreadFactory; 27 import org.thingsboard.common.util.ThingsBoardThreadFactory;
27 import org.thingsboard.rule.engine.api.MailService; 28 import org.thingsboard.rule.engine.api.MailService;
28 import org.thingsboard.server.common.data.ApiFeature; 29 import org.thingsboard.server.common.data.ApiFeature;
@@ -486,7 +487,7 @@ public class DefaultTbApiUsageStateService extends TbApplicationEventListener<Pa @@ -486,7 +487,7 @@ public class DefaultTbApiUsageStateService extends TbApplicationEventListener<Pa
486 log.info("Initializing tenant states."); 487 log.info("Initializing tenant states.");
487 updateLock.lock(); 488 updateLock.lock();
488 try { 489 try {
489 - ExecutorService tmpInitExecutor = Executors.newWorkStealingPool(20); 490 + ExecutorService tmpInitExecutor = ThingsBoardExecutors.newWorkStealingPool(20, "init-tenant-states-from-db");
490 try { 491 try {
491 PageDataIterable<Tenant> tenantIterator = new PageDataIterable<>(tenantService::findTenants, 1024); 492 PageDataIterable<Tenant> tenantIterator = new PageDataIterable<>(tenantService::findTenants, 1024);
492 List<Future<?>> futures = new ArrayList<>(); 493 List<Future<?>> futures = new ArrayList<>();
@@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode; @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
  22 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
22 import org.thingsboard.server.common.data.edge.Edge; 23 import org.thingsboard.server.common.data.edge.Edge;
23 import org.thingsboard.server.common.data.edge.EdgeEvent; 24 import org.thingsboard.server.common.data.edge.EdgeEvent;
24 import org.thingsboard.server.common.data.edge.EdgeEventActionType; 25 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
@@ -79,7 +80,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { @@ -79,7 +80,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService {
79 80
80 @PostConstruct 81 @PostConstruct
81 public void initExecutor() { 82 public void initExecutor() {
82 - tsCallBackExecutor = Executors.newSingleThreadExecutor(); 83 + tsCallBackExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("edge-notifications"));
83 } 84 }
84 85
85 @PreDestroy 86 @PreDestroy
@@ -23,6 +23,7 @@ import org.eclipse.leshan.core.node.LwM2mResource; @@ -23,6 +23,7 @@ import org.eclipse.leshan.core.node.LwM2mResource;
23 import org.eclipse.leshan.core.response.ExecuteResponse; 23 import org.eclipse.leshan.core.response.ExecuteResponse;
24 import org.eclipse.leshan.core.response.ReadResponse; 24 import org.eclipse.leshan.core.response.ReadResponse;
25 import org.eclipse.leshan.core.response.WriteResponse; 25 import org.eclipse.leshan.core.response.WriteResponse;
  26 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
26 27
27 import javax.security.auth.Destroyable; 28 import javax.security.auth.Destroyable;
28 import java.util.Arrays; 29 import java.util.Arrays;
@@ -37,7 +38,7 @@ public class FwLwM2MDevice extends BaseInstanceEnabler implements Destroyable { @@ -37,7 +38,7 @@ public class FwLwM2MDevice extends BaseInstanceEnabler implements Destroyable {
37 38
38 private static final List<Integer> supportedResources = Arrays.asList(0, 1, 2, 3, 5, 6, 7, 9); 39 private static final List<Integer> supportedResources = Arrays.asList(0, 1, 2, 3, 5, 6, 7, 9);
39 40
40 - private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 41 + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName()));
41 42
42 private final AtomicInteger state = new AtomicInteger(0); 43 private final AtomicInteger state = new AtomicInteger(0);
43 44
@@ -24,6 +24,7 @@ import org.eclipse.leshan.core.node.LwM2mResource; @@ -24,6 +24,7 @@ import org.eclipse.leshan.core.node.LwM2mResource;
24 import org.eclipse.leshan.core.response.ExecuteResponse; 24 import org.eclipse.leshan.core.response.ExecuteResponse;
25 import org.eclipse.leshan.core.response.ReadResponse; 25 import org.eclipse.leshan.core.response.ReadResponse;
26 import org.eclipse.leshan.core.response.WriteResponse; 26 import org.eclipse.leshan.core.response.WriteResponse;
  27 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
27 28
28 import javax.security.auth.Destroyable; 29 import javax.security.auth.Destroyable;
29 import java.util.Arrays; 30 import java.util.Arrays;
@@ -38,7 +39,7 @@ public class SwLwM2MDevice extends BaseInstanceEnabler implements Destroyable { @@ -38,7 +39,7 @@ public class SwLwM2MDevice extends BaseInstanceEnabler implements Destroyable {
38 39
39 private static final List<Integer> supportedResources = Arrays.asList(0, 1, 2, 3, 4, 6, 7, 9); 40 private static final List<Integer> supportedResources = Arrays.asList(0, 1, 2, 3, 4, 6, 7, 9);
40 41
41 - private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); 42 + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName()));
42 43
43 private final AtomicInteger state = new AtomicInteger(0); 44 private final AtomicInteger state = new AtomicInteger(0);
44 45
@@ -17,10 +17,12 @@ package org.thingsboard.server.util; @@ -17,10 +17,12 @@ package org.thingsboard.server.util;
17 17
18 import com.google.common.util.concurrent.MoreExecutors; 18 import com.google.common.util.concurrent.MoreExecutors;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
  20 +import org.junit.After;
20 import org.junit.Test; 21 import org.junit.Test;
21 import org.junit.runner.RunWith; 22 import org.junit.runner.RunWith;
22 import org.mockito.Mockito; 23 import org.mockito.Mockito;
23 import org.mockito.junit.MockitoJUnitRunner; 24 import org.mockito.junit.MockitoJUnitRunner;
  25 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
24 import org.thingsboard.server.utils.EventDeduplicationExecutor; 26 import org.thingsboard.server.utils.EventDeduplicationExecutor;
25 27
26 import java.util.concurrent.ExecutorService; 28 import java.util.concurrent.ExecutorService;
@@ -31,6 +33,16 @@ import java.util.function.Consumer; @@ -31,6 +33,16 @@ import java.util.function.Consumer;
31 @RunWith(MockitoJUnitRunner.class) 33 @RunWith(MockitoJUnitRunner.class)
32 public class EventDeduplicationExecutorTest { 34 public class EventDeduplicationExecutorTest {
33 35
  36 + ThingsBoardThreadFactory threadFactory = ThingsBoardThreadFactory.forName(getClass().getSimpleName());
  37 + ExecutorService executor;
  38 +
  39 + @After
  40 + public void tearDown() throws Exception {
  41 + if (executor != null) {
  42 + executor.shutdownNow();
  43 + }
  44 + }
  45 +
34 @Test 46 @Test
35 public void testSimpleFlowSameThread() throws InterruptedException { 47 public void testSimpleFlowSameThread() throws InterruptedException {
36 simpleFlow(MoreExecutors.newDirectExecutorService()); 48 simpleFlow(MoreExecutors.newDirectExecutorService());
@@ -48,32 +60,38 @@ public class EventDeduplicationExecutorTest { @@ -48,32 +60,38 @@ public class EventDeduplicationExecutorTest {
48 60
49 @Test 61 @Test
50 public void testSimpleFlowSingleThread() throws InterruptedException { 62 public void testSimpleFlowSingleThread() throws InterruptedException {
51 - simpleFlow(Executors.newSingleThreadExecutor()); 63 + executor = Executors.newSingleThreadExecutor(threadFactory);
  64 + simpleFlow(executor);
52 } 65 }
53 66
54 @Test 67 @Test
55 public void testPeriodicFlowSingleThread() throws InterruptedException { 68 public void testPeriodicFlowSingleThread() throws InterruptedException {
56 - periodicFlow(Executors.newSingleThreadExecutor()); 69 + executor = Executors.newSingleThreadExecutor(threadFactory);
  70 + periodicFlow(executor);
57 } 71 }
58 72
59 @Test 73 @Test
60 public void testExceptionFlowSingleThread() throws InterruptedException { 74 public void testExceptionFlowSingleThread() throws InterruptedException {
61 - exceptionFlow(Executors.newSingleThreadExecutor()); 75 + executor = Executors.newSingleThreadExecutor(threadFactory);
  76 + exceptionFlow(executor);
62 } 77 }
63 78
64 @Test 79 @Test
65 public void testSimpleFlowMultiThread() throws InterruptedException { 80 public void testSimpleFlowMultiThread() throws InterruptedException {
66 - simpleFlow(Executors.newFixedThreadPool(3)); 81 + executor = Executors.newFixedThreadPool(3, threadFactory);
  82 + simpleFlow(executor);
67 } 83 }
68 84
69 @Test 85 @Test
70 public void testPeriodicFlowMultiThread() throws InterruptedException { 86 public void testPeriodicFlowMultiThread() throws InterruptedException {
71 - periodicFlow(Executors.newFixedThreadPool(3)); 87 + executor = Executors.newFixedThreadPool(3, threadFactory);
  88 + periodicFlow(executor);
72 } 89 }
73 90
74 @Test 91 @Test
75 public void testExceptionFlowMultiThread() throws InterruptedException { 92 public void testExceptionFlowMultiThread() throws InterruptedException {
76 - exceptionFlow(Executors.newFixedThreadPool(3)); 93 + executor = Executors.newFixedThreadPool(3, threadFactory);
  94 + exceptionFlow(executor);
77 } 95 }
78 96
79 private void simpleFlow(ExecutorService executorService) throws InterruptedException { 97 private void simpleFlow(ExecutorService executorService) throws InterruptedException {
@@ -22,6 +22,8 @@ import org.junit.Before; @@ -22,6 +22,8 @@ import org.junit.Before;
22 import org.junit.Test; 22 import org.junit.Test;
23 import org.junit.runner.RunWith; 23 import org.junit.runner.RunWith;
24 import org.mockito.junit.MockitoJUnitRunner; 24 import org.mockito.junit.MockitoJUnitRunner;
  25 +import org.thingsboard.common.util.ThingsBoardExecutors;
  26 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
25 import org.thingsboard.server.common.data.id.DeviceId; 27 import org.thingsboard.server.common.data.id.DeviceId;
26 28
27 import java.util.ArrayList; 29 import java.util.ArrayList;
@@ -45,6 +47,7 @@ public class ActorSystemTest { @@ -45,6 +47,7 @@ public class ActorSystemTest {
45 47
46 private volatile TbActorSystem actorSystem; 48 private volatile TbActorSystem actorSystem;
47 private volatile ExecutorService submitPool; 49 private volatile ExecutorService submitPool;
  50 + private ExecutorService executor;
48 private int parallelism; 51 private int parallelism;
49 52
50 @Before 53 @Before
@@ -60,47 +63,57 @@ public class ActorSystemTest { @@ -60,47 +63,57 @@ public class ActorSystemTest {
60 public void shutdownActorSystem() { 63 public void shutdownActorSystem() {
61 actorSystem.stop(); 64 actorSystem.stop();
62 submitPool.shutdownNow(); 65 submitPool.shutdownNow();
  66 + if (executor != null) {
  67 + executor.shutdownNow();
  68 + }
63 } 69 }
64 70
65 @Test 71 @Test
66 public void test1actorsAnd100KMessages() throws InterruptedException { 72 public void test1actorsAnd100KMessages() throws InterruptedException {
67 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 73 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  74 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
68 testActorsAndMessages(1, _100K, 1); 75 testActorsAndMessages(1, _100K, 1);
69 } 76 }
70 77
71 @Test 78 @Test
72 public void test10actorsAnd100KMessages() throws InterruptedException { 79 public void test10actorsAnd100KMessages() throws InterruptedException {
73 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 80 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  81 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
74 testActorsAndMessages(10, _100K, 1); 82 testActorsAndMessages(10, _100K, 1);
75 } 83 }
76 84
77 @Test 85 @Test
78 public void test100KActorsAnd1Messages5timesSingleThread() throws InterruptedException { 86 public void test100KActorsAnd1Messages5timesSingleThread() throws InterruptedException {
79 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newSingleThreadExecutor()); 87 + executor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName()));
  88 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
80 testActorsAndMessages(_100K, 1, 5); 89 testActorsAndMessages(_100K, 1, 5);
81 } 90 }
82 91
83 @Test 92 @Test
84 public void test100KActorsAnd1Messages5times() throws InterruptedException { 93 public void test100KActorsAnd1Messages5times() throws InterruptedException {
85 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 94 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  95 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
86 testActorsAndMessages(_100K, 1, 5); 96 testActorsAndMessages(_100K, 1, 5);
87 } 97 }
88 98
89 @Test 99 @Test
90 public void test100KActorsAnd10Messages() throws InterruptedException { 100 public void test100KActorsAnd10Messages() throws InterruptedException {
91 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 101 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  102 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
92 testActorsAndMessages(_100K, 10, 1); 103 testActorsAndMessages(_100K, 10, 1);
93 } 104 }
94 105
95 @Test 106 @Test
96 public void test1KActorsAnd1KMessages() throws InterruptedException { 107 public void test1KActorsAnd1KMessages() throws InterruptedException {
97 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 108 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  109 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
98 testActorsAndMessages(1000, 1000, 10); 110 testActorsAndMessages(1000, 1000, 10);
99 } 111 }
100 112
101 @Test 113 @Test
102 public void testNoMessagesAfterDestroy() throws InterruptedException { 114 public void testNoMessagesAfterDestroy() throws InterruptedException {
103 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 115 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  116 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
104 ActorTestCtx testCtx1 = getActorTestCtx(1); 117 ActorTestCtx testCtx1 = getActorTestCtx(1);
105 ActorTestCtx testCtx2 = getActorTestCtx(1); 118 ActorTestCtx testCtx2 = getActorTestCtx(1);
106 119
@@ -119,7 +132,8 @@ public class ActorSystemTest { @@ -119,7 +132,8 @@ public class ActorSystemTest {
119 132
120 @Test 133 @Test
121 public void testOneActorCreated() throws InterruptedException { 134 public void testOneActorCreated() throws InterruptedException {
122 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 135 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  136 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
123 ActorTestCtx testCtx1 = getActorTestCtx(1); 137 ActorTestCtx testCtx1 = getActorTestCtx(1);
124 ActorTestCtx testCtx2 = getActorTestCtx(1); 138 ActorTestCtx testCtx2 = getActorTestCtx(1);
125 TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID())); 139 TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID()));
@@ -145,7 +159,8 @@ public class ActorSystemTest { @@ -145,7 +159,8 @@ public class ActorSystemTest {
145 159
146 @Test 160 @Test
147 public void testActorCreatorCalledOnce() throws InterruptedException { 161 public void testActorCreatorCalledOnce() throws InterruptedException {
148 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 162 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  163 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
149 ActorTestCtx testCtx = getActorTestCtx(1); 164 ActorTestCtx testCtx = getActorTestCtx(1);
150 TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID())); 165 TbActorId actorId = new TbEntityActorId(new DeviceId(UUID.randomUUID()));
151 final int actorsCount = 1000; 166 final int actorsCount = 1000;
@@ -169,7 +184,8 @@ public class ActorSystemTest { @@ -169,7 +184,8 @@ public class ActorSystemTest {
169 184
170 @Test 185 @Test
171 public void testFailedInit() throws InterruptedException { 186 public void testFailedInit() throws InterruptedException {
172 - actorSystem.createDispatcher(ROOT_DISPATCHER, Executors.newWorkStealingPool(parallelism)); 187 + executor = ThingsBoardExecutors.newWorkStealingPool(parallelism, getClass());
  188 + actorSystem.createDispatcher(ROOT_DISPATCHER, executor);
173 ActorTestCtx testCtx1 = getActorTestCtx(1); 189 ActorTestCtx testCtx1 = getActorTestCtx(1);
174 ActorTestCtx testCtx2 = getActorTestCtx(1); 190 ActorTestCtx testCtx2 = getActorTestCtx(1);
175 191
@@ -24,6 +24,7 @@ import org.eclipse.californium.scandium.DTLSConnector; @@ -24,6 +24,7 @@ import org.eclipse.californium.scandium.DTLSConnector;
24 import org.eclipse.californium.scandium.config.DtlsConnectorConfig; 24 import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
25 import org.springframework.beans.factory.annotation.Autowired; 25 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.stereotype.Component; 26 import org.springframework.stereotype.Component;
  27 +import org.thingsboard.common.util.ThingsBoardThreadFactory;
27 28
28 import javax.annotation.PostConstruct; 29 import javax.annotation.PostConstruct;
29 import javax.annotation.PreDestroy; 30 import javax.annotation.PreDestroy;
@@ -118,7 +119,7 @@ public class DefaultCoapServerService implements CoapServerService { @@ -118,7 +119,7 @@ public class DefaultCoapServerService implements CoapServerService {
118 CoapEndpoint dtlsCoapEndpoint = dtlsCoapEndpointBuilder.build(); 119 CoapEndpoint dtlsCoapEndpoint = dtlsCoapEndpointBuilder.build();
119 server.addEndpoint(dtlsCoapEndpoint); 120 server.addEndpoint(dtlsCoapEndpoint);
120 tbDtlsCertificateVerifier = (TbCoapDtlsCertificateVerifier) dtlsConnectorConfig.getAdvancedCertificateVerifier(); 121 tbDtlsCertificateVerifier = (TbCoapDtlsCertificateVerifier) dtlsConnectorConfig.getAdvancedCertificateVerifier();
121 - dtlsSessionsExecutor = Executors.newSingleThreadScheduledExecutor(); 122 + dtlsSessionsExecutor = Executors.newSingleThreadScheduledExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName()));
122 dtlsSessionsExecutor.scheduleAtFixedRate(this::evictTimeoutSessions, new Random().nextInt((int) getDtlsSessionReportTimeout()), getDtlsSessionReportTimeout(), TimeUnit.MILLISECONDS); 123 dtlsSessionsExecutor.scheduleAtFixedRate(this::evictTimeoutSessions, new Random().nextInt((int) getDtlsSessionReportTimeout()), getDtlsSessionReportTimeout(), TimeUnit.MILLISECONDS);
123 } 124 }
124 Resource root = server.getRoot(); 125 Resource root = server.getRoot();
@@ -34,6 +34,7 @@ import org.snmp4j.transport.DefaultTcpTransportMapping; @@ -34,6 +34,7 @@ import org.snmp4j.transport.DefaultTcpTransportMapping;
34 import org.snmp4j.transport.DefaultUdpTransportMapping; 34 import org.snmp4j.transport.DefaultUdpTransportMapping;
35 import org.springframework.beans.factory.annotation.Value; 35 import org.springframework.beans.factory.annotation.Value;
36 import org.springframework.stereotype.Service; 36 import org.springframework.stereotype.Service;
  37 +import org.thingsboard.common.util.ThingsBoardExecutors;
37 import org.thingsboard.common.util.ThingsBoardThreadFactory; 38 import org.thingsboard.common.util.ThingsBoardThreadFactory;
38 import org.thingsboard.server.common.data.DataConstants; 39 import org.thingsboard.server.common.data.DataConstants;
39 import org.thingsboard.server.common.data.TbTransportService; 40 import org.thingsboard.server.common.data.TbTransportService;
@@ -90,7 +91,7 @@ public class SnmpTransportService implements TbTransportService { @@ -90,7 +91,7 @@ public class SnmpTransportService implements TbTransportService {
90 @PostConstruct 91 @PostConstruct
91 private void init() throws IOException { 92 private void init() throws IOException {
92 queryingExecutor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("snmp-querying")); 93 queryingExecutor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("snmp-querying"));
93 - responseProcessingExecutor = Executors.newWorkStealingPool(responseProcessingParallelismLevel); 94 + responseProcessingExecutor = ThingsBoardExecutors.newWorkStealingPool(responseProcessingParallelismLevel, "snmp-response-processing");
94 95
95 initializeSnmp(); 96 initializeSnmp();
96 configureResponseDataMappers(); 97 configureResponseDataMappers();
@@ -99,6 +100,16 @@ public class SnmpTransportService implements TbTransportService { @@ -99,6 +100,16 @@ public class SnmpTransportService implements TbTransportService {
99 log.info("SNMP transport service initialized"); 100 log.info("SNMP transport service initialized");
100 } 101 }
101 102
  103 + @PreDestroy
  104 + public void stop() {
  105 + if (queryingExecutor != null) {
  106 + queryingExecutor.shutdownNow();
  107 + }
  108 + if (responseProcessingExecutor != null) {
  109 + responseProcessingExecutor.shutdownNow();
  110 + }
  111 + }
  112 +
102 private void initializeSnmp() throws IOException { 113 private void initializeSnmp() throws IOException {
103 TransportMapping<?> transportMapping; 114 TransportMapping<?> transportMapping;
104 switch (snmpUnderlyingProtocol) { 115 switch (snmpUnderlyingProtocol) {
@@ -263,7 +263,7 @@ public class MqttClientTest extends AbstractContainerTest { @@ -263,7 +263,7 @@ public class MqttClientTest extends AbstractContainerTest {
263 JsonObject serverRpcPayload = new JsonObject(); 263 JsonObject serverRpcPayload = new JsonObject();
264 serverRpcPayload.addProperty("method", "getValue"); 264 serverRpcPayload.addProperty("method", "getValue");
265 serverRpcPayload.addProperty("params", true); 265 serverRpcPayload.addProperty("params", true);
266 - ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()); 266 + ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName())));
267 ListenableFuture<ResponseEntity> future = service.submit(() -> { 267 ListenableFuture<ResponseEntity> future = service.submit(() -> {
268 try { 268 try {
269 return restClient.getRestTemplate() 269 return restClient.getRestTemplate()
@@ -287,6 +287,7 @@ public class MqttClientTest extends AbstractContainerTest { @@ -287,6 +287,7 @@ public class MqttClientTest extends AbstractContainerTest {
287 mqttClient.publish("v1/devices/me/rpc/response/" + requestId, Unpooled.wrappedBuffer(clientResponse.toString().getBytes())).get(); 287 mqttClient.publish("v1/devices/me/rpc/response/" + requestId, Unpooled.wrappedBuffer(clientResponse.toString().getBytes())).get();
288 288
289 ResponseEntity serverResponse = future.get(5, TimeUnit.SECONDS); 289 ResponseEntity serverResponse = future.get(5, TimeUnit.SECONDS);
  290 + service.shutdownNow();
290 Assert.assertTrue(serverResponse.getStatusCode().is2xxSuccessful()); 291 Assert.assertTrue(serverResponse.getStatusCode().is2xxSuccessful());
291 Assert.assertEquals(clientResponse.toString(), serverResponse.getBody()); 292 Assert.assertEquals(clientResponse.toString(), serverResponse.getBody());
292 293
@@ -259,7 +259,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest { @@ -259,7 +259,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
259 JsonObject serverRpcPayload = new JsonObject(); 259 JsonObject serverRpcPayload = new JsonObject();
260 serverRpcPayload.addProperty("method", "getValue"); 260 serverRpcPayload.addProperty("method", "getValue");
261 serverRpcPayload.addProperty("params", true); 261 serverRpcPayload.addProperty("params", true);
262 - ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()); 262 + ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName())));
263 ListenableFuture<ResponseEntity> future = service.submit(() -> { 263 ListenableFuture<ResponseEntity> future = service.submit(() -> {
264 try { 264 try {
265 return restClient.getRestTemplate() 265 return restClient.getRestTemplate()
@@ -273,6 +273,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest { @@ -273,6 +273,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
273 273
274 // Wait for RPC call from the server and send the response 274 // Wait for RPC call from the server and send the response
275 MqttEvent requestFromServer = listener.getEvents().poll(10, TimeUnit.SECONDS); 275 MqttEvent requestFromServer = listener.getEvents().poll(10, TimeUnit.SECONDS);
  276 + service.shutdownNow();
276 277
277 Assert.assertNotNull(requestFromServer); 278 Assert.assertNotNull(requestFromServer);
278 Assert.assertNotNull(requestFromServer.getMessage()); 279 Assert.assertNotNull(requestFromServer.getMessage());