Skip to content

Commit

Permalink
jstachio/rocker: remove buffer reuse from RockerModule/JStachioModule
Browse files Browse the repository at this point in the history
- fix #3424
  • Loading branch information
jknack committed May 19, 2024
1 parent 03bb587 commit ce92b0b
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,12 @@
*/
interface JStachioBuffer {

public ByteBufferEncodedOutput acquire();
ByteBufferEncodedOutput acquire();

public void release(ByteBufferEncodedOutput buffer);
void release(ByteBufferEncodedOutput buffer);

static JStachioBuffer of(int bufferSize, boolean reuseBuffer) {
if (reuseBuffer) {
return new ReuseBuffer(bufferSize);
} else {
return new NoReuseBuffer(bufferSize);
}
static JStachioBuffer of(int bufferSize) {
return new NoReuseBuffer(bufferSize);
}
}

Expand All @@ -38,24 +34,3 @@ public ByteBufferEncodedOutput acquire() {
@Override
public void release(ByteBufferEncodedOutput buffer) {}
}

class ReuseBuffer implements JStachioBuffer {
private final ThreadLocal<ByteBufferEncodedOutput> localBuffer;

public ReuseBuffer(int bufferSize) {
super();
this.localBuffer =
ThreadLocal.withInitial(
() -> ByteBufferEncodedOutput.ofByteArray(StandardCharsets.UTF_8, bufferSize));
}

@Override
public ByteBufferEncodedOutput acquire() {
return localBuffer.get();
}

@Override
public void release(ByteBufferEncodedOutput buffer) {
buffer.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ public class JStachioModule implements Extension {

private @Nullable JStachio jstachio;
private int bufferSize = 8 * 1024;
private boolean reuseBuffer;
private BiFunction<Context, String, String> contextFunction = (ctx, key) -> ctx.getAttribute(key);
private BiFunction<Context, String, String> contextFunction = Context::getAttribute;

/**
* Sets the jstachio to use instead of the default.
Expand Down Expand Up @@ -70,9 +69,10 @@ public class JStachioModule implements Extension {
*
* @param reuseBuffer True for reuse the buffer. Default is: <code>false</code>
* @return This module.
* @deprecated
*/
@Deprecated
public JStachioModule reuseBuffer(boolean reuseBuffer) {
this.reuseBuffer = reuseBuffer;
return this;
}

Expand Down Expand Up @@ -114,7 +114,7 @@ public void install(@NonNull Jooby application) throws Exception {
} else {
services.put(JStachio.class, this.jstachio);
}
JStachioBuffer buffer = JStachioBuffer.of(bufferSize, reuseBuffer);
JStachioBuffer buffer = JStachioBuffer.of(bufferSize);

JStachioMessageEncoder encoder = new JStachioMessageEncoder(j, buffer, contextFunction);
JStachioResultHandler handler = new JStachioResultHandler(j, buffer, contextFunction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import io.netty.handler.ssl.IdentityCipherSuiteFilter;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.util.ResourceLeakDetector;
import io.netty.util.concurrent.DefaultThreadFactory;

/**
Expand All @@ -51,14 +50,6 @@
* @since 2.0.0
*/
public class NettyServer extends Server.Base {
private static final String LEAK_DETECTION = "io.netty.leakDetection.level";

static {
System.setProperty(
LEAK_DETECTION,
System.getProperty(LEAK_DETECTION, ResourceLeakDetector.Level.DISABLED.name()));
}

private static final int _50 = 50;

private static final int _100 = 100;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.CompositeByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ResourceLeakDetector;

/**
* Implementation of the {@code DataBufferFactory} interface based on a Netty 4 {@link
Expand All @@ -29,6 +30,16 @@
*/
public class NettyDataBufferFactory implements DataBufferFactory {

private static final String LEAK_DETECTION = "io.netty.leakDetection.level";

static {
System.setProperty(
LEAK_DETECTION,
System.getProperty(LEAK_DETECTION, ResourceLeakDetector.Level.DISABLED.name()));
ResourceLeakDetector.setLevel(
ResourceLeakDetector.Level.valueOf(System.getProperty(LEAK_DETECTION)));
}

private final ByteBufAllocator byteBufAllocator;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package io.jooby.rocker;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import com.fizzed.rocker.ContentType;
import com.fizzed.rocker.RockerOutput;
Expand All @@ -19,38 +18,37 @@
*
* @author edgar
*/
class DataBufferOutput implements RockerOutput<DataBufferOutput> {
public class DataBufferOutput implements RockerOutput<DataBufferOutput> {

/** Default buffer size: <code>4k</code>. */
public static final int BUFFER_SIZE = 4096;

private final Charset charset;
private final ContentType contentType;

/** The buffer where data is stored. */
protected DataBuffer buffer;

DataBufferOutput(ContentType contentType, DataBuffer buffer) {
DataBufferOutput(Charset charset, ContentType contentType, DataBuffer buffer) {
this.charset = charset;
this.contentType = contentType;
this.buffer = buffer;
}

void reset() {
buffer.clear();
}

@Override
public ContentType getContentType() {
return contentType;
}

@Override
public Charset getCharset() {
return StandardCharsets.UTF_8;
return charset;
}

@Override
public DataBufferOutput w(String string) {
return w(string.getBytes(StandardCharsets.UTF_8));
buffer.write(string, getCharset());
return this;
}

@Override
Expand All @@ -73,26 +71,9 @@ public DataBuffer toBuffer() {
return buffer;
}

static RockerOutputFactory<DataBufferOutput> factory(DataBufferFactory factory, int bufferSize) {
static RockerOutputFactory<DataBufferOutput> factory(
Charset charset, DataBufferFactory factory, int bufferSize) {
return (contentType, charsetName) ->
new DataBufferOutput(contentType, factory.allocateBuffer(bufferSize));
}

static RockerOutputFactory<DataBufferOutput> reuse(
RockerOutputFactory<DataBufferOutput> factory) {
return new RockerOutputFactory<DataBufferOutput>() {
private final ThreadLocal<DataBufferOutput> thread = new ThreadLocal<>();

@Override
public DataBufferOutput create(ContentType contentType, String charsetName) {
DataBufferOutput output = thread.get();
if (output == null) {
output = factory.create(contentType, charsetName);
thread.set(output);
}
output.reset();
return output;
}
};
new DataBufferOutput(charset, contentType, factory.allocateBuffer(bufferSize));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
*/
package io.jooby.rocker;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import com.fizzed.rocker.RockerOutputFactory;
import com.fizzed.rocker.runtime.RockerRuntime;
import edu.umd.cs.findbugs.annotations.NonNull;
import io.jooby.Environment;
import io.jooby.Extension;
import io.jooby.Jooby;
import io.jooby.ServiceRegistry;
Expand All @@ -21,12 +23,22 @@
* @since 2.0.0
*/
public class RockerModule implements Extension {

private Boolean reloading;
private int bufferSize;
private final Charset charset;

public RockerModule(@NonNull Charset charset, int bufferSize) {
this.charset = charset;
this.bufferSize = bufferSize;
}

private int bufferSize = DataBufferOutput.BUFFER_SIZE;
public RockerModule(@NonNull Charset charset) {
this(charset, DataBufferOutput.BUFFER_SIZE);
}

private boolean reuseBuffer;
public RockerModule() {
this(StandardCharsets.UTF_8);
}

/**
* Turn on/off autoreloading of template for development.
Expand All @@ -45,8 +57,21 @@ public class RockerModule implements Extension {
*
* @param bufferSize Buffer size.
* @return This module.
* @deprecated Use {@link #bufferSize}
*/
@Deprecated(forRemoval = true)
public @NonNull RockerModule useBuffer(int bufferSize) {
return bufferSize(bufferSize);
}

/**
* Configure buffer size to use while rendering. The buffer can grow ups when need it, so this
* option works as a hint to allocate initial memory.
*
* @param bufferSize Buffer size.
* @return This module.
*/
public @NonNull RockerModule bufferSize(int bufferSize) {
this.bufferSize = bufferSize;
return this;
}
Expand All @@ -57,25 +82,22 @@ public class RockerModule implements Extension {
*
* @param reuseBuffer True for reuse the buffer. Default is: <code>false</code>
* @return This module.
* @deprecated
*/
@Deprecated(forRemoval = true)
public RockerModule reuseBuffer(boolean reuseBuffer) {
this.reuseBuffer = reuseBuffer;
return this;
}

@Override
public void install(@NonNull Jooby application) {
Environment env = application.getEnvironment();
RockerRuntime runtime = RockerRuntime.getInstance();
var env = application.getEnvironment();
var runtime = RockerRuntime.getInstance();
boolean reloading =
this.reloading == null
? (env.isActive("dev") && runtime.isReloadingPossible())
: this.reloading;
RockerOutputFactory<DataBufferOutput> factory =
DataBufferOutput.factory(application.getBufferFactory(), bufferSize);
if (reuseBuffer) {
factory = DataBufferOutput.reuse(factory);
}
var factory = DataBufferOutput.factory(charset, application.getBufferFactory(), bufferSize);
runtime.setReloading(reloading);
// result handler
application.resultHandler(new RockerResultHandler(factory));
Expand Down

0 comments on commit ce92b0b

Please sign in to comment.