[
https://issues.apache.org/jira/browse/SOLR-6312?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17553729#comment-17553729
]
Chris M. Hostetter commented on SOLR-6312:
------------------------------------------
FWIW, this bit me in the ass recently with a new usecase for why it was
problematic and i wished i could turn it off. I also realized there is a
"client only" workaround that wasn't too painful that I thought i'd share, and
have some revised thoughts on how CloudSolrClient should _ideally_ work
h3. My New Usecase
I'm working on a custom request handler that takes as it's input whole
documents – along the same lines as MTLHandler, or the DocumentAnalysisHandler,
but I don't want to _only_ take in a stream of text for a single field, or only
a hackish subset of the XML request like those handlers. I want to take in
(multiple) real documents, using ContentLoaders, and feed them through URPs and
then use those doucments.
Writing the handler is easy, and I thought using {{UpdateRequest}} on the solrj
client side would also be easy – but then my unit tests failed when using
CloudSolrCLient but not when using HttpSolrCLient – and i remembered this jira.
(FWIW: My failures weren't even because the leaders were the only nodes getting
the request – i probably wouldn't have noticed that until much later – my test
failures were because the {{directUpdates}} logic splits apart the
UpdateRequest and then stiches the responses from each leader back together
bsaed on what it expects from {{UpdateRequestHandler}} – but it didn't know
about the diff response data my custom request handler was returninging.
h3. My Client Workaround
instead of using {{new UpdateRequest}} I'm using a wrapper class that looks
like this (generalized psuedo code, my actual class has a slightly more limited
surface API since i don't care about things like deletes)...
{code:java}
// important that this is NOT an instance of IsUpdateRequest
public final class NonRoutedUpdate extends GenericSolrRequest {
private final UpdateRequest updates;
public NonRoutedUpdate(final String path, final SolrParams params, final
UpdateRequest updates) {
super(METHOD.POST, path, params);
this.updates = updates
}
@Override
public String getRequestType() {
return "non-routed-update";
}
@Override
public RequestWriter.ContentWriter getContentWriter(String expectedType) {
return new UpdateContentWriter(updates);
}
public Collection<ContentStream> getContentStreams() throws IOException {
throw new UnsupportedOperationException("Bug in some assumption: we
shouldn't be asked for a stream");
}
private static final class UpdateContentWriter implements
RequestWriter.ContentWriter {
private final UpdateRequest updates;
public UpdateContentWriter(final UpdateRequest updates) {
this.updates = updates;
}
@Override
public void write(OutputStream os) throws IOException {
new JavaBinUpdateRequestCodec().marshal(this.updates, os);
}
@Override
public String getContentType() {
return CommonParams.JAVABIN_MIME;
}
}
}
{code}
(something similar could be done to wrap a {{ContentStreamUpdateRequest}} )
h3. Revised opinion on ideal functionality
My 8+ year old comments still ring true to me ... but i actually think we
should go farther.
It strikes me that there is really no reason why
{{CloudSolrClient.updatesToLeaders}} should really be (only a) Client setting –
it seems like it should really be a request option – some updates i know are
best sent only to leaders, other requests that are {{instanceOf
IsUpdateRequest}} I know should really just be round robined (or obey my
{{{}shards.preferences{}}}) and i'd like to be able use one client to send both
requests.
In an ideal world i think we would have:
* a {{default boolean isSendToLeaders()}} to the {{IsUpdateRequest}} interface
that defaults to returning true
** {{AbstractUpdateRequest.isSendToLeaders()}} would override that default
impl backed by a {{AbstractUpdateRequest.setSendToLeaders(boolean)}} (which a
value that defaults to true)
* In {{CloudSolrClient.sendRequest}} the {{request instanceof
IsUpdateRequest}} block should skip out of this entire bock, and leave the
local variable {{sendToLeaders = false}} unless {{request.isSendToLeaders() &&
this.isUpdatesToLeaders()}}
> CloudSolrServer doesn't honor updatesToLeaders constructor argument
> -------------------------------------------------------------------
>
> Key: SOLR-6312
> URL: https://issues.apache.org/jira/browse/SOLR-6312
> Project: Solr
> Issue Type: Bug
> Components: clients - java, SolrJ
> Affects Versions: 4.9, 7.5
> Reporter: Steve Davids
> Priority: Major
> Fix For: 4.10
>
> Attachments: SOLR-6312.patch
>
>
> The CloudSolrServer doesn't use the updatesToLeaders property - all SolrJ
> requests are being sent to the shard leaders.
--
This message was sent by Atlassian Jira
(v8.20.7#820007)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]