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

[RFC] Netty: add Netty 4 as a new Netty backend and make it default #25

Merged
merged 3 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,43 @@ on:
jobs:
run-tests-job:
runs-on: ubuntu-latest
env:
replay-workdir: replay
criminals-workdir: criminals
steps:
- name: Checkout
uses: actions/checkout@v2
with:
path: ${{env.replay-workdir}}
- uses: actions/setup-java@v1
with:
java-version: '11'
- name: Run unit-tests
run: ./gradlew clean test --info --rerun-tasks
working-directory: ${{env.replay-workdir}}
- name: Run integration tests
run: ./gradlew clean uitest -Dselenide.headless=true
working-directory: ${{env.replay-workdir}}
- uses: actions/upload-artifact@v2
if: failure()
with:
name: test-report
path: build/reports/
path: ${{env.replay-workdir}}/build/reports/
- name: Checkout Criminals
uses: actions/checkout@v2
with:
repository: asolntsev/criminals
path: ${{env.criminals-workdir}}
- name: Setup RePlay for Criminals
run: echo 'includeBuild "'../${{env.replay-workdir}}'"' > ${{env.criminals-workdir}}/settings.gradle
- name: Run Criminals unit-tests
run: ./gradlew clean test --info
working-directory: ${{env.criminals-workdir}}
- name: Run Criminals integration tests
run: ./gradlew clean uitest -Dselenide.headless=true
working-directory: ${{env.criminals-workdir}}
- uses: actions/upload-artifact@v2
if: failure()
with:
name: criminals-test-report
path: ${{env.criminals-workdir}}/build/reports/
1 change: 1 addition & 0 deletions framework/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dependencies {
implementation('org.hibernate:hibernate-ehcache:5.6.12.Final') {transitive = false}
// Upgrade to Netty4 is WIP: https://github.com/codeborne/replay/pull/25
api('io.netty:netty:3.10.6.Final')
api('io.netty:netty-all:4.1.84.Final')
api('org.slf4j:slf4j-api:2.0.3')
api('org.slf4j:slf4j-reload4j:2.0.3')
api('org.slf4j:jul-to-slf4j:2.0.3')
Expand Down
4 changes: 2 additions & 2 deletions framework/src/play/Invoker.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.jamonapi.Monitor;
import com.jamonapi.MonitorFactory;
import play.server.PlayHandler;
import play.server.NettyInvocation;
import play.utils.PThreadFactory;

import java.util.concurrent.Future;
Expand Down Expand Up @@ -32,7 +32,7 @@ public class Invoker {
* The code to run
* @return The future object, to know when the task is completed
*/
public Future<?> invoke(PlayHandler.NettyInvocation invocation) {
public Future<?> invoke(NettyInvocation invocation) {
Monitor monitor = MonitorFactory.getMonitor("Invoker queue size", "elmts.");
monitor.add(executor.getQueue().size());
invocation.onQueued();
Expand Down
6 changes: 6 additions & 0 deletions framework/src/play/server/NettyInvocation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package play.server;

import play.Invocation;

public abstract class NettyInvocation extends Invocation {
}
4 changes: 2 additions & 2 deletions framework/src/play/server/ResettableFileInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

import static java.util.Objects.requireNonNull;

class ResettableFileInputStream extends InputStream {
public class ResettableFileInputStream extends InputStream {
private final File file;
private InputStream in;

ResettableFileInputStream(File file) throws FileNotFoundException {
public ResettableFileInputStream(File file) throws FileNotFoundException {
this.file = requireNonNull(file);
reset();
}
Expand Down
71 changes: 3 additions & 68 deletions framework/src/play/server/Server.java
Original file line number Diff line number Diff line change
@@ -1,78 +1,13 @@
package play.server;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.Play;
import play.Play.Mode;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;

import static java.lang.Integer.parseInt;

public class Server {
private static final Logger logger = LoggerFactory.getLogger(Server.class);

public static int httpPort;
private final Play play;

public class Server extends play.server.netty4.Server {
public Server(Play play) {
this(play, parseInt(Play.configuration.getProperty("http.port", "9000")));
super(play);
}

public Server(Play play, int port) {
this.play = play;
httpPort = port;
}

public void start() {
System.setProperty("file.encoding", "utf-8");

ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool())
);
InetAddress address = address();
bootstrap.setPipelineFactory(new HttpServerPipelineFactory(Play.invoker, play.getActionInvoker()));
bootstrap.bind(new InetSocketAddress(address, httpPort));
bootstrap.setOption("child.tcpNoDelay", true);

if (Play.mode == Mode.DEV) {
if (address == null) {
logger.info("Listening for HTTP on port {} (Waiting a first request to start) ...", httpPort);
} else {
logger.info("Listening for HTTP at {}:{} (Waiting a first request to start) ...", address, httpPort);
}
} else {
if (address == null) {
logger.info("Listening for HTTP on port {} ...", httpPort);
} else {
logger.info("Listening for HTTP at {}:{} ...", address, httpPort);
}
}
}

private InetAddress address() {
if (Play.configuration.getProperty("http.address") != null) {
return address(Play.configuration.getProperty("http.address"));
}

if (System.getProperties().containsKey("http.address")) {
return address(System.getProperty("http.address"));
}

return null;
}

private InetAddress address(String host) {
try {
return InetAddress.getByName(host);
}
catch (UnknownHostException e) {
throw new RuntimeException("Cannot resolve address " + host, e);
}
super(play, port);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package play.server;
package play.server.netty3;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package play.server;
package play.server.netty3;

import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package play.server;
package play.server.netty3;


import org.jboss.netty.buffer.AbstractChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferFactory;
import org.jboss.netty.buffer.ChannelBufferIndexFinder;
import org.jboss.netty.buffer.WrappedChannelBuffer;
import play.server.ResettableFileInputStream;

import java.io.File;
import java.io.FileNotFoundException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package play.server;
package play.server.netty3;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package play.server;
package play.server.netty3;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package play.server;
package play.server.netty3;

import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipeline;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package play.server;
package play.server.netty3;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
Expand All @@ -17,7 +17,6 @@
import org.jboss.netty.handler.stream.ChunkedWriteHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.Invocation;
import play.InvocationContext;
import play.Invoker;
import play.Play;
Expand All @@ -36,6 +35,7 @@
import play.mvc.Scope.RenderArgs;
import play.mvc.results.NotFound;
import play.mvc.results.RenderStatic;
import play.server.NettyInvocation;
import play.templates.JavaExtensions;
import play.templates.TemplateLoader;
import play.utils.ErrorsCookieCrypter;
Expand Down Expand Up @@ -121,7 +121,7 @@ public void messageReceived(final ChannelHandlerContext ctx, MessageEvent messag
copyResponse(ctx, request, response, nettyRequest);
} else {
// Delegate to Play framework
invoker.invoke(new NettyInvocation(request, response, ctx, nettyRequest, messageEvent));
invoker.invoke(new Netty3Invocation(request, response, ctx, nettyRequest, messageEvent));
}

} catch (IllegalArgumentException ex) {
Expand All @@ -138,14 +138,14 @@ public void messageReceived(final ChannelHandlerContext ctx, MessageEvent messag

private static final Map<String, RenderStatic> staticPathsCache = new HashMap<>();

public class NettyInvocation extends Invocation {
private class Netty3Invocation extends NettyInvocation {
private final ChannelHandlerContext ctx;
private final Request request;
private final Response response;
private final HttpRequest nettyRequest;
private final MessageEvent event;

public NettyInvocation(Request request, Response response, ChannelHandlerContext ctx, HttpRequest nettyRequest, MessageEvent e) {
public Netty3Invocation(Request request, Response response, ChannelHandlerContext ctx, HttpRequest nettyRequest, MessageEvent e) {
this.ctx = ctx;
this.request = request;
this.response = response;
Expand Down
78 changes: 78 additions & 0 deletions framework/src/play/server/netty3/Server.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package play.server.netty3;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.Play;
import play.Play.Mode;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;

import static java.lang.Integer.parseInt;

public class Server {
private static final Logger logger = LoggerFactory.getLogger(Server.class);

public static int httpPort;
private final Play play;

public Server(Play play) {
this(play, parseInt(Play.configuration.getProperty("http.port", "9000")));
}

public Server(Play play, int port) {
this.play = play;
httpPort = port;
}

public void start() {
System.setProperty("file.encoding", "utf-8");

ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool())
);
InetAddress address = address();
bootstrap.setPipelineFactory(new HttpServerPipelineFactory(Play.invoker, play.getActionInvoker()));
bootstrap.bind(new InetSocketAddress(address, httpPort));
bootstrap.setOption("child.tcpNoDelay", true);

if (Play.mode == Mode.DEV) {
if (address == null) {
logger.info("Listening for HTTP on port {} (Waiting a first request to start) ...", httpPort);
} else {
logger.info("Listening for HTTP at {}:{} (Waiting a first request to start) ...", address, httpPort);
}
} else {
if (address == null) {
logger.info("Listening for HTTP on port {} ...", httpPort);
} else {
logger.info("Listening for HTTP at {}:{} ...", address, httpPort);
}
}
}

private InetAddress address() {
if (Play.configuration.getProperty("http.address") != null) {
return address(Play.configuration.getProperty("http.address"));
}

if (System.getProperties().containsKey("http.address")) {
return address(System.getProperty("http.address"));
}

return null;
}

private InetAddress address(String host) {
try {
return InetAddress.getByName(host);
}
catch (UnknownHostException e) {
throw new RuntimeException("Cannot resolve address " + host, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package play.server;
package play.server.netty3;

import org.apache.commons.io.IOUtils;
import org.jboss.netty.buffer.ChannelBufferInputStream;
Expand Down
Loading