Refactoring of device creation using gateway

This commit is contained in:
Andrii Shvaika 2020-04-29 10:02:00 +03:00
parent 79b4411c69
commit a38ee80e09

View File

@ -54,6 +54,8 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by ashvayka on 19.01.17.
@ -69,6 +71,7 @@ public class GatewaySessionHandler {
private final TransportService transportService;
private final DeviceInfoProto gateway;
private final UUID sessionId;
private final Lock deviceCreationLock = new ReentrantLock();
private final ConcurrentMap<String, GatewayDeviceSessionCtx> devices;
private final ConcurrentMap<String, SettableFuture<GatewayDeviceSessionCtx>> deviceFutures;
private final ConcurrentMap<MqttTopicMatcher, Integer> mqttQoSMap;
@ -108,15 +111,29 @@ public class GatewaySessionHandler {
}
private ListenableFuture<GatewayDeviceSessionCtx> onDeviceConnect(String deviceName, String deviceType) {
SettableFuture<GatewayDeviceSessionCtx> future;
GatewayDeviceSessionCtx result = devices.get(deviceName);
if (result == null) {
synchronized (deviceFutures) {
future = deviceFutures.get(deviceName);
deviceCreationLock.lock();
try {
result = devices.get(deviceName);
if (result == null) {
return getDeviceCreationFuture(deviceName, deviceType);
} else {
return toCompletedFuture(result);
}
} finally {
deviceCreationLock.unlock();
}
} else {
return toCompletedFuture(result);
}
}
private ListenableFuture<GatewayDeviceSessionCtx> getDeviceCreationFuture(String deviceName, String deviceType) {
SettableFuture<GatewayDeviceSessionCtx> future = deviceFutures.get(deviceName);
if (future == null) {
final SettableFuture<GatewayDeviceSessionCtx> futureToSet = SettableFuture.create();
deviceFutures.put(deviceName, futureToSet);
future = futureToSet;
try {
transportService.process(GetOrCreateDeviceFromGatewayRequestMsg.newBuilder()
.setDeviceName(deviceName)
@ -145,16 +162,19 @@ public class GatewaySessionHandler {
deviceFutures.remove(deviceName);
}
});
return futureToSet;
} catch (Throwable e) {
deviceFutures.remove(deviceName);
throw e;
}
}
}
} else {
future = SettableFuture.create();
future.set(result);
return future;
}
}
private ListenableFuture<GatewayDeviceSessionCtx> toCompletedFuture(GatewayDeviceSessionCtx result) {
SettableFuture<GatewayDeviceSessionCtx> future = SettableFuture.create();
future.set(result);
return future;
}