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

SOLR-17682: QueryResponseWriter hierarchy refactor #3209

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

dsmiley
Copy link
Contributor

@dsmiley dsmiley commented Feb 25, 2025

QRW now does write(OutputStream) and NOT write(Writer). BinaryQueryResponseWriter is removed
QRW.writeToString for tests
TextQueryResponseWriter added as base for all text QRWs QueryResponseWriterUtil is removed

https://issues.apache.org/jira/browse/SOLR-17682

QRW now does write(OutputStream) and NOT write(Writer).
BinaryQueryResponseWriter is removed
QRW.writeToString for debugging
TextQueryResponseWriter added as base for all text QRWs
QueryResponseWriterUtil is removed
Copy link
Contributor Author

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10.0 only; no deprecations

@@ -45,12 +44,14 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BinaryResponseWriter implements BinaryQueryResponseWriter {
/** Solr's "javabin" format. TODO rename accordingly. */
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth doing in another PR; maybe same JIRA

@Override
public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response)
throws IOException {
throw new RuntimeException("This is a binary writer , Cannot write to a characterstream");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existence of this was a code-smell that the hierarchy was wrong; promoting my efforts here

throws IOException {
WriterImpl sw = new WriterImpl(jsonfactory, out, request, response);
out = new NonFlushingStream(out);
// resolve the encoding
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this charSet check logic is new. Since Jackson can specify the encoding and since the contentType (with possibly the encoding) is now passed in (new), made sense to choose the right one.

*/
public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response)
void write(
OutputStream out, SolrQueryRequest request, SolrQueryResponse response, String contentType)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added contentType since the production code path will have this already, and we'll need it in TextQueryResponseWriter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a debatable change... it'd be less disruptive to leave it as it was and then only the text formats will re-acquire it which is fairly trivial parsing to do a second time. Shrug.

}
return getBaseWriter(request).getContentType(request, response);
}

@Override
public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need a Writer/Reader variant of this (I think).

@@ -81,7 +83,8 @@ private static Writer buildWriter(OutputStream outputStream, String charset)
*
* <p>See SOLR-8669.
*/
private static class NonFlushingStream extends OutputStream {
// nocommit discuss moving to SolrDispatchFilter wrapper. If keep them move?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an observation I had to do things better. Basically, don't we want Solr to always prevent a flush, not just specifically here only sometimes for some QueryResponseWriters? If so, it can easily go on the close shield thing (see elsewhere in this PR to show how. Then we can drop this NonFlushingStream thing and not worry about wether we should use it in other scenarios. CC @magibney wonder if you have thoughts on this one

responseWriter.write(out, req, rsp);
return out.toString();
}
return req.getResponseWriter().writeToString(req, rsp);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern happens in many places. The existence of it and repeating was a code-smell that the hierarchy was wrong; promoting my efforts here


@Override
public void flush() throws IOException {
// nocommit discuss
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here's the front door of Solr; super simple to prevent flushes here too

out = new ByteArrayOutputStream();
// to be fair, from my previous tests, much of the performance will be sucked up
// by java's UTF-8 encoding/decoding, not the actual writing
Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dropped this branch because in normal use we'll write to an OutputStream, not a Writer.

throws IOException {
try (SmileWriter sw = new SmileWriter(out, request, response)) {
sw.writeResponse();
}
}

@Override
public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smile was wrongly subclassing BinaryResponseWriter (JavaBin) and thus inheriting its content type. It was an innocent mistake enabled by BinaryResponseWriter's bad name; should say "JavaBin" in there.

@@ -47,12 +47,15 @@
* org.apache.solr.handler.admin.MetricsHandler}
*/
@SuppressWarnings(value = "unchecked")
public class PrometheusResponseWriter extends RawResponseWriter {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mlbiscoc why did you choose RawResponseWriter? It's a very special QueryResponseWriter and I don't see that the this response writer utilizes it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully remember. I think I followed a different writer at the time and this one took an OutputStream which was what I was looking for but please with change if this is not correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants