From 9e6cb5e500d536a37116a45c4fd5edbe10e8571a Mon Sep 17 00:00:00 2001 From: Carsten Otto Date: Fri, 5 Nov 2021 18:28:02 +0100 Subject: [PATCH] cache node information --- .../cotto/lndmanagej/grpc/GrpcNodeInfo.java | 29 ++++++++++++++++++- .../de/cotto/lndmanagej/grpc/GrpcService.java | 4 +-- .../lndmanagej/grpc/GrpcNodeInfoTest.java | 10 ++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcNodeInfo.java b/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcNodeInfo.java index dcc58620..1f1a27b2 100644 --- a/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcNodeInfo.java +++ b/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcNodeInfo.java @@ -1,20 +1,47 @@ package de.cotto.lndmanagej.grpc; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import de.cotto.lndmanagej.model.Node; import lnrpc.LightningNode; import lnrpc.NodeInfo; import org.springframework.stereotype.Component; +import javax.annotation.Nonnull; +import java.util.concurrent.TimeUnit; + @Component public class GrpcNodeInfo { + private static final int MAXIMUM_SIZE = 500; + private static final int CACHE_EXPIRY_MINUTES = 30; + private final GrpcService grpcService; + private final LoadingCache cache; public GrpcNodeInfo(GrpcService grpcService) { this.grpcService = grpcService; + CacheLoader loader = new CacheLoader<>() { + @Override + public Node load(@Nonnull String pubkey) { + return getNodeWithoutCache(pubkey); + } + }; + cache = CacheBuilder.newBuilder() + .expireAfterWrite(CACHE_EXPIRY_MINUTES, TimeUnit.MINUTES) + .maximumSize(MAXIMUM_SIZE) + .build(loader); } public Node getNode(String pubkey) { - NodeInfo nodeInfo = grpcService.getNodeInfo(pubkey); + return cache.getUnchecked(pubkey); + } + + private Node getNodeWithoutCache(String pubkey) { + NodeInfo nodeInfo = grpcService.getNodeInfo(pubkey).orElse(null); + if (nodeInfo == null) { + return Node.builder().withPubkey(pubkey).build(); + } LightningNode node = nodeInfo.getNode(); return Node.builder() .withPubkey(pubkey) diff --git a/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcService.java b/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcService.java index 584d21aa..e65eff32 100644 --- a/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcService.java +++ b/grpc-adapter/src/main/java/de/cotto/lndmanagej/grpc/GrpcService.java @@ -70,7 +70,7 @@ public class GrpcService { .orElse(List.of()); } - public NodeInfo getNodeInfo(String pubkey) { - return lightningStub.getNodeInfo(NodeInfoRequest.newBuilder().setPubKey(pubkey).build()); + public Optional getNodeInfo(String pubkey) { + return get(() -> lightningStub.getNodeInfo(NodeInfoRequest.newBuilder().setPubKey(pubkey).build())); } } diff --git a/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcNodeInfoTest.java b/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcNodeInfoTest.java index 63d3f2d2..abdaa57f 100644 --- a/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcNodeInfoTest.java +++ b/grpc-adapter/src/test/java/de/cotto/lndmanagej/grpc/GrpcNodeInfoTest.java @@ -9,6 +9,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.Optional; + import static de.cotto.lndmanagej.model.NodeFixtures.NODE; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; @@ -27,7 +29,7 @@ class GrpcNodeInfoTest { .setAlias(NODE.alias()) .setLastUpdate(NODE.lastUpdate()) .build()); - when(grpcService.getNodeInfo(NODE.pubkey())).thenReturn(node.build()); + when(grpcService.getNodeInfo(NODE.pubkey())).thenReturn(Optional.of(node.build())); } @Test @@ -44,4 +46,10 @@ class GrpcNodeInfoTest { void getNode_sets_last_update() { assertThat(grpcNodeInfo.getNode(NODE.pubkey()).lastUpdate()).isEqualTo(NODE.lastUpdate()); } + + @Test + void getNode_error() { + when(grpcService.getNodeInfo(NODE.pubkey())).thenReturn(Optional.empty()); + assertThat(grpcNodeInfo.getNode(NODE.pubkey()).alias()).isEqualTo(NODE.pubkey()); + } } \ No newline at end of file