Skip to content

Commit

Permalink
Streamline the response handling to reduce the amount of garbage crea…
Browse files Browse the repository at this point in the history
…ted per request.
  • Loading branch information
ldaley committed Sep 15, 2014
1 parent 4e3a79c commit bbd7429
Show file tree
Hide file tree
Showing 39 changed files with 379 additions and 529 deletions.
61 changes: 61 additions & 0 deletions ratpack-core/src/main/java/ratpack/exec/PromiseOperations.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,67 @@ public interface PromiseOperations<T> {
*/
<O> Promise<O> flatMap(Function<? super T, ? extends Promise<O>> transformer);

/**
* Handles (terminates) the promise if it matches the given predicate.
* <p>
* This can be useful to provide common validation or similar.
* If the predicate applies to the promised value, it will not be propagated to the next subscriber.
* <pre class="java">{@code
* import ratpack.exec.ExecControl;
* import ratpack.exec.Execution;
* import ratpack.exec.Promise;
* import ratpack.func.Function;
* import ratpack.test.UnitTest;
* import ratpack.test.exec.ExecHarness;
* import ratpack.test.exec.ExecResult;
*
* import java.util.concurrent.Callable;
*
* public class Example {
*
* public static void main(String[] args) throws Exception {
* try (ExecHarness harness = UnitTest.execHarness()) {
* ExecResult<String> result = harness.execute(new Function<Execution, Promise<String>>() {
* public Promise<String> apply(Execution execution) throws Exception {
* final ExecControl control = execution.getControl();
* return control
* .blocking(new Callable<String>() {
* public String call() throws Exception {
* return "foo";
* }
* })
* .flatMap(new Function<String, Promise<String>>() {
* public Promise<String> apply(final String s) throws Exception {
* return control.blocking(new Callable<String>() {
* public String call() throws Exception {
* return s.toUpperCase();
* }
* });
* }
* })
* .map(new Function<String, String>() {
* public String apply(String s) throws Exception {
* return s + "-BAR";
* }
* });
* }
* });
*
* assert result.getValue().equals("FOO-BAR");
* }
* }
*
* }
* }</pre>
* <p>
* In the above example, {@code flatMap()} is being used because the transformation requires a blocking operation (it doesn't really in this case, but that's what the example is showing).
* In this case, it would be more convenient to use {@link #blockingMap(Function)}.
*
* @param transformer the transformation to apply to the promised value
* @param <O> the type of the transformed object
* @see #blockingMap(Function)
* @return a promise for the transformed value
*/
Promise<T> route(Predicate<? super T> predicate, Action<? super T> action);

Promise<T> onNull(NoArgAction action);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void run() {
final String ifNoneMatch = context.getRequest().getHeaders().get(HttpHeaders.Names.IF_NONE_MATCH);
Response response = context.getResponse();
if (ifNoneMatch != null && ifNoneMatch.trim().equals("*")) {
response.status(NOT_MODIFIED.code(), NOT_MODIFIED.reasonPhrase()).send();
response.status(NOT_MODIFIED.code()).send();
return;
}

Expand All @@ -73,7 +73,7 @@ public void run() {
}

try {
response.sendFile(context, attributes, file);
response.sendFile(attributes, file);
} catch (Exception e) {
throw ExceptionUtils.uncheck(e);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@

package ratpack.file.internal;

import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.reactivestreams.Subscriber;

import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;

public interface ResponseTransmitter {

void transmit(Object body);
void transmit(HttpResponseStatus status, ByteBuf body);

void transmit(HttpResponseStatus responseStatus, BasicFileAttributes basicFileAttributes, Path file);

Subscriber<Object> transmitter();
Subscriber<Object> transmitter(HttpResponseStatus status);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ratpack.file.internal;

import com.google.common.base.Predicate;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.UncheckedExecutionException;
import ratpack.func.Pair;

import java.util.concurrent.ExecutionException;

import static ratpack.util.ExceptionUtils.toException;
import static ratpack.util.ExceptionUtils.uncheck;

public class ShouldCompressPredicate implements Predicate<Pair<Long, String>> {

private final long compressionMinSize;
private final ImmutableSet<String> compressionMimeTypeWhiteList;
private final ImmutableSet<String> compressionMimeTypeBlackList;

private final LoadingCache<String, Boolean> cache = CacheBuilder.newBuilder().build(new CacheLoader<String, Boolean>() {
@Override
public Boolean load(@SuppressWarnings("NullableProblems") String key) throws Exception {
for (String s : compressionMimeTypeWhiteList) {
if (key.startsWith(s)) {
return true;
}
}
for (String s : compressionMimeTypeBlackList) {
if (key.startsWith(s)) {
return false;
}
}
return true;
}
});

public ShouldCompressPredicate(long compressionMinSize, ImmutableSet<String> compressionMimeTypeWhiteList, ImmutableSet<String> compressionMimeTypeBlackList) {
this.compressionMinSize = compressionMinSize;
this.compressionMimeTypeWhiteList = compressionMimeTypeWhiteList;
this.compressionMimeTypeBlackList = compressionMimeTypeBlackList;
}

@Override
public boolean apply(Pair<Long, String> fileDetails) {
if (fileDetails.left < compressionMinSize) {
return false;
}

try {
return cache.get(fileDetails.right);
} catch (ExecutionException | UncheckedExecutionException e) {
throw uncheck(toException(e.getCause()));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ public void lastModified(Date date, Runnable runnable) {
long ifModifiedSinceSecs = time / 1000;

if (lastModifiedSecs == ifModifiedSinceSecs) {
requestConstants.response.status(NOT_MODIFIED.code(), NOT_MODIFIED.reasonPhrase()).send();
requestConstants.response.status(NOT_MODIFIED.code()).send();
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@

package ratpack.handling.internal;

import io.netty.handler.codec.http.HttpHeaders;
import ratpack.handling.Context;
import ratpack.http.Request;
import ratpack.handling.Redirector;
import ratpack.http.Request;
import ratpack.http.internal.HttpHeaderConstants;
import ratpack.server.PublicAddress;

import java.net.URI;
Expand All @@ -32,7 +32,7 @@ public class DefaultRedirector implements Redirector {
public void redirect(Context context, String location, int code) {
context.getResponse().status(code);
String normalizedLocation = generateRedirectLocation(context, context.getRequest(), location);
context.getResponse().getHeaders().set(HttpHeaders.Names.LOCATION, normalizedLocation);
context.getResponse().getHeaders().set(HttpHeaderConstants.LOCATION, normalizedLocation);
context.getResponse().send();
}

Expand Down
Loading

0 comments on commit bbd7429

Please sign in to comment.