Skip to content

Update throttler to 700ms in IndexManager.java#15501

Open
ThiloteE wants to merge 1 commit intoJabRef:mainfrom
ThiloteE:ThiloteE-2026-04-06-IndexThrottlerValue
Open

Update throttler to 700ms in IndexManager.java#15501
ThiloteE wants to merge 1 commit intoJabRef:mainfrom
ThiloteE:ThiloteE-2026-04-06-IndexThrottlerValue

Conversation

@ThiloteE
Copy link
Copy Markdown
Member

@ThiloteE ThiloteE commented Apr 6, 2026

Related issues and pull requests

Follow up to #15289 (comment)

PR Description

Delays indexing for 700ms.

Reasoning:

Suggested change

    this.indexUpdateThrottler = taskExecutor.createThrottler(200);

If this is comparable to a 200 ms delay, then I would suggest at least 700 ms.

200ms would require a typing speed of 300 characters per minute to not trigger an indexing, which is what I personally can do when I type really fast, but I know from experience that the average persons typing speed is much slower (Once upon a time, I taught some kids and after half a year the fastest was only able to exceed 100 characters per minute).

60 seconds divided by 300 characters = 0.2 seconds per character
60 seconds divided by 100 characters = 0.6 seconds per character

Steps to test

  1. Have automatic search groups
  2. Have entries with groups
  3. Type something in a field of one of the entries
  4. Wait 700ms

Expected result: See that indexing is delayed.

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • [/] I added JUnit tests for changes (if applicable)
  • [/] I added screenshots in the PR description (if change is visible to the user)
  • [/] I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • [/] I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • [/] I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@ThiloteE ThiloteE marked this pull request as ready for review April 6, 2026 00:54
@qodo-free-for-open-source-projects
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Increase index throttle delay to 700ms

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Increases index update throttle delay from 200ms to 700ms
• Accommodates average typing speeds for better indexing performance
• Prevents excessive indexing triggers during rapid text input
Diagram
flowchart LR
  A["IndexManager initialization"] -- "createThrottler parameter" --> B["200ms throttle"]
  B -- "updated to" --> C["700ms throttle"]
  C -- "reduces indexing frequency" --> D["Better performance"]
Loading

Grey Divider

File Changes

1. jablib/src/main/java/org/jabref/logic/search/IndexManager.java ✨ Enhancement +1/-1

Increase throttler delay to 700ms

• Updated indexUpdateThrottler creation parameter from 200ms to 700ms
• Aligns throttle delay with average user typing speeds
• Reduces unnecessary indexing operations during text input

jablib/src/main/java/org/jabref/logic/search/IndexManager.java


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown
Contributor

qodo-free-for-open-source-projects bot commented Apr 6, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider


Action required

1. Throttler not stopped on close 🐞 Bug ☼ Reliability
Description
IndexManager.updateEntry schedules delayed indexing via indexUpdateThrottler, but
IndexManager.close()/closeAndWait() never cancel or shut down the throttler. With the new 700ms
delay, scheduled updates are more likely to run after bibFieldsIndexer/linkedFilesIndexer are
closed, producing SQL errors and leaking the throttler’s ScheduledThreadPoolExecutor thread.
Code

jablib/src/main/java/org/jabref/logic/search/IndexManager.java[88]

+        this.indexUpdateThrottler = taskExecutor.createThrottler(700);
Evidence
The constructor creates a DelayTaskThrottler with the new 700ms delay, and updateEntry schedules
work on it. However, close()/closeAndWait() only close indexers and remove listeners; they do not
cancel/shutdown the throttler. DelayTaskThrottler uses its own ScheduledThreadPoolExecutor and will
run scheduled commands after the delay; those commands call BibFieldsIndexer.updateEntry, which uses
a JDBC connection that BibFieldsIndexer.closeIndex closes. LibraryTab/SaveDatabaseAction call
IndexManager.close as part of normal UI lifecycle, so this can occur during regular close/save-as
flows.

jablib/src/main/java/org/jabref/logic/search/IndexManager.java[65-90]
jablib/src/main/java/org/jabref/logic/search/IndexManager.java[170-223]
jablib/src/main/java/org/jabref/logic/search/IndexManager.java[237-249]
jablib/src/main/java/org/jabref/logic/util/DelayTaskThrottler.java[12-45]
jablib/src/main/java/org/jabref/logic/search/indexing/BibFieldsIndexer.java[300-305]
jablib/src/main/java/org/jabref/logic/search/indexing/BibFieldsIndexer.java[416-437]
jabgui/src/main/java/org/jabref/gui/LibraryTab.java[706-727]
jabgui/src/main/java/org/jabref/gui/exporter/SaveDatabaseAction.java[133-163]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`IndexManager` schedules delayed indexing work via `indexUpdateThrottler`, but `close()` / `closeAndWait()` never cancel or shut down the throttler. After increasing the delay to 700ms, there is a larger window where a scheduled task can execute after the indexers have been closed, resulting in indexing work running against closed resources (e.g., closed JDBC connection) and leaving the throttler thread alive.

