This is an automated email from the ASF dual-hosted git repository.
mridulpathak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git
The following commit(s) were added to refs/heads/trunk by this push:
new 2afd9f164 Fixed: Stop the Lucene document indexers before OFBiz closes
the datasources (OFBIZ-13686)
2afd9f164 is described below
commit 2afd9f164072fc0442895c6c25cd26b080787bd0
Author: Mridul Pathak <[email protected]>
AuthorDate: Thu Oct 15 19:19:47 2026 +0530
Fixed: Stop the Lucene document indexers before OFBiz closes the
datasources (OFBIZ-13686)
The new lucene-container stops the document indexers when OFBiz shuts down,
waiting at most 3 seconds, so that they are done with the database before the
framework closes the datasources. As before, the documents still queued at that
point are not indexed; what changes is that an indexer no longer tries to
prepare documents from a closed datasource, which failed with errors in the log.
---
lucene/ofbiz-component.xml | 2 +
.../ofbiz/content/search/DocumentIndexer.java | 52 +++++++++++++++++++++
.../content/search/DocumentIndexerContainer.java | 54 ++++++++++++++++++++++
3 files changed, 108 insertions(+)
diff --git a/lucene/ofbiz-component.xml b/lucene/ofbiz-component.xml
index 709caf902..36413ee02 100644
--- a/lucene/ofbiz-component.xml
+++ b/lucene/ofbiz-component.xml
@@ -35,6 +35,8 @@ under the License.
<test-suite loader="main" location="testdef/lucenetests.xml"/>
+ <container name="lucene-container" loaders="main,load-data,test"
class="org.apache.ofbiz.content.search.DocumentIndexerContainer"/>
+
<!-- this overrides the content application in order to add the index
management screens -->
<webapp name="content"
title="Content"
diff --git
a/lucene/src/main/java/org/apache/ofbiz/content/search/DocumentIndexer.java
b/lucene/src/main/java/org/apache/ofbiz/content/search/DocumentIndexer.java
index 0dbe1d3ec..3dfdd36d8 100644
--- a/lucene/src/main/java/org/apache/ofbiz/content/search/DocumentIndexer.java
+++ b/lucene/src/main/java/org/apache/ofbiz/content/search/DocumentIndexer.java
@@ -20,7 +20,9 @@ package org.apache.ofbiz.content.search;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
@@ -43,6 +45,20 @@ public final class DocumentIndexer extends Thread {
private static final String MODULE = DocumentIndexer.class.getName();
private static Map<String, DocumentIndexer> documentIndexerMap = new
HashMap<>();
+ // set when OFBiz shuts down: the indexers then stop without indexing the
documents still queued
+ private static volatile boolean stopping = false;
+ // queued to wake up an indexer waiting for documents, so that it sees it
has to stop
+ private static final LuceneDocument STOP = new LuceneDocument() {
+ @Override
+ public Term getDocumentIdentifier() {
+ return null;
+ }
+
+ @Override
+ public Document prepareDocument(Delegator delegator) {
+ return null;
+ }
+ };
private LinkedBlockingQueue<LuceneDocument> documentIndexQueue = new
LinkedBlockingQueue<>();
private Delegator delegator;
private Directory indexDirectory;
@@ -90,6 +106,9 @@ public final class DocumentIndexer extends Thread {
Debug.logError(e, MODULE);
break;
}
+ if (stopping) {
+ break;
+ }
Term documentIdentifier =
ofbizDocument.getDocumentIdentifier();
Document document = null;
boolean prepared = false;
@@ -100,6 +119,10 @@ public final class DocumentIndexer extends Thread {
// the record may still exist: keep its document in the
index instead of deleting it
Debug.logError(e, getName() + ": could not prepare Lucene
document, index left unchanged for: " + ofbizDocument, MODULE);
}
+ if (stopping) {
+ // the document may not have been prepared correctly, the
datasources being closed
+ break;
+ }
if (!prepared && indexWriter == null) {
// nothing to write and no pending changes to commit
continue;
@@ -185,4 +208,33 @@ public final class DocumentIndexer extends Thread {
public boolean queue(LuceneDocument document) {
return documentIndexQueue.add(document);
}
+
+ /**
+ * Stops all the document indexers, without indexing the documents still
queued.
+ * This method is called when OFBiz shuts down, so that the indexers are
done with the database before it is closed.
+ * @param timeoutMillis the maximum time to wait for the indexers to stop
+ */
+ public static void stopAll(long timeoutMillis) {
+ stopping = true;
+ List<DocumentIndexer> documentIndexers;
+ synchronized (DocumentIndexer.class) {
+ documentIndexers = new ArrayList<>(documentIndexerMap.values());
+ }
+ long deadline = System.currentTimeMillis() + timeoutMillis;
+ for (DocumentIndexer documentIndexer : documentIndexers) {
+ documentIndexer.documentIndexQueue.clear();
+ documentIndexer.queue(STOP);
+ }
+ for (DocumentIndexer documentIndexer : documentIndexers) {
+ try {
+ documentIndexer.join(Math.max(1, deadline -
System.currentTimeMillis()));
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return;
+ }
+ if (documentIndexer.isAlive()) {
+ Debug.logWarning(documentIndexer.getName() + " did not stop
within " + timeoutMillis + " ms", MODULE);
+ }
+ }
+ }
}
diff --git
a/lucene/src/main/java/org/apache/ofbiz/content/search/DocumentIndexerContainer.java
b/lucene/src/main/java/org/apache/ofbiz/content/search/DocumentIndexerContainer.java
new file mode 100644
index 000000000..252a927f3
--- /dev/null
+++
b/lucene/src/main/java/org/apache/ofbiz/content/search/DocumentIndexerContainer.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+
*******************************************************************************/
+package org.apache.ofbiz.content.search;
+
+import java.util.List;
+
+import org.apache.ofbiz.base.container.Container;
+import org.apache.ofbiz.base.start.StartupCommand;
+
+/**
+ * Stops the document indexers when OFBiz shuts down, before the datasources
they read from get closed.
+ */
+public class DocumentIndexerContainer implements Container {
+
+ private static final long STOP_TIMEOUT_MILLIS = 3000;
+
+ private String name;
+
+ @Override
+ public void init(List<StartupCommand> ofbizCommands, String name, String
configFile) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public void stop() {
+ DocumentIndexer.stopAll(STOP_TIMEOUT_MILLIS);
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+}