We are developing a system that allows users to search within an unstable DB which is located on a remote server that we do not control. For this task we use Hibernate and Springboot infrastructures.
When our server application is started it starts the indexing task which that is supposed to run every day at 12:00. The purpose of the task is to index the unstable remote DB. For that purpose we use MassIndexer in the following way –
FullTextEntityManager fullTextEntityManagerL = Search.getFullTextEntityManager(em);
fullTextEntityManagerL.createIndexer(classes)
.batchSizeToLoadObjects(50)
.threadsToLoadObjects(5)
.typesToIndexInParallel(2)
.idFetchSize(15)
//.progressMonitor(monitor)
.transactionTimeout(1800)
.startAndWait();
The problem is that the server disconnects frequently during the indexing time and the results of the index that we receive are broken. It causes issues with the search – we can not execute the search with the broken index and our server stops working properly. We would like to find a way to identify that the index that we are using completed correctly and not broken. In case it is broken we would like to use previous successfully completed index and restart the task to try again in 1 hour.
The database is Legacy one and it should not be changed by our application and also that no primary keys to the tables we need are present
Another problem that we face is that during the search functionality of our application, while running search on the index, the server disconnected and the results can not be retrieved. We would like to recognize during the search function that server is not available and to inform the user about it and to return empty results properly. Currently there is no way to check it. For search we use DatabaseService .search(filter, handler) functionality in a following way –
@Component
public class AsyncSearchExecutor {
private Logger logger = LoggerFactory.getLogger(AsyncSearchExecutor.class);
private final DatabaseService databaseService;
@Autowired
public AsyncSearchExecutor(DatabaseService databaseService) {
this.databaseService = databaseService;
}
public List search(FullTextSearchFilter filter, DatabaseSearchHandler... searchHandlers) {
logger.info("Executed search for {}.", filter);
List<FullTextSearchSimpleResult> result = new ArrayList();
int index = 0;
CompletableFuture[] completableFutures = new CompletableFuture[searchHandlers.length];
for (DatabaseSearchHandler handler : searchHandlers) {
CompletableFuture<List<FullTextSearchSimpleResult>> results = databaseService.search(filter, handler);
completableFutures[index] = results;
index++;
}
// Wait until they are all done
CompletableFuture.allOf(completableFutures).join();
try {
for (CompletableFuture future : completableFutures) {
result.addAll((List<FullTextSearchSimpleResult>) future.get());
}
} catch (InterruptedException | ExecutionException e) {
logger.error("Exception {} occurred on uniting search results.", e.getMessage());
}
return result;
}
}
return asyncSearchExecutor.search(filter, oDatabaseSerachHandler, wDBSearchDBHandler);