update platform and gradle

This commit is contained in:
Carsten Otto
2025-02-16 13:45:35 +01:00
parent c79f920d1a
commit 6a84e71532
12 changed files with 64 additions and 25 deletions

View File

@@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.BiFunction;
import static de.cotto.lndmanagej.configuration.PickhardtPaymentsConfigurationSettings.LIQUIDITY_INFORMATION_MAX_AGE;
@@ -34,6 +35,7 @@ public class LiquidityBoundsService {
private static final Duration DEFAULT_MAX_AGE = Duration.of(10, ChronoUnit.MINUTES);
private final MissionControlService missionControlService;
private final Map<TwoPubkeys, LiquidityBoundsWithTimestamp> entries;
private final ReentrantLock entriesLock = new ReentrantLock();
private final ConfigurationService configurationService;
private final LoadingCache<Object, Duration> maxAgeCache = new CacheBuilder()
.withRefresh(Duration.ofSeconds(5))
@@ -107,9 +109,12 @@ public class LiquidityBoundsService {
BiFunction<LiquidityBounds, Coins, Optional<LiquidityBounds>> function
) {
TwoPubkeys twoPubkeys = new TwoPubkeys(source, target);
synchronized (this.entries) {
entriesLock.lock();
try {
Optional<LiquidityBounds> updated = function.apply(getInfo(twoPubkeys), amount);
updated.ifPresent(liquidityBounds -> setInfo(twoPubkeys, liquidityBounds));
} finally {
entriesLock.unlock();
}
}

View File

@@ -122,7 +122,7 @@ public class OnlinePeersService {
}
private int getRoundedPercentage(Duration total, Duration offline) {
return (int) (offline.getSeconds() * 100.0 / total.getSeconds());
return (int) (offline.toSeconds() * 100.0 / total.toSeconds());
}
private int getChangesWithoutCache(Pubkey pubkey) {

View File

@@ -84,7 +84,7 @@ class BalancesDaoImpl implements BalancesDao {
if (!first || open) {
long satoshis = balances.balanceInformation().localBalance().satoshis();
Duration duration = Duration.between(timestamp, previous);
long minutes = duration.getSeconds() / 60;
long minutes = duration.toSeconds() / 60;
totalSatoshis += satoshis * minutes;
totalMinutes += minutes;
}

View File

@@ -8,7 +8,7 @@ repositories {
dependencies {
implementation(platform("de.c-otto.lndmanagej:platform"))
implementation("de.c-otto:java-conventions:2024.06.07")
implementation("de.c-otto:java-conventions:2025.02.16")
implementation("org.springframework.boot:spring-boot-gradle-plugin")
implementation("com.google.protobuf:protobuf-gradle-plugin")
}

View File

@@ -54,6 +54,6 @@ public class ForwardingEventsDaoImpl implements ForwardingEventsDao {
}
private long getAfterEpochMilliSeconds(Duration maxAge) {
return Instant.now().toEpochMilli() - maxAge.getSeconds() * 1_000;
return Instant.now().toEpochMilli() - maxAge.toSeconds() * 1_000;
}
}

View File

@@ -24,5 +24,6 @@ dependencies {
api("io.grpc:grpc-stub:$grpcVersion")
api("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
api("io.vavr:vavr:0.10.4")
api("javax.annotation:javax.annotation-api:1.3.2")
}
}

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@@ -76,6 +76,6 @@ public class SettledInvoicesDaoImpl implements SettledInvoicesDao {
}
private long getAfterEpochSeconds(Duration maxAge) {
return Instant.now().toEpochMilli() / 1_000 - maxAge.getSeconds();
return Instant.now().toEpochMilli() / 1_000 - maxAge.toSeconds();
}
}

View File

@@ -9,12 +9,13 @@ import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@Component
public class Payments {
private final GrpcPayments grpcPayments;
private final PaymentsDao dao;
private static final Object SAVE_PAYMENTS_LOCK = new Object();
private static final ReentrantLock SAVE_PAYMENTS_LOCK = new ReentrantLock();
public Payments(GrpcPayments grpcPayments, PaymentsDao dao) {
this.grpcPayments = grpcPayments;
@@ -25,9 +26,12 @@ public class Payments {
public void loadNewSettledPayments() {
List<Payment> payments;
do {
synchronized (SAVE_PAYMENTS_LOCK) {
SAVE_PAYMENTS_LOCK.lock();
try {
payments = grpcPayments.getCompletePaymentsAfter(dao.getIndexOffset()).orElse(List.of());
dao.save(payments);
} finally {
SAVE_PAYMENTS_LOCK.unlock();
}
} while (payments.size() == grpcPayments.getLimit());
}
@@ -37,7 +41,8 @@ public class Payments {
List<Optional<Payment>> paymentOptionals;
OptionalLong maxIndex;
do {
synchronized (SAVE_PAYMENTS_LOCK) {
SAVE_PAYMENTS_LOCK.lock();
try {
long offsetSettledPayments = dao.getAllSettledIndexOffset();
long offsetKnownPayments = dao.getIndexOffset();
if (offsetKnownPayments == offsetSettledPayments) {
@@ -48,6 +53,8 @@ public class Payments {
maxIndex = getMaxIndexAllSettled(paymentOptionals);
dao.save(paymentOptionals.stream().flatMap(Optional::stream).toList());
maxIndex.ifPresent(dao::setAllSettledIndexOffset);
} finally {
SAVE_PAYMENTS_LOCK.unlock();
}
} while (paymentOptionals.size() == grpcPayments.getLimit() && maxIndex.isPresent());
}

View File

@@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
public class PaymentStatus extends Flux<InstantWithString> {
private boolean success;
@@ -22,6 +23,7 @@ public class PaymentStatus extends Flux<InstantWithString> {
private int numberOfAttemptedRoutes;
private final List<InstantWithString> allMessages;
private final List<PaymentStatusSubscription> subscriptions;
private final ReentrantLock lock = new ReentrantLock();
public PaymentStatus() {
super();
@@ -42,26 +44,35 @@ public class PaymentStatus extends Flux<InstantWithString> {
}
public void settled() {
synchronized (this) {
lock.lock();
try {
addMessage("Settled");
success = true;
subscriptions.forEach(PaymentStatusSubscription::onComplete);
} finally {
lock.unlock();
}
}
public void failed(FailureCode failureCode) {
synchronized (this) {
lock.lock();
try {
addMessage("Failed with " + failureCode.toString());
failure = true;
subscriptions.forEach(PaymentStatusSubscription::onComplete);
} finally {
lock.unlock();
}
}
public void failed(String message) {
synchronized (this) {
lock.lock();
try {
addMessage(message);
failure = true;
subscriptions.forEach(PaymentStatusSubscription::onComplete);
} finally {
lock.unlock();
}
}
@@ -93,9 +104,12 @@ public class PaymentStatus extends Flux<InstantWithString> {
private void addMessage(String message) {
InstantWithString messageWithTimestamp = new InstantWithString(message);
synchronized (this) {
lock.lock();
try {
allMessages.add(messageWithTimestamp);
subscriptions.forEach(paymentStatusSubscription -> paymentStatusSubscription.onNext(messageWithTimestamp));
} finally {
lock.unlock();
}
}
@@ -133,9 +147,12 @@ public class PaymentStatus extends Flux<InstantWithString> {
public void subscribe(@Nonnull CoreSubscriber<? super InstantWithString> subscriber) {
PaymentStatusSubscription subscription =
new PaymentStatusSubscription(subscriber, new ArrayList<>(allMessages));
synchronized (this) {
lock.lock();
try {
subscriber.onSubscribe(subscription);
subscriptions.add(subscription);
} finally {
lock.unlock();
}
if (isFailure() || isSuccess()) {
subscription.onComplete();
@@ -164,6 +181,7 @@ public class PaymentStatus extends Flux<InstantWithString> {
}
private class PaymentStatusSubscription implements Subscription {
private final ReentrantLock lock = new ReentrantLock();
private final Subscriber<? super InstantWithString> subscriber;
private final List<InstantWithString> messagesForSubscriber;
private long requested;
@@ -179,9 +197,12 @@ public class PaymentStatus extends Flux<InstantWithString> {
@Override
public void request(long numberOfMessages) {
synchronized (this) {
lock.lock();
try {
requested += numberOfMessages;
sendRequestedMessages();
} finally {
lock.unlock();
}
}
@@ -199,9 +220,12 @@ public class PaymentStatus extends Flux<InstantWithString> {
}
public void onNext(InstantWithString message) {
synchronized (this) {
lock.lock();
try {
messagesForSubscriber.add(message);
sendRequestedMessages();
} finally {
lock.unlock();
}
}

View File

@@ -14,6 +14,7 @@ import org.junit.jupiter.api.Test;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;
import static de.cotto.lndmanagej.ReactiveStreamReader.readAll;
import static de.cotto.lndmanagej.ReactiveStreamReader.readMessages;
@@ -248,6 +249,10 @@ class PaymentStatusTest {
@Test
void testEquals() {
EqualsVerifier.simple().forClass(PaymentStatus.class).verify();
EqualsVerifier.simple()
.forClass(PaymentStatus.class)
.withPrefabValues(ReentrantLock.class, new ReentrantLock(), new ReentrantLock())
.withIgnoredFields("lock")
.verify();
}
}

View File

@@ -14,7 +14,8 @@ public record BalanceInformationModel(
) {
private static final int TEN_PERCENT = 10;
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###");
private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT =
ThreadLocal.withInitial(() -> new DecimalFormat("###"));
public static final BalanceInformationModel EMPTY = createFromModel(BalanceInformation.EMPTY);
public static BalanceInformationModel createFromModel(BalanceInformation balanceInformation) {
@@ -44,15 +45,11 @@ public record BalanceInformationModel(
public String getOutboundPercentageLabel() {
double outbound = getOutboundPercentage();
synchronized (DECIMAL_FORMAT) {
return outbound < TEN_PERCENT ? "" : DECIMAL_FORMAT.format(outbound) + "%";
}
return outbound < TEN_PERCENT ? "" : DECIMAL_FORMAT.get().format(outbound) + "%";
}
public String getInboundPercentageLabel() {
double inbound = getInboundPercentage();
synchronized (DECIMAL_FORMAT) {
return inbound < TEN_PERCENT ? "" : DECIMAL_FORMAT.format(inbound) + "%";
}
return inbound < TEN_PERCENT ? "" : DECIMAL_FORMAT.get().format(inbound) + "%";
}
}