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;
+    }
+}

Reply via email to