mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
Cache safe call proxies for profiles instead of continuously recreating them (#1880)
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
+34
-10
@@ -12,9 +12,11 @@
|
||||
*/
|
||||
package org.openhab.core.thing.internal;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
@@ -26,6 +28,7 @@ import javax.measure.Quantity;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.cache.ExpiringCacheMap;
|
||||
import org.openhab.core.common.AbstractUID;
|
||||
import org.openhab.core.common.SafeCaller;
|
||||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
@@ -88,6 +91,9 @@ import org.slf4j.LoggerFactory;
|
||||
@Component(service = { EventSubscriber.class, CommunicationManager.class }, immediate = true)
|
||||
public class CommunicationManager implements EventSubscriber, RegistryChangeListener<ItemChannelLink> {
|
||||
|
||||
// how long to cache profile safe call instances
|
||||
private static final Duration CACHE_EXPIRATION = Duration.ofMinutes(30);
|
||||
|
||||
// the timeout to use for any item event processing
|
||||
public static final long THINGHANDLER_EVENT_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
|
||||
|
||||
@@ -106,6 +112,8 @@ public class CommunicationManager implements EventSubscriber, RegistryChangeList
|
||||
private final SafeCaller safeCaller;
|
||||
private final ThingRegistry thingRegistry;
|
||||
|
||||
private final ExpiringCacheMap<Integer, Profile> profileSafeCallCache = new ExpiringCacheMap<>(CACHE_EXPIRATION);
|
||||
|
||||
@Activate
|
||||
public CommunicationManager(final @Reference AutoUpdateManager autoUpdateManager,
|
||||
final @Reference ChannelTypeRegistry channelTypeRegistry,
|
||||
@@ -282,11 +290,19 @@ public class CommunicationManager implements EventSubscriber, RegistryChangeList
|
||||
handleEvent(itemName, command, commandEvent.getSource(), s -> acceptedCommandTypeMap.get(s),
|
||||
(profile, thing, convertedCommand) -> {
|
||||
if (profile instanceof StateProfile) {
|
||||
safeCaller.create(((StateProfile) profile), StateProfile.class) //
|
||||
.withAsync() //
|
||||
.withIdentifier(thing) //
|
||||
.withTimeout(THINGHANDLER_EVENT_TIMEOUT) //
|
||||
.build().onCommandFromItem(convertedCommand);
|
||||
int key = Objects.hash("COMMAND", profile, thing);
|
||||
Profile p = profileSafeCallCache.putIfAbsentAndGet(key, () -> {
|
||||
return safeCaller.create(((StateProfile) profile), StateProfile.class) //
|
||||
.withAsync() //
|
||||
.withIdentifier(thing) //
|
||||
.withTimeout(THINGHANDLER_EVENT_TIMEOUT) //
|
||||
.build();
|
||||
});
|
||||
if (p instanceof StateProfile) {
|
||||
((StateProfile) p).onCommandFromItem(convertedCommand);
|
||||
} else {
|
||||
throw new IllegalStateException("Expiringcache didn't provide a StateProfile instance!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -296,11 +312,19 @@ public class CommunicationManager implements EventSubscriber, RegistryChangeList
|
||||
final State newState = updateEvent.getItemState();
|
||||
handleEvent(itemName, newState, updateEvent.getSource(), s -> acceptedStateTypeMap.get(s),
|
||||
(profile, thing, convertedState) -> {
|
||||
safeCaller.create(profile, Profile.class) //
|
||||
.withAsync() //
|
||||
.withIdentifier(thing) //
|
||||
.withTimeout(THINGHANDLER_EVENT_TIMEOUT) //
|
||||
.build().onStateUpdateFromItem(convertedState);
|
||||
int key = Objects.hash("UPDATE", profile, thing);
|
||||
Profile p = profileSafeCallCache.putIfAbsentAndGet(key, () -> {
|
||||
return safeCaller.create(profile, Profile.class) //
|
||||
.withAsync() //
|
||||
.withIdentifier(thing) //
|
||||
.withTimeout(THINGHANDLER_EVENT_TIMEOUT) //
|
||||
.build();
|
||||
});
|
||||
if (p != null) {
|
||||
p.onStateUpdateFromItem(convertedState);
|
||||
} else {
|
||||
throw new IllegalStateException("Expiringcache didn't provide a Profile instance!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user