Browse Source

Realistic low-level approach with "rapidoid-http-fast" (#2257)

Nikolche Mihajlovski 9 years ago
parent
commit
a65b3ed66d

+ 7 - 0
frameworks/Java/rapidoid/README.md

@@ -1,3 +1,10 @@
 # Rapidoid Benchmarking Test
 
 This is the Rapidoid portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### Plaintext and JSON Encoding tests - using Rapidoid's low-level API (rapidoid-http-fast)
+* [lowlevel/Main.java](src/main/java/lowlevel/Main.java)
+* [lowlevel/PlaintextAndJsonServer.java](src/main/java/lowlevel/PlaintextAndJsonServer.java)
+
+## Versions
+Rapidoid 5.2.2 (http://www.rapidoid.org)

+ 22 - 20
frameworks/Java/rapidoid/benchmark_config.json

@@ -1,24 +1,26 @@
 {
   "framework": "rapidoid",
-  "tests": [{
-    "default": {
-      "setup_file": "setup",
-      "json_url": "/json",
-      "plaintext_url": "/plaintext",
-      "port": 8080,
-      "approach": "Stripped",
-      "classification": "Platform",
-      "database": "None",
-      "framework": "rapidoid",
-      "language": "Java",
-      "orm": "Raw",
-      "platform": "Rapidoid",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "rapidoid",
-      "notes": "",
-      "versus": "rapidoid"
+  "tests": [
+    {
+      "default": {
+        "setup_file": "setup-low-level",
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Platform",
+        "database": "None",
+        "framework": "rapidoid-http-fast",
+        "language": "Java",
+        "orm": "Raw",
+        "platform": "Rapidoid",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "rapidoid-http-fast",
+        "notes": "",
+        "versus": ""
+      }
     }
-  }]
+  ]
 }

+ 24 - 36
frameworks/Java/rapidoid/pom.xml

@@ -1,71 +1,59 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
 	<modelVersion>4.0.0</modelVersion>
 
-    <groupId>com.techempower</groupId>
-    <artifactId>rapidoid</artifactId>
-    <version>1.0</version>
+	<groupId>com.techempower</groupId>
+	<artifactId>rapidoid</artifactId>
+	<version>1.0</version>
 	<packaging>jar</packaging>
-	
-     <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    </properties>
-    
-    <dependencies>
-        <dependency>
-            <groupId>org.rapidoid</groupId>
-            <artifactId>rapidoid-http</artifactId>
-            <version>3.0.0</version>
-        </dependency>
-	<dependency>
-		<groupId>com.fasterxml.jackson.core</groupId>
-		<artifactId>jackson-databind</artifactId>
-		<version>2.6.0-rc2</version>
-	</dependency>
-	<dependency>
-		<groupId>com.fasterxml.jackson.module</groupId>
-		<artifactId>jackson-module-afterburner</artifactId>
-		<version>2.6.0-rc2</version>
-	</dependency>
-    </dependencies>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.rapidoid</groupId>
+			<artifactId>rapidoid-quick</artifactId>
+			<version>5.2.2</version>
+		</dependency>
+	</dependencies>
 
 	<build>
 		<plugins>
+
 			<plugin>
 				<inherited>true</inherited>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-compiler-plugin</artifactId>
-				<version>2.3.2</version>
+				<version>3.1</version>
 				<configuration>
-					<source>1.7</source>
-					<target>1.7</target>
+					<source>1.8</source>
+					<target>1.8</target>
 					<optimize>true</optimize>
 					<debug>false</debug>
 				</configuration>
 			</plugin>
+
 			<plugin>
 				<artifactId>maven-assembly-plugin</artifactId>
 				<configuration>
-					<archive>
-						<manifest>
-							<mainClass>hello.HelloWebServer</mainClass>
-						</manifest>
-					</archive>
 					<descriptorRefs>
 						<descriptorRef>jar-with-dependencies</descriptorRef>
 					</descriptorRefs>
 				</configuration>
 				<executions>
 					<execution>
-						<id>make-assembly</id> <!-- this is used for inheritance merges -->
-						<phase>package</phase> <!-- bind to the packaging phase -->
+						<id>make-assembly</id>
+						<phase>package</phase>
 						<goals>
 							<goal>single</goal>
 						</goals>
 					</execution>
 				</executions>
 			</plugin>
+
 		</plugins>
 	</build>
 </project>

+ 1 - 1
frameworks/Java/rapidoid/setup.sh → frameworks/Java/rapidoid/setup-low-level.sh

@@ -5,4 +5,4 @@ fw_depends java maven
 mvn clean compile assembly:single
 
 cd target
-java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -jar rapidoid-1.0-jar-with-dependencies.jar &
+java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts -cp rapidoid-1.0-jar-with-dependencies.jar lowlevel.Main &

+ 5 - 7
frameworks/Java/rapidoid/source_code

@@ -1,7 +1,5 @@
-./rapidoid/src/
-./rapidoid/src/main
-./rapidoid/src/main/java
-./rapidoid/src/main/java/hello
-./rapidoid/src/main/java/hello/HelloWebServer.java
-./rapidoid/src/main/java/hello/SimpleHttpProtocol.java
-./rapidoid/src/main/java/hello/Message.java
+./rapidoid/src/main/java/common
+./rapidoid/src/main/java/common/Message.java
+./rapidoid/src/main/java/lowlevel
+./rapidoid/src/main/java/lowlevel/Main.java
+./rapidoid/src/main/java/lowlevel/PlaintextAndJsonServer.java

+ 1 - 1
frameworks/Java/rapidoid/src/main/java/hello/Message.java → frameworks/Java/rapidoid/src/main/java/common/Message.java

@@ -1,4 +1,4 @@
-package hello;
+package common;
 
 public class Message {
 

+ 0 - 12
frameworks/Java/rapidoid/src/main/java/hello/HelloWebServer.java

@@ -1,12 +0,0 @@
-package hello;
-
-import org.rapidoid.net.Serve;
-
-public class HelloWebServer {
-
-	public static void main(String[] args) throws Exception {
-		int port = args.length > 0 ? Integer.parseInt(args[0]) : 8080;
-		Serve.server().protocol(new SimpleHttpProtocol()).port(port).build().start();
-	}
-
-}

+ 0 - 178
frameworks/Java/rapidoid/src/main/java/hello/SimpleHttpProtocol.java

@@ -1,178 +0,0 @@
-package hello;
-
-/*
- * #%L
- * rapidoid-demo
- * %%
- * Copyright (C) 2014 - 2015 Nikolche Mihajlovski
- * %%
- * 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.
- * #L%
- */
-
-import org.rapidoid.buffer.Buf;
-import org.rapidoid.bytes.BytesUtil;
-import org.rapidoid.data.Range;
-import org.rapidoid.data.Ranges;
-import org.rapidoid.http.HttpParser;
-import org.rapidoid.net.Protocol;
-import org.rapidoid.net.abstracts.Channel;
-import org.rapidoid.net.impl.RapidoidHelper;
-import org.rapidoid.util.Dates;
-import org.rapidoid.wrap.BoolWrap;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
-
-public class SimpleHttpProtocol implements Protocol {
-
-	private static final byte[] HTTP_200_OK = "HTTP/1.1 200 OK\r\n".getBytes();
-
-	private static final byte[] HTTP_404_NOT_FOUND = "HTTP/1.1 404 Not Found\r\nContent-Length: 10\r\n\r\nNot found!"
-			.getBytes();
-
-	private static final byte[] CONN_KEEP_ALIVE = "Connection: keep-alive\r\n"
-			.getBytes();
-
-	private static final byte[] CONN_CLOSE = "Connection: close\r\n".getBytes();
-
-	private static final byte[] SERVER_X = "Server: X\r\n".getBytes();
-
-	private static final byte[] CONTENT_LENGTH_HDR = "Content-Length: "
-			.getBytes();
-
-	private static final byte[] CONTENT_TYPE_PLAIN = "Content-Type: text/plain; charset=UTF-8\r\n"
-			.getBytes();
-
-	private static final byte[] CONTENT_TYPE_JSON = "Content-Type: application/json; charset=UTF-8\r\n"
-			.getBytes();
-
-	private static final byte[] CONTENT_LENGTH = "Content-Length:           "
-			.getBytes();
-
-	private static final byte[] RESPONSE = "Hello, World!".getBytes();
-
-	private static final byte[] DATE_HDR = "Date: ".getBytes();
-
-	private static final byte[] RESPONSE_LENGTH = String.valueOf(
-			RESPONSE.length).getBytes();
-
-	private static final byte[] URI_PLAIN = "/plaintext".getBytes();
-
-	private static final byte[] URI_JSON = "/json".getBytes();
-
-	private static final HttpParser HTTP_PARSER = new HttpParser();
-
-	public static final ObjectMapper MAPPER = mapper();
-
-	private static ObjectMapper mapper() {
-		ObjectMapper mapper = new ObjectMapper();
-		mapper.registerModule(new AfterburnerModule());
-		return mapper;
-	}
-
-	public void process(Channel ctx) {
-		if (ctx.isInitial()) {
-			return;
-		}
-
-		Buf buf = ctx.input();
-		RapidoidHelper helper = ctx.helper();
-
-		Range[] ranges = helper.ranges1.ranges;
-		Ranges headers = helper.ranges2;
-
-		BoolWrap isGet = helper.booleans[0];
-		BoolWrap isKeepAlive = helper.booleans[1];
-
-		Range verb = ranges[ranges.length - 1];
-		Range uri = ranges[ranges.length - 2];
-		Range path = ranges[ranges.length - 3];
-		Range query = ranges[ranges.length - 4];
-		Range protocol = ranges[ranges.length - 5];
-		Range body = ranges[ranges.length - 6];
-
-		HTTP_PARSER.parse(buf, isGet, isKeepAlive, body, verb, uri, path,
-				query, protocol, headers, helper);
-
-		response(ctx, buf, path, isGet.value, isKeepAlive.value);
-	}
-
-	private void response(Channel ctx, Buf buf, Range path, boolean isGet,
-			boolean isKeepAlive) {
-		boolean processed = false;
-
-		if (isGet) {
-
-			ctx.write(HTTP_200_OK);
-
-			ctx.write(isKeepAlive ? CONN_KEEP_ALIVE : CONN_CLOSE);
-
-			ctx.write(SERVER_X);
-
-			ctx.write(DATE_HDR);
-			ctx.write(Dates.getDateTimeBytes());
-			ctx.write(CR_LF);
-
-			if (BytesUtil.matches(buf.bytes(), path, URI_PLAIN, true)
-					|| path.length == 1) {
-				handlePlaintext(ctx);
-				processed = true;
-			} else if (BytesUtil.matches(buf.bytes(), path, URI_JSON, true)) {
-				handleJson(ctx);
-				processed = true;
-			}
-
-			ctx.closeIf(!isKeepAlive);
-		}
-
-		if (!processed) {
-			ctx.write(HTTP_404_NOT_FOUND);
-			ctx.close();
-		}
-	}
-
-	private void handlePlaintext(Channel ctx) {
-		ctx.write(CONTENT_LENGTH_HDR);
-		ctx.write(RESPONSE_LENGTH);
-		ctx.write(CR_LF);
-
-		ctx.write(CONTENT_TYPE_PLAIN);
-		ctx.write(CR_LF);
-		ctx.write(RESPONSE);
-	}
-
-	private void handleJson(Channel ctx) {
-		Buf output = ctx.output();
-
-		ctx.write(CONTENT_TYPE_JSON);
-		ctx.write(CONTENT_LENGTH);
-
-		int posConLen = output.size() - 10;
-		ctx.write(CR_LF);
-		ctx.write(CR_LF);
-
-		int posBefore = output.size();
-
-		Message msg = new Message("Hello, World!");
-		try {
-			MAPPER.writeValue(output.asOutputStream(), msg);
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-
-		int posAfter = output.size();
-		output.putNumAsText(posConLen, posAfter - posBefore, false);
-	}
-
-}

+ 9 - 0
frameworks/Java/rapidoid/src/main/java/lowlevel/Main.java

@@ -0,0 +1,9 @@
+package lowlevel;
+
+public class Main {
+
+	public static void main(String[] args) throws Exception {
+		new PlaintextAndJsonServer().listen(8080);
+	}
+
+}

+ 40 - 0
frameworks/Java/rapidoid/src/main/java/lowlevel/PlaintextAndJsonServer.java

@@ -0,0 +1,40 @@
+package lowlevel;
+
+import common.Message;
+import org.rapidoid.buffer.Buf;
+import org.rapidoid.data.BufRange;
+import org.rapidoid.data.BufRanges;
+import org.rapidoid.http.AbstractHttpServer;
+import org.rapidoid.http.HttpStatus;
+import org.rapidoid.http.MediaType;
+import org.rapidoid.net.abstracts.Channel;
+
+public class PlaintextAndJsonServer extends AbstractHttpServer {
+
+	private static final byte[] URI_PLAINTEXT = "/plaintext".getBytes();
+
+	private static final byte[] URI_JSON = "/json".getBytes();
+
+	private static final byte[] HELLO_WORLD = "Hello, World!".getBytes();
+
+	public PlaintextAndJsonServer() {
+		super("X", "", "", false);
+	}
+
+	@Override
+	protected HttpStatus handle(Channel ctx, Buf buf, BufRange verb, BufRange uri, BufRange path, BufRange query,
+	                            BufRange protocol, BufRanges headers, boolean isGet, boolean isKeepAlive, BufRange body) {
+
+		if (isGet) {
+			if (matches(buf, path, URI_PLAINTEXT)) {
+				return ok(ctx, isKeepAlive, HELLO_WORLD, MediaType.TEXT_PLAIN);
+
+			} else if (matches(buf, path, URI_JSON)) {
+				return serializeToJson(ctx, isKeepAlive, new Message("Hello, World!"));
+			}
+		}
+
+		return HttpStatus.NOT_FOUND;
+	}
+
+}