[ 
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]

Reply via email to