diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-06 14:35:27 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-06 17:23:01 +0100 |
commit | 2c8d19b82de5ec4b47a5eb4ab566bbcb1725d118 (patch) | |
tree | 1d535de3b8621d827c6657edfb1eb26fa803410d | |
parent | ffdbd053a2b57383b2d463e8050394776b14abdf (diff) |
Deprecate public APIs using Guava's ListenableFuture
Public methods:
- com.yahoo.processing.rendering.Renderer.render()
- com.yahoo.search.handler.HttpSearchResponse.waitableRender()
- com.yahoo.processing.rendering.AsynchronousSectionedRenderer.renderBeforeHandover()
19 files changed, 203 insertions, 113 deletions
diff --git a/application/abi-spec.json b/application/abi-spec.json index 5c298471b9c..2138f12854c 100644 --- a/application/abi-spec.json +++ b/application/abi-spec.json @@ -347,7 +347,7 @@ "public final com.yahoo.processing.Response process(com.yahoo.component.ComponentSpecification, com.yahoo.processing.Request)", "protected abstract com.yahoo.processing.Response doProcess(com.yahoo.component.chain.Chain, com.yahoo.processing.Request)", "public final byte[] processAndRender(com.yahoo.component.ComponentSpecification, com.yahoo.component.ComponentSpecification, com.yahoo.processing.Request)", - "protected abstract com.google.common.util.concurrent.ListenableFuture doProcessAndRender(com.yahoo.component.ComponentSpecification, com.yahoo.processing.Request, com.yahoo.processing.rendering.Renderer, java.io.ByteArrayOutputStream)", + "protected abstract java.util.concurrent.CompletableFuture doProcessAndRender(com.yahoo.component.ComponentSpecification, com.yahoo.processing.Request, com.yahoo.processing.rendering.Renderer, java.io.ByteArrayOutputStream)", "protected com.yahoo.component.chain.Chain getChain(com.yahoo.component.ComponentSpecification)", "protected final com.yahoo.processing.rendering.Renderer getRenderer(com.yahoo.component.ComponentSpecification)", "protected abstract com.yahoo.processing.rendering.Renderer doGetRenderer(com.yahoo.component.ComponentSpecification)" diff --git a/application/src/main/java/com/yahoo/application/container/Processing.java b/application/src/main/java/com/yahoo/application/container/Processing.java index 1f96fe2294b..4ca367ea720 100644 --- a/application/src/main/java/com/yahoo/application/container/Processing.java +++ b/application/src/main/java/com/yahoo/application/container/Processing.java @@ -2,7 +2,6 @@ package com.yahoo.application.container; import com.yahoo.api.annotations.Beta; -import com.google.common.util.concurrent.ListenableFuture; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.chain.Chain; import com.yahoo.processing.Processor; @@ -15,6 +14,7 @@ import com.yahoo.processing.rendering.Renderer; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.concurrent.CompletableFuture; /** * @author Einar M R Rosenvinge @@ -41,14 +41,14 @@ public final class Processing extends ProcessingBase<Request, Response, Processo } @Override - protected ListenableFuture<Boolean> doProcessAndRender(ComponentSpecification chainSpec, - Request request, - Renderer<Response> renderer, - ByteArrayOutputStream stream) throws IOException { + protected CompletableFuture<Boolean> doProcessAndRender(ComponentSpecification chainSpec, + Request request, + Renderer<Response> renderer, + ByteArrayOutputStream stream) throws IOException { Execution execution = handler.createExecution(getChain(chainSpec), request); Response response = execution.process(request); - return renderer.render(stream, response, execution, request); + return renderer.renderResponse(stream, response, execution, request); } @Override diff --git a/application/src/main/java/com/yahoo/application/container/ProcessingBase.java b/application/src/main/java/com/yahoo/application/container/ProcessingBase.java index 2b4ea822d03..96866b94e29 100644 --- a/application/src/main/java/com/yahoo/application/container/ProcessingBase.java +++ b/application/src/main/java/com/yahoo/application/container/ProcessingBase.java @@ -2,20 +2,18 @@ package com.yahoo.application.container; import com.yahoo.api.annotations.Beta; -import com.google.common.util.concurrent.ListenableFuture; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.chain.Chain; import com.yahoo.processing.Processor; import com.yahoo.processing.Request; import com.yahoo.processing.Response; import com.yahoo.processing.execution.chain.ChainRegistry; -import com.yahoo.processing.rendering.AsynchronousRenderer; import com.yahoo.processing.rendering.Renderer; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; /** * @author gjoranv @@ -45,13 +43,13 @@ public abstract class ProcessingBase<REQUEST extends Request, RESPONSE extends R REQUEST request) throws IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); Renderer<RESPONSE> renderer = getRenderer(rendererSpec); - ListenableFuture<Boolean> renderTask = doProcessAndRender(chainSpec, request, renderer, stream); + CompletableFuture<Boolean> renderTask = doProcessAndRender(chainSpec, request, renderer, stream); awaitFuture(renderTask); return stream.toByteArray(); } - private void awaitFuture(ListenableFuture<Boolean> renderTask) { + private void awaitFuture(CompletableFuture<Boolean> renderTask) { try { renderTask.get(); } catch (InterruptedException | ExecutionException e) { @@ -59,10 +57,10 @@ public abstract class ProcessingBase<REQUEST extends Request, RESPONSE extends R } } - protected abstract ListenableFuture<Boolean> doProcessAndRender(ComponentSpecification chainSpec, - REQUEST request, - Renderer<RESPONSE> renderer, - ByteArrayOutputStream stream) throws IOException ; + protected abstract CompletableFuture<Boolean> doProcessAndRender(ComponentSpecification chainSpec, + REQUEST request, + Renderer<RESPONSE> renderer, + ByteArrayOutputStream stream) throws IOException ; protected Chain<PROCESSOR> getChain(ComponentSpecification chainSpec) { Chain<PROCESSOR> chain = getChains().getComponent(chainSpec); diff --git a/application/src/main/java/com/yahoo/application/container/Search.java b/application/src/main/java/com/yahoo/application/container/Search.java index 3535b660b78..6a2f728fbcc 100644 --- a/application/src/main/java/com/yahoo/application/container/Search.java +++ b/application/src/main/java/com/yahoo/application/container/Search.java @@ -2,7 +2,6 @@ package com.yahoo.application.container; import com.yahoo.api.annotations.Beta; -import com.google.common.util.concurrent.ListenableFuture; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.chain.Chain; import com.yahoo.processing.execution.chain.ChainRegistry; @@ -12,10 +11,10 @@ import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.search.handler.HttpSearchResponse; import com.yahoo.search.handler.SearchHandler; -import com.yahoo.search.searchchain.SearchChainRegistry; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.concurrent.CompletableFuture; /** * @author Einar M R Rosenvinge @@ -41,12 +40,12 @@ public final class Search extends ProcessingBase<Query, Result, Searcher> { } @Override - protected ListenableFuture<Boolean> doProcessAndRender(ComponentSpecification chainSpec, - Query request, - Renderer<Result> renderer, - ByteArrayOutputStream stream) throws IOException { + protected CompletableFuture<Boolean> doProcessAndRender(ComponentSpecification chainSpec, + Query request, + Renderer<Result> renderer, + ByteArrayOutputStream stream) throws IOException { Result result = process(chainSpec, request); - return HttpSearchResponse.waitableRender(result, result.getQuery(), renderer, stream); + return HttpSearchResponse.asyncRender(result, result.getQuery(), renderer, stream); } @Override diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json index e4b97c3c968..cdd6da944c5 100644 --- a/container-core/abi-spec.json +++ b/container-core/abi-spec.json @@ -3137,8 +3137,9 @@ "public abstract void endResponse()", "public void <init>()", "public void <init>(java.util.concurrent.Executor)", - "public final com.google.common.util.concurrent.ListenableFuture render(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", + "public final java.util.concurrent.CompletableFuture renderResponse(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", "public void deconstruct()", + "public final java.util.concurrent.CompletableFuture renderResponseBeforeHandover(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", "public final com.google.common.util.concurrent.ListenableFuture renderBeforeHandover(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", "public com.yahoo.processing.execution.Execution getExecution()", "public com.yahoo.processing.Response getResponse()", @@ -3184,7 +3185,8 @@ "public void <init>()", "public com.yahoo.processing.rendering.Renderer clone()", "public void init()", - "public abstract com.google.common.util.concurrent.ListenableFuture render(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", + "public com.google.common.util.concurrent.ListenableFuture render(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", + "public java.util.concurrent.CompletableFuture renderResponse(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", "public abstract java.lang.String getEncoding()", "public abstract java.lang.String getMimeType()", "public bridge synthetic com.yahoo.component.AbstractComponent clone()", diff --git a/container-core/src/main/java/com/yahoo/processing/handler/AbstractProcessingHandler.java b/container-core/src/main/java/com/yahoo/processing/handler/AbstractProcessingHandler.java index 5119e69f72e..9b9224e70ef 100644 --- a/container-core/src/main/java/com/yahoo/processing/handler/AbstractProcessingHandler.java +++ b/container-core/src/main/java/com/yahoo/processing/handler/AbstractProcessingHandler.java @@ -244,7 +244,8 @@ public abstract class AbstractProcessingHandler<COMPONENT extends Processor> ext // Render if we have a renderer capable of it if (getRenderer() instanceof AsynchronousSectionedRenderer) { - ((AsynchronousSectionedRenderer) getRenderer()).renderBeforeHandover(new ContentChannelOutputStream(channel), response, execution, request); + ((AsynchronousSectionedRenderer) getRenderer()).renderResponseBeforeHandover( + new ContentChannelOutputStream(channel), response, execution, request); } } diff --git a/container-core/src/main/java/com/yahoo/processing/handler/ProcessingResponse.java b/container-core/src/main/java/com/yahoo/processing/handler/ProcessingResponse.java index 54fbce9e177..28645b4bde0 100644 --- a/container-core/src/main/java/com/yahoo/processing/handler/ProcessingResponse.java +++ b/container-core/src/main/java/com/yahoo/processing/handler/ProcessingResponse.java @@ -1,19 +1,9 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.processing.handler; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Executor; - import com.google.common.collect.ImmutableList; import com.yahoo.container.jdisc.AsyncHttpResponse; -import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.VespaHeaders; -import com.yahoo.container.logging.AccessLogEntry; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; import com.yahoo.processing.Request; @@ -26,6 +16,14 @@ import com.yahoo.processing.request.ErrorMessage; import com.yahoo.processing.response.Data; import com.yahoo.processing.response.DataList; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executor; + /** * A response from running a request through processing. This response is just a * wrapper of the knowhow needed to render the Response from processing. @@ -62,7 +60,7 @@ public class ProcessingResponse extends AsyncHttpResponse { AsynchronousRenderer asyncRenderer = (AsynchronousRenderer)renderer; asyncRenderer.setNetworkWiring(channel, completionHandler); } - renderer.render(stream, processingResponse, execution, processingRequest); + renderer.renderResponse(stream, processingResponse, execution, processingRequest); // the stream is closed in AsynchronousSectionedRenderer, after all data // has arrived } diff --git a/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java b/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java index b77d493ea30..21375ee3d76 100644 --- a/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java +++ b/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java @@ -3,11 +3,10 @@ package com.yahoo.processing.rendering; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; +import com.yahoo.concurrent.CompletableFutures; import com.yahoo.concurrent.ThreadFactoryFactory; import com.yahoo.jdisc.handler.CompletionHandler; import com.yahoo.jdisc.handler.ContentChannel; -import java.util.logging.Level; import com.yahoo.processing.Request; import com.yahoo.processing.Response; import com.yahoo.processing.execution.Execution; @@ -23,12 +22,14 @@ import java.util.ArrayDeque; import java.util.Collections; import java.util.Deque; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -126,7 +127,7 @@ public abstract class AsynchronousSectionedRenderer<RESPONSE extends Response> e return executor; } - private SettableFuture<Boolean> success; + private CompletableFuture<Boolean> success; private ContentChannel channel; private CompletionHandler completionHandler; @@ -173,8 +174,8 @@ public abstract class AsynchronousSectionedRenderer<RESPONSE extends Response> e * @return a future indicating whether rendering was successful */ @Override - public final ListenableFuture<Boolean> render(OutputStream stream, RESPONSE response, - Execution execution, Request request) { + public final CompletableFuture<Boolean> renderResponse(OutputStream stream, RESPONSE response, + Execution execution, Request request) { if (beforeHandoverMode) { // rendering has already started or is already complete beforeHandoverMode = false; if ( ! dataListListenerStack.isEmpty() && @@ -215,22 +216,31 @@ public abstract class AsynchronousSectionedRenderer<RESPONSE extends Response> e * At this point the worker thread still owns the Response, so all this rendering must happen * on the caller thread invoking freeze (that is, on the thread calling this). */ - public final ListenableFuture<Boolean> renderBeforeHandover(OutputStream stream, RESPONSE response, - Execution execution, Request request) { + public final CompletableFuture<Boolean> renderResponseBeforeHandover(OutputStream stream, RESPONSE response, + Execution execution, Request request) { beforeHandoverMode = true; if ( ! isInitialized) throw new IllegalStateException("render() invoked before init()."); return startRender(stream, response, execution, request); } - private ListenableFuture<Boolean> startRender(OutputStream stream, RESPONSE response, + + /** @deprecated Use {@link #renderResponseBeforeHandover(OutputStream, Response, Execution, Request)} */ + @Deprecated(forRemoval = true, since = "7") + @SuppressWarnings("removal") + public final ListenableFuture<Boolean> renderBeforeHandover(OutputStream stream, RESPONSE response, + Execution execution, Request request) { + return CompletableFutures.toGuavaListenableFuture(renderResponseBeforeHandover(stream, response, execution, request)); + } + + private CompletableFuture<Boolean> startRender(OutputStream stream, RESPONSE response, Execution execution, Request request) { this.response = response; this.stream = stream; this.execution = execution; DataListListener parentOfTopLevelListener = new DataListListener(new ParentOfTopLevel(request,response.data()), null); dataListListenerStack.addFirst(parentOfTopLevelListener); - success = SettableFuture.create(); + success = new CompletableFuture<>(); try { getExecutor().execute(parentOfTopLevelListener); } catch (RejectedExecutionException e) { @@ -471,11 +481,11 @@ public abstract class AsynchronousSectionedRenderer<RESPONSE extends Response> e logger.log(Level.WARNING, "Exception caught while closing stream to client.", e); } finally { if (failed != null) { - success.setException(failed); + success.completeExceptionally(failed); } else if (closeException != null) { - success.setException(closeException); + success.completeExceptionally(closeException); } else { - success.set(true); + success.complete(true); } if (channel != null) { channel.close(completionHandler); @@ -541,7 +551,7 @@ public abstract class AsynchronousSectionedRenderer<RESPONSE extends Response> e } catch (Exception ignored) { } } - success.setException(e); + success.completeExceptionally(e); } } } catch (Error e) { diff --git a/container-core/src/main/java/com/yahoo/processing/rendering/Renderer.java b/container-core/src/main/java/com/yahoo/processing/rendering/Renderer.java index 14ec3002b0a..8db4ed4f624 100644 --- a/container-core/src/main/java/com/yahoo/processing/rendering/Renderer.java +++ b/container-core/src/main/java/com/yahoo/processing/rendering/Renderer.java @@ -3,11 +3,13 @@ package com.yahoo.processing.rendering; import com.google.common.util.concurrent.ListenableFuture; import com.yahoo.component.AbstractComponent; +import com.yahoo.concurrent.CompletableFutures; import com.yahoo.processing.Request; import com.yahoo.processing.Response; import com.yahoo.processing.execution.Execution; import java.io.OutputStream; +import java.util.concurrent.CompletableFuture; /** * Renders a response to a stream. The renderers are cloned just before @@ -41,6 +43,17 @@ public abstract class Renderer<RESPONSE extends Response> extends AbstractCompon } /** + * @deprecated Use/implement {@link #renderResponse(OutputStream, Response, Execution, Request)} instead. + * Return type changed from {@link ListenableFuture} to {@link CompletableFuture}. + */ + @Deprecated(forRemoval = true, since = "7") + @SuppressWarnings("removal") + public ListenableFuture<Boolean> render(OutputStream stream, RESPONSE response, Execution execution, + Request request) { + return CompletableFutures.toGuavaListenableFuture(renderResponse(stream, response, execution, request)); + } + + /** * Render a response to a stream. The stream also exposes a ByteBuffer API * for efficient transactions to JDisc. The returned future will throw the * exception causing failure wrapped in an ExecutionException if rendering @@ -50,10 +63,13 @@ public abstract class Renderer<RESPONSE extends Response> extends AbstractCompon * @param response the response to render * @param execution the execution which created this response * @param request the request matching the response - * @return a ListenableFuture containing a boolean where true indicates a successful rendering + * @return a {@link CompletableFuture} containing a boolean where true indicates a successful rendering */ - public abstract ListenableFuture<Boolean> render(OutputStream stream, RESPONSE response, - Execution execution, Request request); + @SuppressWarnings("removal") + public CompletableFuture<Boolean> renderResponse(OutputStream stream, RESPONSE response, + Execution execution, Request request) { + return CompletableFutures.toCompletableFuture(render(stream, response, execution, request)); + } /** * Name of the output encoding, if applicable. diff --git a/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java b/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java index ce2b54ba6ff..50864c8b034 100644 --- a/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java +++ b/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java @@ -15,7 +15,6 @@ import com.yahoo.processing.response.DataList; import com.yahoo.processing.response.IncomingData; import com.yahoo.text.Utf8; import org.junit.Test; -import static org.junit.Assert.*; import java.io.IOException; import java.io.OutputStream; @@ -23,10 +22,15 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; /** * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a> @@ -222,7 +226,7 @@ public class AsynchronousSectionedRendererTest { return render(renderer, data); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "removal"}) public String render(Renderer renderer, DataList data) throws InterruptedException, IOException { TestContentChannel contentChannel = new TestContentChannel(); diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json index 183bb33b4f4..d88701dab03 100644 --- a/container-search/abi-spec.json +++ b/container-search/abi-spec.json @@ -4301,6 +4301,8 @@ "public void <init>(int, com.yahoo.search.Result, com.yahoo.search.Query, com.yahoo.processing.rendering.Renderer)", "public com.google.common.util.concurrent.ListenableFuture waitableRender(java.io.OutputStream)", "public static com.google.common.util.concurrent.ListenableFuture waitableRender(com.yahoo.search.Result, com.yahoo.search.Query, com.yahoo.processing.rendering.Renderer, java.io.OutputStream)", + "public java.util.concurrent.CompletableFuture asyncRender(java.io.OutputStream)", + "public static java.util.concurrent.CompletableFuture asyncRender(com.yahoo.search.Result, com.yahoo.search.Query, com.yahoo.processing.rendering.Renderer, java.io.OutputStream)", "public void render(java.io.OutputStream, com.yahoo.jdisc.handler.ContentChannel, com.yahoo.jdisc.handler.CompletionHandler)", "public void populateAccessLogEntry(com.yahoo.container.logging.AccessLogEntry)", "public java.lang.String getParsedQuery()", @@ -7201,13 +7203,13 @@ ], "methods": [ "public void <init>()", - "public final com.google.common.util.concurrent.ListenableFuture render(java.io.OutputStream, com.yahoo.search.Result, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", + "public final java.util.concurrent.CompletableFuture renderResponse(java.io.OutputStream, com.yahoo.search.Result, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", "protected abstract void render(java.io.Writer, com.yahoo.search.Result)", "public java.lang.String getCharacterEncoding(com.yahoo.search.Result)", "public java.lang.String getDefaultSummaryClass()", "public final java.lang.String getRequestedEncoding(com.yahoo.search.Query)", "public com.yahoo.search.rendering.Renderer clone()", - "public bridge synthetic com.google.common.util.concurrent.ListenableFuture render(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", + "public bridge synthetic java.util.concurrent.CompletableFuture renderResponse(java.io.OutputStream, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", "public bridge synthetic com.yahoo.processing.rendering.Renderer clone()", "public bridge synthetic com.yahoo.component.AbstractComponent clone()", "public bridge synthetic java.lang.Object clone()" diff --git a/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java b/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java index 5c897245e64..64e7403fa1a 100644 --- a/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java +++ b/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java @@ -3,6 +3,7 @@ package com.yahoo.search.handler; import com.google.common.util.concurrent.ListenableFuture; import com.yahoo.collections.ListMap; +import com.yahoo.concurrent.CompletableFutures; import com.yahoo.container.handler.Coverage; import com.yahoo.container.handler.Timing; import com.yahoo.container.jdisc.ExtendedResponse; @@ -25,6 +26,7 @@ import java.io.OutputStream; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; /** * Wrap the result of a query as an HTTP response. @@ -75,20 +77,36 @@ public class HttpSearchResponse extends ExtendedResponse { } } + /** @deprecated Use {@link #asyncRender(OutputStream)} instead */ + @Deprecated(forRemoval = true, since = "7") public ListenableFuture<Boolean> waitableRender(OutputStream stream) throws IOException { return waitableRender(result, query, rendererCopy, stream); } + /** @deprecated Use {@link #asyncRender(Result, Query, Renderer, OutputStream)} instead */ + @Deprecated(forRemoval = true, since = "7") + @SuppressWarnings("removal") public static ListenableFuture<Boolean> waitableRender(Result result, Query query, Renderer<Result> renderer, OutputStream stream) throws IOException { + return CompletableFutures.toGuavaListenableFuture(asyncRender(result, query, renderer, stream)); + } + + public CompletableFuture<Boolean> asyncRender(OutputStream stream) { + return asyncRender(result, query, rendererCopy, stream); + } + + public static CompletableFuture<Boolean> asyncRender(Result result, + Query query, + Renderer<Result> renderer, + OutputStream stream) { SearchResponse.trimHits(result); SearchResponse.removeEmptySummaryFeatureFields(result); - return renderer.render(stream, result, query.getModel().getExecution(), query); - + return renderer.renderResponse(stream, result, query.getModel().getExecution(), query); } + @Override public void render(OutputStream output, ContentChannel networkChannel, CompletionHandler handler) throws IOException { if (rendererCopy instanceof AsynchronousSectionedRenderer) { @@ -98,9 +116,9 @@ public class HttpSearchResponse extends ExtendedResponse { try { try { long nanoStart = System.nanoTime(); - ListenableFuture<Boolean> promise = waitableRender(output); + CompletableFuture<Boolean> promise = asyncRender(output); if (metric != null) { - promise.addListener(new RendererLatencyReporter(nanoStart), Runnable::run); + promise.whenComplete((__, ___) -> new RendererLatencyReporter(nanoStart).run()); } } finally { if (!(rendererCopy instanceof AsynchronousSectionedRenderer)) { diff --git a/container-search/src/main/java/com/yahoo/search/rendering/Renderer.java b/container-search/src/main/java/com/yahoo/search/rendering/Renderer.java index b8a7f0d1978..6ff8f003f7e 100644 --- a/container-search/src/main/java/com/yahoo/search/rendering/Renderer.java +++ b/container-search/src/main/java/com/yahoo/search/rendering/Renderer.java @@ -1,19 +1,18 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.rendering; -import com.yahoo.search.Query; -import com.yahoo.search.Result; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; import com.yahoo.io.ByteWriter; import com.yahoo.processing.Request; import com.yahoo.processing.execution.Execution; +import com.yahoo.search.Query; +import com.yahoo.search.Result; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; +import java.util.concurrent.CompletableFuture; /** * Renders a search result to a writer synchronously @@ -37,7 +36,7 @@ abstract public class Renderer extends com.yahoo.processing.rendering.Renderer<R * @return a future which is always completed to true */ @Override - public final ListenableFuture<Boolean> render(OutputStream stream, Result response, Execution execution, Request request) { + public final CompletableFuture<Boolean> renderResponse(OutputStream stream, Result response, Execution execution, Request request) { Writer writer = null; try { writer = createWriter(stream, response); @@ -50,8 +49,8 @@ abstract public class Renderer extends com.yahoo.processing.rendering.Renderer<R if (writer != null) try { writer.close(); } catch (IOException e2) {}; } - SettableFuture<Boolean> completed = SettableFuture.create(); - completed.set(true); + CompletableFuture<Boolean> completed = new CompletableFuture<>(); + completed.complete(true); return completed; } diff --git a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java index 0819cbd72b4..b39c170c6a3 100644 --- a/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/pagetemplates/engine/test/ExecutionAbstractTestCase.java @@ -53,7 +53,7 @@ public class ExecutionAbstractTestCase { assertRendered(result,resultFileName,false); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "removal"}) protected void assertRendered(Result result, String resultFileName, boolean print) { try { PageTemplatesXmlRenderer renderer = new PageTemplatesXmlRenderer(); diff --git a/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java index 359aed85d30..59aaf60d981 100644 --- a/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/rendering/AsyncGroupPopulationTestCase.java @@ -1,19 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.rendering; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.junit.Test; - import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -29,6 +16,18 @@ import com.yahoo.search.result.HitGroup; import com.yahoo.search.result.Relevance; import com.yahoo.search.searchchain.Execution; import com.yahoo.text.Utf8; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Test adding hits to a hit group during rendering. @@ -98,6 +97,7 @@ public class AsyncGroupPopulationTestCase { } @Test + @SuppressWarnings("removal") public final void test() throws InterruptedException, ExecutionException, JsonParseException, JsonMappingException, IOException { String rawExpected = "{" diff --git a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java index 7395b4802a0..f3a71af0b9e 100644 --- a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java @@ -364,6 +364,7 @@ public class JsonRendererTestCase { } @Test + @SuppressWarnings("removal") public void testEmptyTracing() throws IOException, InterruptedException, ExecutionException { String expected = "{" + " \"root\": {" @@ -391,7 +392,7 @@ public class JsonRendererTestCase { assertEqualJson(expected, summary); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "removal"}) @Test public void testTracingWithEmptySubtree() throws IOException, InterruptedException, ExecutionException { String expected = "{" @@ -1372,6 +1373,7 @@ public class JsonRendererTestCase { return render(execution, r); } + @SuppressWarnings("removal") private String render(Execution execution, Result r) throws InterruptedException, ExecutionException { ByteArrayOutputStream bs = new ByteArrayOutputStream(); ListenableFuture<Boolean> f = renderer.render(bs, r, execution, null); diff --git a/container-search/src/test/java/com/yahoo/search/rendering/SyncDefaultRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/SyncDefaultRendererTestCase.java index ae1eade12d3..99911276f50 100644 --- a/container-search/src/test/java/com/yahoo/search/rendering/SyncDefaultRendererTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/rendering/SyncDefaultRendererTestCase.java @@ -1,17 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.rendering; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.concurrent.ExecutionException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import com.google.common.util.concurrent.ListenableFuture; import com.yahoo.component.chain.Chain; import com.yahoo.prelude.fastsearch.FastHit; @@ -26,6 +15,15 @@ import com.yahoo.search.statistics.ElapsedTimeTestCase.CreativeTimeSource; import com.yahoo.search.statistics.ElapsedTimeTestCase.UselessSearcher; import com.yahoo.search.statistics.TimeTracker; import com.yahoo.text.Utf8; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Check the legacy sync default renderer doesn't spontaneously combust. @@ -56,7 +54,7 @@ public class SyncDefaultRendererTestCase { assertEquals("text/xml", d.getMimeType()); } - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "removal"}) @Test public void testRenderWriterResult() throws InterruptedException, ExecutionException { Query q = new Query("/?query=a&tracelevel=5"); diff --git a/container-search/src/test/java/com/yahoo/search/rendering/XMLRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/XMLRendererTestCase.java index 0fad449763f..b3534d580d8 100644 --- a/container-search/src/test/java/com/yahoo/search/rendering/XMLRendererTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/rendering/XMLRendererTestCase.java @@ -1,39 +1,36 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.rendering; -import static org.junit.Assert.*; - -import java.io.ByteArrayOutputStream; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - +import com.google.common.util.concurrent.ListenableFuture; import com.yahoo.component.ComponentId; +import com.yahoo.component.chain.Chain; import com.yahoo.container.QrSearchersConfig; import com.yahoo.prelude.Index; import com.yahoo.prelude.IndexFacts; import com.yahoo.prelude.IndexModel; import com.yahoo.prelude.SearchDefinition; -import com.yahoo.prelude.searcher.JuniperSearcher; -import com.yahoo.search.result.Hit; -import com.yahoo.search.result.Relevance; -import com.yahoo.search.searchchain.Execution; -import com.yahoo.search.searchchain.testutil.DocumentSourceSearcher; -import org.junit.Test; - -import com.google.common.util.concurrent.ListenableFuture; -import com.yahoo.component.chain.Chain; import com.yahoo.prelude.fastsearch.FastHit; +import com.yahoo.prelude.searcher.JuniperSearcher; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.search.result.Coverage; import com.yahoo.search.result.ErrorMessage; +import com.yahoo.search.result.Hit; import com.yahoo.search.result.HitGroup; +import com.yahoo.search.result.Relevance; +import com.yahoo.search.searchchain.Execution; +import com.yahoo.search.searchchain.testutil.DocumentSourceSearcher; import com.yahoo.search.statistics.ElapsedTimeTestCase; -import com.yahoo.search.statistics.TimeTracker; import com.yahoo.search.statistics.ElapsedTimeTestCase.CreativeTimeSource; +import com.yahoo.search.statistics.TimeTracker; import com.yahoo.text.Utf8; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Test the XML renderer @@ -158,6 +155,7 @@ public class XMLRendererTestCase { assertTrue(summary.contains("<meta type=\"context\">")); } + @SuppressWarnings("removal") private String render(Result result) throws Exception { XmlRenderer renderer = new XmlRenderer(); renderer.init(); diff --git a/vespajlib/src/main/java/com/yahoo/concurrent/CompletableFutures.java b/vespajlib/src/main/java/com/yahoo/concurrent/CompletableFutures.java index 2dab634d8be..35506ec4512 100644 --- a/vespajlib/src/main/java/com/yahoo/concurrent/CompletableFutures.java +++ b/vespajlib/src/main/java/com/yahoo/concurrent/CompletableFutures.java @@ -1,8 +1,14 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.concurrent; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; +import com.yahoo.yolean.UncheckedInterruptedException; + import java.util.List; +import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; /** * Helper for {@link java.util.concurrent.CompletableFuture} / {@link java.util.concurrent.CompletionStage}. @@ -64,4 +70,43 @@ public class CompletableFutures { return combiner.combined; } + /** + * Helper for migrating from {@link ListenableFuture} to {@link CompletableFuture> in Vespa public apis + * @deprecated to be removed in Vespa 8 + */ + @Deprecated(forRemoval = true, since = "7") + public static <V> ListenableFuture<V> toGuavaListenableFuture(CompletableFuture<V> future) { + SettableFuture<V> guavaFuture = SettableFuture.create(); + future.whenComplete((result, error) -> { + if (result != null) guavaFuture.set(result); + else if (error instanceof CancellationException) guavaFuture.setException(error); + else guavaFuture.cancel(true); + }); + return guavaFuture; + } + + /** + * Helper for migrating from {@link ListenableFuture} to {@link CompletableFuture> in Vespa public apis + * @deprecated to be removed in Vespa 8 + */ + @Deprecated(forRemoval = true, since = "7") + public static <V> CompletableFuture<V> toCompletableFuture(ListenableFuture<V> guavaFuture) { + CompletableFuture<V> future = new CompletableFuture<>(); + guavaFuture.addListener( + () -> { + if (guavaFuture.isCancelled()) future.cancel(true); + try { + V value = guavaFuture.get(); + future.complete(value); + } catch (InterruptedException e) { + // Should not happens since listener is invoked after future is complete + throw new UncheckedInterruptedException(e); + } catch (ExecutionException e) { + future.completeExceptionally(e.getCause()); + } + }, + Runnable::run); + return future; + } + } |