Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce memory overhead of searches #6471

Merged
merged 32 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
type: perf
issue: 6469
title: "Searching for a large number of resources can use a lot of
memory, due to the nature of deduplication of results in memory.
We will instead push this responsibility to the db to save
reduce this overhead.
"
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ public IBundleProvider registerSearch(
myContext.getResourceDefinition(theResourceType).getImplementingClass();
final ISearchBuilder<JpaPid> sb = mySearchBuilderFactory.newSearchBuilder(theResourceType, resourceTypeClass);
sb.setFetchSize(mySyncSize);
sb.setRequireTotal(theParams.getCount() != null);

final Integer loadSynchronousUpTo = getLoadSynchronousUpToOrNull(theCacheControlDirective);
boolean isOffsetQuery = theParams.isOffsetQuery();
Expand All @@ -393,14 +394,19 @@ public IBundleProvider registerSearch(

try {
return direct.get();

} catch (ResourceNotFoundInIndexException theE) {
// some resources were not found in index, so we will inform this and resort to JPA search
ourLog.warn(
"Some resources were not found in index. Make sure all resources were indexed. Resorting to database search.");
}
}

// we need a max to fetch for synchronous searches;
// otherwise we'll explode memory.
Integer maxToLoad = getSynchronousMaxResultsToFetch(theParams, loadSynchronousUpTo);
ourLog.debug("Setting a max fetch value of {} for synchronous search", maxToLoad);
sb.setMaxResultsToFetch(maxToLoad);

ourLog.debug("Search {} is loading in synchronous mode", searchUuid);
return mySynchronousSearchSvc.executeQuery(
theParams, theRequestDetails, searchUuid, sb, loadSynchronousUpTo, theRequestPartitionId);
Expand Down Expand Up @@ -434,6 +440,35 @@ public IBundleProvider registerSearch(
return retVal;
}

/**
* The max results to return if this is a synchronous search.
*
* We'll look in this order:
* * load synchronous up to (on params)
* * param count (+ offset)
* * StorageSettings fetch size default max
* *
*/
private Integer getSynchronousMaxResultsToFetch(SearchParameterMap theParams, Integer theLoadSynchronousUpTo) {
if (theLoadSynchronousUpTo != null) {
return theLoadSynchronousUpTo;
}

if (theParams.getCount() != null) {
int valToReturn = theParams.getCount() + 1;
if (theParams.getOffset() != null) {
valToReturn += theParams.getOffset();
}
return valToReturn;
}

if (myStorageSettings.getFetchSizeDefaultMaximum() != null) {
return myStorageSettings.getFetchSizeDefaultMaximum();
}

return myStorageSettings.getInternalSynchronousSearchSize();
}

private void validateSearch(SearchParameterMap theParams) {
validateIncludes(theParams.getIncludes(), Constants.PARAM_INCLUDE);
validateIncludes(theParams.getRevIncludes(), Constants.PARAM_REVINCLUDE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public IBundleProvider executeQuery(
resources, theRequestDetails, myInterceptorBroadcaster);

SimpleBundleProvider bundleProvider = new SimpleBundleProvider(resources);
if (hasACount) {
if (hasACount && theSb.requiresTotal()) {
bundleProvider.setTotalResourcesRequestedReturned(receivedResourceCount);
}
if (theParams.isOffsetQuery()) {
Expand Down
Loading
Loading