thingsboard设备状态更新可能导致的不一致性问腿
2023-02-18 15:41:36 时间
thingboard的概述这里就不再赘述,直接入主题讨论下thingsboard设备状态更新可能存在的不一致性问题,thingsboard有一个周期性执行的任务,该任务在DefaultDeviceStateService类的updateInactivityStateIfExpired,该任务用于更新设备的在线离线状态,当设备长时间不与tb进行交互的情况下,该任务就可以将设备的状态更新为离线。
下面看下可能存在问题的代码:
void updateInactivityStateIfExpired(long ts, DeviceId deviceId, DeviceStateData stateData) {
log.trace("Processing state {} for device {}", stateData, deviceId);
if (stateData != null) {
DeviceState state = stateData.getState();
if (!isActive(ts, state)
&& (state.getLastInactivityAlarmTime() == 0L || state.getLastInactivityAlarmTime() < state.getLastActivityTime())
&& stateData.getDeviceCreationTime() + state.getInactivityTimeout() < ts) {
if (partitionService.resolve(ServiceType.TB_CORE, stateData.getTenantId(), deviceId).isMyPartition()) {
state.setActive(false);
state.setLastInactivityAlarmTime(ts);
save(deviceId, ACTIVITY_STATE, false);
save(deviceId, INACTIVITY_ALARM_TIME, ts);
pushRuleEngineMessage(stateData, INACTIVITY_EVENT);
} else {
cleanupEntity(deviceId);
}
}
} else {
log.debug("[{}] Device that belongs to other server is detected and removed.", deviceId);
cleanupEntity(deviceId);
}
}
boolean isActive(long ts, DeviceState state) {
return ts < state.getLastActivityTime() + state.getInactivityTimeout();
}
从上面代码可以tb原有代码在更新设备在线状态与设备离线时间是分成两步的,在特殊情况下可能存在更新设备状态失败但是更新设备离线时间成功的情况,毕竟不在一个事务中,这样导致的情况就是设备离线时间更新了,但是设备状态却仍然为在线状态。
这样导致的情况就是即使tb的任务想要把设备状态更新为离线,但是因为
state.getLastInactivityAlarmTime() == 0L || state.getLastInactivityAlarmTime() < state.getLastActivityTime()
永远为false而导致设备状态永远无法更新。
笔者给出一种解决方案:
在之前条件的基础上再增加一个条件:
boolean cond1 = state.isOnline() && state.getLastInactivityAlarmTime() > state.getLastActivityTime();
使用上述条件与tb原有的条件进行或操作就可以解决极端情况下设备状态永远无法离线的问题。
相关文章
- NDK开发(三) :JNI访问Java变量和方法
- NDK开发(四) :JNI操作Java数组
- NDK开发(五) :JNI实现文件加解密
- NDK开发(六) :JNI实现文件拆分和合并
- NDK开发(七) :JNI实现文件夹遍历
- NDK开发(八) :JNI下Bitmap的使用
- NDK开发(九) :Hello jniCallback
- NDK开发(十) :Hello OpenGLES3
- 利用ClassLoader实现检查项目中不符合规范的代码
- okhttp的使用介绍
- okhttp之OkHttpClient
- okhttp之Request
- okhttp之RealCall.execute()流程介绍
- okhttp之五个拦截器的介绍
- okhttp之自定义拦截器
- okhttp之Dispatcher
- okhttp之Connection
- okhttp之ConnectionPool
- okhttp之StreamAllocation
- Java虚拟机运行时数据区介绍