This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_9x in repository https://gitbox.apache.org/repos/asf/solr.git
commit 2f11d3d5525c753261322546cb09d464ffb5888e Author: David Smiley <[email protected]> AuthorDate: Tue Dec 16 23:56:34 2025 -0500 SOLR-17982: setForcedDistrib (#3931) Provide an internal API to force distributed search (even when one shard). (cherry picked from commit 5c9cab2901a88385a09ca2a17821e41f062731c3) --- .../SOLR-17982-refactorSearchHandlerForcedDistrib.yml | 9 +++++++++ .../apache/solr/handler/component/HttpShardHandler.java | 8 ++++++-- .../org/apache/solr/handler/component/ResponseBuilder.java | 10 ++++++++++ .../org/apache/solr/handler/component/SearchHandler.java | 6 +++--- .../src/java/org/apache/solr/servlet/HttpSolrCall.java | 14 ++++++++++++++ .../org/apache/solr/BaseDistributedSearchTestCase.java | 11 +++++------ 6 files changed, 47 insertions(+), 11 deletions(-) diff --git a/changelog/unreleased/SOLR-17982-refactorSearchHandlerForcedDistrib.yml b/changelog/unreleased/SOLR-17982-refactorSearchHandlerForcedDistrib.yml new file mode 100644 index 00000000000..dd330bd13f4 --- /dev/null +++ b/changelog/unreleased/SOLR-17982-refactorSearchHandlerForcedDistrib.yml @@ -0,0 +1,9 @@ +# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc +title: Provide an internal API to force distributed search (even when one shard). Also, refactor/reorganize SearchHandler for clarity & extensibility. +type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other +authors: + - name: David Smiley + - name: Sonu Sharma +links: + - name: SOLR-17982 + url: https://issues.apache.org/jira/browse/SOLR-17982 diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java index 36c62aae972..73b960db91e 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.java @@ -406,7 +406,7 @@ public class HttpShardHandler extends ShardHandler { public void prepDistributed(ResponseBuilder rb) { final SolrQueryRequest req = rb.req; final SolrParams params = req.getParams(); - final String shards = params.get(ShardParams.SHARDS); + String shards = params.get(ShardParams.SHARDS); CoreDescriptor coreDescriptor = req.getCore().getCoreDescriptor(); CloudDescriptor cloudDescriptor = req.getCloudDescriptor(); @@ -445,7 +445,7 @@ public class HttpShardHandler extends ShardHandler { .build(); rb.slices = replicaSource.getSliceNames().toArray(new String[replicaSource.getSliceCount()]); - if (canShortCircuit(rb.slices, onlyNrt, params, cloudDescriptor)) { + if (!rb.isForcedDistrib() && canShortCircuit(rb.slices, onlyNrt, params, cloudDescriptor)) { rb.isDistrib = false; rb.shortCircuitedURL = ZkCoreNodeProps.getCoreUrl(zkController.getBaseUrl(), coreDescriptor.getName()); @@ -477,6 +477,9 @@ public class HttpShardHandler extends ShardHandler { } } } else { + if (shards == null) { + shards = req.getHttpSolrCall().getThisNodeUrl() + "/" + req.getCore().getName(); + } replicaSource = new StandaloneReplicaSource.Builder() .allowListUrlChecker(urlChecker) @@ -504,6 +507,7 @@ public class HttpShardHandler extends ShardHandler { return String.join("|", shardUrls); } + /** Can we avoid distributed search / coordinator? */ private boolean canShortCircuit( String[] slices, boolean onlyNrtReplicas, diff --git a/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java b/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java index 7ce3e1c05c9..4547438689e 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java +++ b/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java @@ -151,6 +151,16 @@ public class ResponseBuilder { public List<ShardRequest> outgoing; // requests to be sent public List<ShardRequest> finished; // requests that have received responses from all shards public String shortCircuitedURL; + private boolean forcedDistrib = false; + + public boolean isForcedDistrib() { + return forcedDistrib; + } + + /** Force distributed-search / coordinator logic when not a sub-shard request. */ + public void setForcedDistrib(boolean forcedDistrib) { + this.forcedDistrib = forcedDistrib; + } /** This function will return true if this was a distributed search request. */ public boolean isDistributed() { diff --git a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java index 0bf03caab5e..10ef832d924 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java @@ -334,8 +334,8 @@ public class SearchHandler extends RequestHandlerBase } protected boolean isDistrib(SolrQueryRequest req, ResponseBuilder rb) { - boolean isZkAware = req.getCoreContainer().isZooKeeperAware(); - boolean isDistrib = req.getParams().getBool(DISTRIB, isZkAware); + boolean theDefault = req.getCoreContainer().isZooKeeperAware() || rb.isForcedDistrib(); + boolean isDistrib = req.getParams().getBool(DISTRIB, theDefault); if (!isDistrib) { // for back compat, a shards param with URLs like localhost:8983/solr will mean that this // search is distributed. @@ -345,7 +345,7 @@ public class SearchHandler extends RequestHandlerBase return isDistrib; } - public ShardHandler getAndPrepShardHandler(SolrQueryRequest req, ResponseBuilder rb) { + protected ShardHandler getAndPrepShardHandler(SolrQueryRequest req, ResponseBuilder rb) { ShardHandler shardHandler = null; CoreContainer cc = req.getCoreContainer(); diff --git a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java index 9f4696e7740..93feb4b5d15 100644 --- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java +++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java @@ -82,6 +82,7 @@ import org.apache.solr.api.V2HttpCall; import org.apache.solr.client.api.util.SolrVersion; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.impl.HttpClientUtil; +import org.apache.solr.cloud.ZkController; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.cloud.Aliases; @@ -1343,6 +1344,19 @@ public class HttpSolrCall { return Collections.emptyMap(); } + /** + * The URL to this core, e.g. {@code http://localhost:8983/solr}. + * + * @see ZkController#getBaseUrl() + */ + public String getThisNodeUrl() { + String scheme = getReq().getScheme(); + String host = getReq().getServerName(); + int port = getReq().getServerPort(); + String context = getReq().getContextPath(); + return String.format(Locale.ROOT, "%s://%s:%d%s", scheme, host, port, context); + } + /** A faster method for randomly picking items when you do not need to consume all items. */ private static class RandomIterator<E> implements Iterator<E> { private Random rand; diff --git a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java index 2766781708e..fbc1c26069c 100644 --- a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java +++ b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java @@ -711,19 +711,18 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 { /** Returns the QueryResponse from {@link #queryServer} */ protected QueryResponse query(boolean setDistribParams, SolrParams p) throws Exception { + if (p.get("distrib") != null) { + throw new IllegalArgumentException("don't pass distrib param"); + } - final ModifiableSolrParams params = new ModifiableSolrParams(p); - - // TODO: look into why passing true causes fails - params.set("distrib", "false"); - final QueryResponse controlRsp = controlClient.query(params); + final QueryResponse controlRsp = controlClient.query(p); validateControlData(controlRsp); if (shardCount == 0) { // mostly for temp debugging return controlRsp; } - params.remove("distrib"); + final ModifiableSolrParams params = new ModifiableSolrParams(p); if (setDistribParams) setDistributedParams(params); QueryResponse rsp = queryServer(params);
