Merge pull request #8980 from toniprieto/index-consumer-readonly-mode

Improve performance of discovery consumer when there are many items to index
This commit is contained in:
Tim Donohue
2023-11-03 10:55:28 -05:00
committed by GitHub
5 changed files with 83 additions and 0 deletions

View File

@@ -810,6 +810,15 @@ public class Context implements AutoCloseable {
readOnlyCache.clear(); readOnlyCache.clear();
} }
// When going to READ_ONLY, flush database changes to ensure that the current data is retrieved
if (newMode == Mode.READ_ONLY && mode != Mode.READ_ONLY) {
try {
dbConnection.flushSession();
} catch (SQLException ex) {
log.warn("Unable to flush database changes after switching to READ_ONLY mode", ex);
}
}
//save the new mode //save the new mode
mode = newMode; mode = newMode;
} }

View File

@@ -148,4 +148,12 @@ public interface DBConnection<T> {
* @throws java.sql.SQLException passed through. * @throws java.sql.SQLException passed through.
*/ */
public <E extends ReloadableEntity> void uncacheEntity(E entity) throws SQLException; public <E extends ReloadableEntity> void uncacheEntity(E entity) throws SQLException;
/**
* Do a manual flush. This synchronizes the in-memory state of the Session
* with the database (write changes to the database)
*
* @throws SQLException passed through.
*/
public void flushSession() throws SQLException;
} }

View File

@@ -337,4 +337,17 @@ public class HibernateDBConnection implements DBConnection<Session> {
} }
} }
} }
/**
* Do a manual flush. This synchronizes the in-memory state of the Session
* with the database (write changes to the database)
*
* @throws SQLException passed through.
*/
@Override
public void flushSession() throws SQLException {
if (getSession().isDirty()) {
getSession().flush();
}
}
} }

View File

@@ -205,6 +205,10 @@ public class IndexEventConsumer implements Consumer {
@Override @Override
public void end(Context ctx) throws Exception { public void end(Context ctx) throws Exception {
// Change the mode to readonly to improve performance
Context.Mode originalMode = ctx.getCurrentMode();
ctx.setMode(Context.Mode.READ_ONLY);
try { try {
for (String uid : uniqueIdsToDelete) { for (String uid : uniqueIdsToDelete) {
try { try {
@@ -234,6 +238,8 @@ public class IndexEventConsumer implements Consumer {
uniqueIdsToDelete.clear(); uniqueIdsToDelete.clear();
createdItemsToUpdate.clear(); createdItemsToUpdate.clear();
} }
ctx.setMode(originalMode);
} }
} }

View File

@@ -0,0 +1,47 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.core;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.dspace.AbstractIntegrationTestWithDatabase;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.authorize.factory.AuthorizeServiceFactory;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.builder.CommunityBuilder;
import org.junit.Test;
public class ContextIT extends AbstractIntegrationTestWithDatabase {
AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
@Test
public void testGetPoliciesNewCommunityAfterReadOnlyModeChange() throws Exception {
context.turnOffAuthorisationSystem();
// First disable the index consumer. The indexing process calls the authorizeService
// function used in this test and may affect the test
context.setDispatcher("noindex");
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
context.restoreAuthSystemState();
context.setMode(Context.Mode.READ_ONLY);
List<ResourcePolicy> policies = authorizeService.getPoliciesActionFilter(context, parentCommunity,
Constants.READ);
assertEquals("Should return the default anonymous group read policy", 1, policies.size());
}
}