Performance Improvement for Device State Service

This commit is contained in:
Andrew Shvayka 2019-12-20 15:58:55 +02:00
parent cacdf09eef
commit 95752ff3b9

View File

@ -141,6 +141,8 @@ public class DefaultDeviceStateService implements DeviceStateService {
private ListeningScheduledExecutorService queueExecutor; private ListeningScheduledExecutorService queueExecutor;
private ConcurrentMap<TenantId, Set<DeviceId>> tenantDevices = new ConcurrentHashMap<>(); private ConcurrentMap<TenantId, Set<DeviceId>> tenantDevices = new ConcurrentHashMap<>();
private ConcurrentMap<DeviceId, DeviceStateData> deviceStates = new ConcurrentHashMap<>(); private ConcurrentMap<DeviceId, DeviceStateData> deviceStates = new ConcurrentHashMap<>();
private ConcurrentMap<DeviceId, Long> deviceLastReportedActivity = new ConcurrentHashMap<>();
private ConcurrentMap<DeviceId, Long> deviceLastSavedActivity = new ConcurrentHashMap<>();
@PostConstruct @PostConstruct
public void init() { public void init() {
@ -175,6 +177,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
@Override @Override
public void onDeviceActivity(DeviceId deviceId) { public void onDeviceActivity(DeviceId deviceId) {
deviceLastReportedActivity.put(deviceId, System.currentTimeMillis());
queueExecutor.submit(() -> onDeviceActivitySync(deviceId)); queueExecutor.submit(() -> onDeviceActivitySync(deviceId));
} }
@ -245,6 +248,8 @@ public class DefaultDeviceStateService implements DeviceStateService {
tenantDeviceSet.remove(device.getId()); tenantDeviceSet.remove(device.getId());
} }
deviceStates.remove(device.getId()); deviceStates.remove(device.getId());
deviceLastReportedActivity.remove(device.getId());
deviceLastSavedActivity.remove(device.getId());
} }
} }
try { try {
@ -305,6 +310,8 @@ public class DefaultDeviceStateService implements DeviceStateService {
} else { } else {
log.debug("[{}] Device that belongs to other server is detected and removed.", deviceId); log.debug("[{}] Device that belongs to other server is detected and removed.", deviceId);
deviceStates.remove(deviceId); deviceStates.remove(deviceId);
deviceLastReportedActivity.remove(deviceId);
deviceLastSavedActivity.remove(deviceId);
} }
} }
} }
@ -330,20 +337,23 @@ public class DefaultDeviceStateService implements DeviceStateService {
} }
private void onDeviceActivitySync(DeviceId deviceId) { private void onDeviceActivitySync(DeviceId deviceId) {
long lastReportedActivity = deviceLastReportedActivity.getOrDefault(deviceId, 0L);
long lastSavedActivity = deviceLastSavedActivity.getOrDefault(deviceId, 0L);
if (lastReportedActivity > 0 && lastReportedActivity > lastSavedActivity) {
DeviceStateData stateData = getOrFetchDeviceStateData(deviceId); DeviceStateData stateData = getOrFetchDeviceStateData(deviceId);
if (stateData != null) { if (stateData != null) {
DeviceState state = stateData.getState(); DeviceState state = stateData.getState();
long ts = System.currentTimeMillis(); stateData.getState().setLastActivityTime(lastReportedActivity);
stateData.getState().setLastActivityTime(ts);
pushRuleEngineMessage(stateData, ACTIVITY_EVENT); pushRuleEngineMessage(stateData, ACTIVITY_EVENT);
save(deviceId, LAST_ACTIVITY_TIME, ts); save(deviceId, LAST_ACTIVITY_TIME, lastReportedActivity);
deviceLastSavedActivity.put(deviceId, lastReportedActivity);
if (!state.isActive()) { if (!state.isActive()) {
state.setActive(true); state.setActive(true);
save(deviceId, ACTIVITY_STATE, state.isActive()); save(deviceId, ACTIVITY_STATE, state.isActive());
} }
} }
} }
}
private DeviceStateData getOrFetchDeviceStateData(DeviceId deviceId) { private DeviceStateData getOrFetchDeviceStateData(DeviceId deviceId) {
DeviceStateData deviceStateData = deviceStates.get(deviceId); DeviceStateData deviceStateData = deviceStates.get(deviceId);
@ -431,6 +441,8 @@ public class DefaultDeviceStateService implements DeviceStateService {
Optional<ServerAddress> address = routingService.resolveById(deviceId); Optional<ServerAddress> address = routingService.resolveById(deviceId);
if (!address.isPresent()) { if (!address.isPresent()) {
deviceStates.remove(deviceId); deviceStates.remove(deviceId);
deviceLastReportedActivity.remove(deviceId);
deviceLastSavedActivity.remove(deviceId);
Set<DeviceId> deviceIds = tenantDevices.get(tenantId); Set<DeviceId> deviceIds = tenantDevices.get(tenantId);
if (deviceIds != null) { if (deviceIds != null) {
deviceIds.remove(deviceId); deviceIds.remove(deviceId);