From 54c52db3607bcc52d75909dab88e7d8085f04fd4 Mon Sep 17 00:00:00 2001 From: Ruslan Date: Sat, 24 Aug 2024 15:46:07 +0300 Subject: [PATCH 1/4] Refine ProgressCounter (#11671) * Refine ProgressCounter * Revert PROGRESS_MESSAGES --- .../logic/ai/GenerateEmbeddingsTask.java | 2 ++ .../ai/models/UpdateEmbeddingModelTask.java | 2 ++ .../ai/summarization/GenerateSummaryTask.java | 2 ++ .../jabref/logic/util/ProgressCounter.java | 34 +++++++++++++------ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jabref/logic/ai/GenerateEmbeddingsTask.java b/src/main/java/org/jabref/logic/ai/GenerateEmbeddingsTask.java index 8f825ff5426..0ec89939626 100644 --- a/src/main/java/org/jabref/logic/ai/GenerateEmbeddingsTask.java +++ b/src/main/java/org/jabref/logic/ai/GenerateEmbeddingsTask.java @@ -65,6 +65,8 @@ protected Void call() throws Exception { LOGGER.info("Finished embeddings generation task for entry {}", citationKey); + progressCounter.stop(); + return null; } diff --git a/src/main/java/org/jabref/logic/ai/models/UpdateEmbeddingModelTask.java b/src/main/java/org/jabref/logic/ai/models/UpdateEmbeddingModelTask.java index 63da2d1c870..0a487aeccb6 100644 --- a/src/main/java/org/jabref/logic/ai/models/UpdateEmbeddingModelTask.java +++ b/src/main/java/org/jabref/logic/ai/models/UpdateEmbeddingModelTask.java @@ -74,6 +74,8 @@ public Void call() { throw new RuntimeException(Localization.lang("An I/O error occurred while opening the embedding model by URL %0", modelUrl), e); } + progressCounter.stop(); + return null; } diff --git a/src/main/java/org/jabref/logic/ai/summarization/GenerateSummaryTask.java b/src/main/java/org/jabref/logic/ai/summarization/GenerateSummaryTask.java index ee33d3822d3..c99076a3653 100644 --- a/src/main/java/org/jabref/logic/ai/summarization/GenerateSummaryTask.java +++ b/src/main/java/org/jabref/logic/ai/summarization/GenerateSummaryTask.java @@ -98,6 +98,8 @@ protected Void call() throws Exception { LOGGER.info("Finished summarization task for entry {}", citationKey); + progressCounter.stop(); + return null; } diff --git a/src/main/java/org/jabref/logic/util/ProgressCounter.java b/src/main/java/org/jabref/logic/util/ProgressCounter.java index 32974741eeb..06093c09044 100644 --- a/src/main/java/org/jabref/logic/util/ProgressCounter.java +++ b/src/main/java/org/jabref/logic/util/ProgressCounter.java @@ -4,6 +4,8 @@ import java.time.Instant; import java.util.List; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ReadOnlyStringProperty; import javafx.beans.property.SimpleIntegerProperty; @@ -28,14 +30,24 @@ private record ProgressMessage(int maxTime, String message) { } new ProgressMessage(Integer.MAX_VALUE, Localization.lang("Estimated time left: more than 2 minutes.")) ); + private static final Duration PERIODIC_UPDATE_DURATION = Duration.ofSeconds(PROGRESS_MESSAGES.getFirst().maxTime); + private final IntegerProperty workDone = new SimpleIntegerProperty(0); private final IntegerProperty workMax = new SimpleIntegerProperty(0); private final StringProperty message = new SimpleStringProperty(""); - private Instant oneWorkTimeStart = Instant.now(); - private Duration lastEtaCalculation = Duration.ofDays(1); + // Progress counter is updated on two events: + // 1) When workDone or workMax changes: this in normal behavior. + // 2) When PERIODIC_UPDATE_DURATION passes: it is used in situations where one piece of work takes too much time + // (and so there are no events 1), and so the message could be "approx. 5 seconds", while it should be more. + private final Timeline periodicUpdate = new Timeline(new KeyFrame(new javafx.util.Duration(PERIODIC_UPDATE_DURATION.getSeconds() * 1000), e -> update())); + + private final Instant workStartTime = Instant.now(); public ProgressCounter() { + periodicUpdate.setCycleCount(Timeline.INDEFINITE); + periodicUpdate.play(); + workDone.addListener(obs -> update()); workMax.addListener(obs -> update()); } @@ -79,16 +91,14 @@ public void listenToAllProperties(Runnable runnable) { } private void update() { - Instant oneWorkTimeEnd = Instant.now(); - Duration duration = Duration.between(oneWorkTimeStart, oneWorkTimeEnd); - oneWorkTimeStart = oneWorkTimeEnd; + Duration workTime = Duration.between(workStartTime, Instant.now()); + Duration oneWorkTime = workTime.dividedBy(workDone.get() == 0 ? 1 : workDone.get()); + Duration eta = oneWorkTime.multipliedBy(workMax.get() - workDone.get() <= 0 ? 1 : workMax.get() - workDone.get()); - Duration eta = duration.multipliedBy(workMax.get() - workDone.get()); + updateMessage(eta); - if (lastEtaCalculation.minus(eta).isPositive()) { - updateMessage(eta); - - lastEtaCalculation = eta; + if (workDone.get() != 0 && workMax.get() != 0 && workDone.get() == workMax.get()) { + stop(); } } @@ -128,4 +138,8 @@ private void updateMessage(Duration eta) { } } } + + public void stop() { + periodicUpdate.stop(); + } } From de1b0a17da6645ba49dfad38d7ab84c8d6056457 Mon Sep 17 00:00:00 2001 From: Ruslan Date: Sat, 24 Aug 2024 15:47:30 +0300 Subject: [PATCH 2/4] Improve AI preferences UI and add temperature help (#11670) * Improve AI preferences UI and add temperature help * Fix checkstyle --- .../org/jabref/gui/preferences/ai/AiTab.fxml | 314 ++++++++++++------ .../org/jabref/gui/preferences/ai/AiTab.java | 6 +- .../java/org/jabref/logic/help/HelpFile.java | 5 +- 3 files changed, 213 insertions(+), 112 deletions(-) diff --git a/src/main/java/org/jabref/gui/preferences/ai/AiTab.fxml b/src/main/java/org/jabref/gui/preferences/ai/AiTab.fxml index faa1105338e..9115ba3b394 100644 --- a/src/main/java/org/jabref/gui/preferences/ai/AiTab.fxml +++ b/src/main/java/org/jabref/gui/preferences/ai/AiTab.fxml @@ -9,151 +9,249 @@ - + + + -