Tyler Gorton 2 weeks ago
committed by GitHub
parent
commit
11ec2d6635
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 39
      application/src/main/java/org/thingsboard/server/config/AsyncConfig.java
  2. 42
      dao/src/main/java/org/thingsboard/server/dao/device/AsyncDeviceEventPublisher.java
  3. 17
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

39
application/src/main/java/org/thingsboard/server/config/AsyncConfig.java

@ -0,0 +1,39 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean("deviceEventExecutor")
public Executor deviceEventExecutor() {
ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor();
exec.setCorePoolSize(2);
exec.setMaxPoolSize(5);
exec.setQueueCapacity(100);
exec.setThreadNamePrefix("device-event-");
exec.initialize();
return exec;
}
}

42
dao/src/main/java/org/thingsboard/server/dao/device/AsyncDeviceEventPublisher.java

@ -0,0 +1,42 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.device;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.thingsboard.server.cache.device.DeviceCacheEvictEvent;
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
@Service
public class AsyncDeviceEventPublisher {
private final ApplicationEventPublisher publisher;
public AsyncDeviceEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Async("deviceEventExecutor")
public void publishCacheEvictEventAsync(DeviceCacheEvictEvent event) {
publisher.publishEvent(event);
}
@Async("deviceEventExecutor")
public void publishSaveEventAsync(SaveEntityEvent event) {
publisher.publishEvent(event);
}
}

17
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -22,9 +22,11 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.cache.device.DeviceCacheEvictEvent;
@ -119,6 +121,9 @@ public class DeviceServiceImpl extends CachedVersionedEntityService<DeviceCacheK
private final EntityCountService countService;
private final JpaExecutorService executor;
@Autowired
private AsyncDeviceEventPublisher asyncDeviceEventPublisher;
@Override
public DeviceInfo findDeviceInfoById(TenantId tenantId, DeviceId deviceId) {
log.trace("Executing findDeviceInfoById [{}]", deviceId);
@ -215,6 +220,15 @@ public class DeviceServiceImpl extends CachedVersionedEntityService<DeviceCacheK
return savedDevice;
}
@Override
protected void publishEvictEvent(DeviceCacheEvictEvent event) {
if (TransactionSynchronizationManager.isActualTransactionActive()) {
asyncDeviceEventPublisher.publishCacheEvictEventAsync(event);
} else {
handleEvictEvent(event);
}
}
private Device doSaveDevice(Device device, String accessToken, boolean doValidate) {
return doSaveDevice(device, accessToken, doValidate, NameConflictStrategy.DEFAULT);
}
@ -271,7 +285,8 @@ public class DeviceServiceImpl extends CachedVersionedEntityService<DeviceCacheK
if (device.getId() == null) {
countService.publishCountEntityEvictEvent(savedDevice.getTenantId(), EntityType.DEVICE);
}
eventPublisher.publishEvent(SaveEntityEvent.builder().tenantId(savedDevice.getTenantId()).entityId(savedDevice.getId())
asyncDeviceEventPublisher.publishSaveEventAsync(SaveEntityEvent.builder().tenantId(savedDevice.getTenantId()).entityId(savedDevice.getId())
.entity(savedDevice).oldEntity(oldDevice).created(device.getId() == null).build());
return savedDevice;
} catch (Exception t) {

Loading…
Cancel
Save