Hibernate Search synchrone Ausführung in Hauptthread
-
27-09-2019 - |
Frage
Es scheint, dass Hibernate Search synchrone Ausführung verwendet andere Threads als die anrufende Gewinde für die parallele Ausführung.
Wie führe ich die Hibernate Search Exekutionen seriell in den rufenden Thread?
Das Problem scheint in der org.hibernate.search.backend.impl.lucene.QueueProcessors
Klasse zu sein:
private void runAllWaiting() throws InterruptedException {
List<Future<Object>> futures = new ArrayList<Future<Object>>( dpProcessors.size() );
// execute all work in parallel on each DirectoryProvider;
// each DP has it's own ExecutorService.
for ( PerDPQueueProcessor process : dpProcessors.values() ) {
ExecutorService executor = process.getOwningExecutor();
//wrap each Runnable in a Future
FutureTask<Object> f = new FutureTask<Object>( process, null );
futures.add( f );
executor.execute( f );
}
// and then wait for all tasks to be finished:
for ( Future<Object> f : futures ) {
if ( !f.isDone() ) {
try {
f.get();
}
catch (CancellationException ignore) {
// ignored, as in java.util.concurrent.AbstractExecutorService.invokeAll(Collection<Callable<T>>
// tasks)
}
catch (ExecutionException error) {
// rethrow cause to serviced thread - this could hide more exception:
Throwable cause = error.getCause();
throw new SearchException( cause );
}
}
}
}
Eine serielle synchrone Ausführung in dem rufenden Thread passieren würde und Kontextinformationen wie Authentifizierungsinformationen an die zugrunde liegenden DirectoryProvider aus.
Lösung
Sehr alte Frage, aber ich könnte es auch beantworten ...
Hibernate Search macht das für ein Verzeichnis Single-Threaded-Zugriff auf die Lucene IndexWriter
zu gewährleisten (die von Lucene erforderlich). Ich stelle ich die Verwendung eines Single-Threaded Executor pro-Verzeichnis war ein Weg, mit dem Warteschlangen-Problem umzugehen.
Wenn Sie wollen alles in den rufenden Thread Sie ausführen müssen neu implementieren, die LuceneBackendQueueProcessorFactory
und binden Sie es an hibernate.search.worker.backend
in Ihrem Hibernate Eigenschaften. Nicht trivial, aber machbar.