dotCMS / dotCMS/core

IndiciesInfo.Builder.copy() silently drops reindexLive

Open Beginner friendly
#37,283 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Team : Maintenance
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Summary

IndiciesInfo.Builder.copy() copies four of the five index pointers and omits reindexLive. Every caller that uses it to make a "modified copy" of the current pointers therefore nulls the reindex-live slot as a side effect.

Affected version

26.08.03-01 (code path unchanged on main at time of writing)

Code

public static Builder copy(final IndiciesInfo info) {
    final IndiciesInfo.Builder builder = new IndiciesInfo.Builder();
    builder.setWorking(info.getWorking());
    builder.setLive(info.getLive());
    builder.setReindexWorking(info.getReindexWorking());
    builder.setSiteSearch(info.getSiteSearch());
    // setReindexLive(info.getReindexLive()) is missing
    return builder;
}

Callers in ContentletIndexAPIImpl: activateIndex, deactivateIndex, clearEsStorePointer. Each does Builder.copy(info), mutates one slot, and calls legacyIndiciesAPI.point(builder.build()).

That the omission is unintended is visible at the call sites, which explicitly clear reindexLive only under a condition — implying they expect copy() to have preserved it otherwise:

} else if (IndexType.LIVE.is(indexName)) {
    builder.setLive(indexAPI.getNameWithClusterIDPrefix(indexName));
    if (indexAPI.getNameWithClusterIDPrefix(indexName).equals(info.getReindexLive())) {
        builder.setReindexLive(null);
    }
}

Impact

Activating or deactivating any index while a full reindex is in flight silently clears reindexLive. Consequences:

  • isInFullReindex() is reindexWorking != null && reindexLive != null, so it flips to false mid-reindex.
  • In addBulkRequestToProcessor, live documents then route to the old live index rather than the reindex target, because the branch is guarded on indices.reindexLive == null.
  • ReindexThread.finalizeReIndex() pauses the thread when !isInFullReindex().

Not the cause of the incident this was found during, but it is a real one-line defect on a path operators use during exactly the kind of index maintenance where a reindex may be running.

Suggested fix

Add the missing line:

builder.setReindexLive(info.getReindexLive());

Worth a regression test asserting Builder.copy(info) round-trips all five slots.

Related

Found while investigating #37279, #37280, #37281, #37282 — not part of that failure chain.

Related Freshdesk ticket: https://helpdesk.dotcms.com/a/tickets/38957

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at IndiciesInfo.Builder.copy() and inspect its callers in ContentletIndexAPIImpl, especially activateIndex, deactivateIndex, and clearEsStorePointer. Verify the reindexLive pointer is preserved during modified copies, add a regression test that round-trips all five slots, and confirm the reindex state remains intact while index maintenance runs.

Written by the indexing model from the issue text.

Assessment

Tech stack
elasticsearch, java
Domain
backend, search
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.