## Issue Context
- `updateEntry(...)` uses `indexUpdateThrottler.schedule(...)` to execute indexing later.
- `DelayTaskThrottler` owns a `ScheduledThreadPoolExecutor` that must be shut down.
- `IndexManager.close()` is called when a library tab is closed / during save-as, without shutting down the shared `TaskExecutor`.

## Fix Focus Areas
- Add throttler cleanup in `IndexManager.close()` and `IndexManager.closeAndWait()` (cancel pending work and shut down the throttler, ideally without blocking the UI thread in `close()`).
- Optionally guard `updateEntry(...)` with a `closed` flag to avoid scheduling after close.

### Suggested approach
- In `close()`:
 - `indexUpdateThrottler.cancel();`
 - Offload `indexUpdateThrottler.shutdown()` to a background executor (to avoid up to ~15s blocking from `awaitTermination`).
- In `closeAndWait()`:
 - `indexUpdateThrottler.cancel();`
 - Call `indexUpdateThrottler.shutdown()` directly (since this path is explicitly waiting).

## Fix Focus Areas (code pointers)
- jablib/src/main/java/org/jabref/logic/search/IndexManager.java[170-223]
- jablib/src/main/java/org/jabref/logic/search/IndexManager.java[237-249]
- jablib/src/main/java/org/jabref/logic/util/DelayTaskThrottler.java[36-75]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

this.bibFieldsSearcher = new BibFieldsSearcher(postgreServer.getConnection(), bibFieldsIndexer.getTable());
this.linkedFilesSearcher = new LinkedFilesSearcher(databaseContext, linkedFilesIndexer, preferences.getFilePreferences());
this.indexUpdateThrottler = taskExecutor.createThrottler(200);
this.indexUpdateThrottler = taskExecutor.createThrottler(700);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Throttler not stopped on close 🐞 Bug ☼ Reliability

IndexManager.updateEntry schedules delayed indexing via indexUpdateThrottler, but
IndexManager.close()/closeAndWait() never cancel or shut down the throttler. With the new 700ms
delay, scheduled updates are more likely to run after bibFieldsIndexer/linkedFilesIndexer are
closed, producing SQL errors and leaking the throttler’s ScheduledThreadPoolExecutor thread.
Agent Prompt
## Issue description
`IndexManager` schedules delayed indexing work via `indexUpdateThrottler`, but `close()` / `closeAndWait()` never cancel or shut down the throttler. After increasing the delay to 700ms, there is a larger window where a scheduled task can execute after the indexers have been closed, resulting in indexing work running against closed resources (e.g., closed JDBC connection) and leaving the throttler thread alive.

## Issue Context
- `updateEntry(...)` uses `indexUpdateThrottler.schedule(...)` to execute indexing later.
- `DelayTaskThrottler` owns a `ScheduledThreadPoolExecutor` that must be shut down.
- `IndexManager.close()` is called when a library tab is closed / during save-as, without shutting down the shared `TaskExecutor`.

## Fix Focus Areas
- Add throttler cleanup in `IndexManager.close()` and `IndexManager.closeAndWait()` (cancel pending work and shut down the throttler, ideally without blocking the UI thread in `close()`).
- Optionally guard `updateEntry(...)` with a `closed` flag to avoid scheduling after close.

### Suggested approach
- In `close()`:
  - `indexUpdateThrottler.cancel();`
  - Offload `indexUpdateThrottler.shutdown()` to a background executor (to avoid up to ~15s blocking from `awaitTermination`).
- In `closeAndWait()`:
  - `indexUpdateThrottler.cancel();`
  - Call `indexUpdateThrottler.shutdown()` directly (since this path is explicitly waiting).

## Fix Focus Areas (code pointers)
- jablib/src/main/java/org/jabref/logic/search/IndexManager.java[170-223]
- jablib/src/main/java/org/jabref/logic/search/IndexManager.java[237-249]
- jablib/src/main/java/org/jabref/logic/util/DelayTaskThrottler.java[36-75]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant