-
Notifications
You must be signed in to change notification settings - Fork 114
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
Rpc Server Reliability Upgrades #619
Merged
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
b34fcca
rpc server reliability upgrades
ali-sharif eface81
style and import fixes
ali-sharif 6751f1b
make makeSecure() access private in NanoRpcServer.java
ali-sharif c233761
removed unnecessary throws clause from AionUndertowRpcHandler.java
ali-sharif 3629342
added link to rpc configuration wiki in config file
ali-sharif File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
/.idea/ | ||
/mod*/.idea/ | ||
/mod*/*.iml | ||
ij-execution.out | ||
|
||
# build | ||
/build/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
modApiServer/src/org/aion/api/server/http/undertow/AionUndertowRootHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package org.aion.api.server.http.undertow; | ||
|
||
import io.undertow.server.HttpHandler; | ||
import io.undertow.server.HttpServerExchange; | ||
import io.undertow.server.handlers.BlockingHandler; | ||
import io.undertow.server.handlers.RequestDumpingHandler; | ||
import io.undertow.server.handlers.RequestLimitingHandler; | ||
import io.undertow.server.handlers.StuckThreadDetectionHandler; | ||
import org.aion.log.AionLoggerFactory; | ||
import org.aion.log.LogEnum; | ||
import org.slf4j.Logger; | ||
|
||
/** | ||
* Created this handler to "collect" all handlers in the chain in one place. | ||
* This is the classical approach to server design (filter request through a bunch of objects that can choose | ||
* to either pass the request object to the next handler or respond to the request itself) | ||
* | ||
* @implNote a possible optimization here would be to use the RequestBufferingHandler | ||
* | ||
* According to Stuart Douglas (http://lists.jboss.org/pipermail/undertow-dev/2018-July/002224.html): | ||
* | ||
* "The advantage [of RequestBufferingHandler] is that if you are going to | ||
* dispatch to a worker thread then the dispatch does not happen until the | ||
* request has been read, thus reducing the amount of time a worker spends | ||
* processing the request. Essentially this allows you to take advantage of | ||
* non-blocking IO even for applications that use blocking IO, but at the | ||
* expense of memory for buffering." | ||
* | ||
*/ | ||
public class AionUndertowRootHandler implements HttpHandler { | ||
private static final Logger LOG = AionLoggerFactory.getLogger(LogEnum.API.name()); | ||
|
||
// the root handler stores the first reference in the chain of handler references | ||
// (therefore we don't have to hold all the downstream references) | ||
private final HttpHandler rootHandler; | ||
|
||
public AionUndertowRootHandler(AionUndertowRpcHandler rpcHandler, | ||
RequestLimitingConfiguration requestLimiting, | ||
StuckThreadDetectorConfiguration stuckThreadDetector) { | ||
/** | ||
* Opinion: StuckThreadDetectionHandler should be enabled by default, since in the grand-scheme of things, it's | ||
* performance overhead is not too great and it could potentially help us catch implementation bugs in the API. | ||
* | ||
* See Impl: github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/StuckThreadDetectionHandler.java | ||
*/ | ||
HttpHandler thirdHandler; | ||
if (stuckThreadDetector.isEnabled()) { | ||
thirdHandler = new StuckThreadDetectionHandler(stuckThreadDetector.getTimeoutSeconds(), rpcHandler); | ||
} else { | ||
thirdHandler = rpcHandler; | ||
} | ||
|
||
// Only enable request dumping in TRACE mode | ||
HttpHandler secondHandler; | ||
if (LOG.isTraceEnabled()) { | ||
secondHandler = new RequestDumpingHandler(thirdHandler); | ||
} else { | ||
secondHandler = thirdHandler; | ||
} | ||
|
||
HttpHandler firstHandler; | ||
if (requestLimiting.isEnabled()) { | ||
/** | ||
* @implNote rationale for doing this: request limiting handler is really a last resort for someone | ||
* trying to protect their kernel from being dos-ed by limiting compute resources the RPC server can consume. | ||
* The maximumConcurrentRequests in this case, are effectively the number of worker threads available. | ||
*/ | ||
firstHandler = new RequestLimitingHandler(requestLimiting.getMaxConcurrentConnections(), | ||
requestLimiting.getQueueSize(), secondHandler); | ||
} else { | ||
firstHandler = secondHandler; | ||
} | ||
|
||
// first thing we need to do is dispatch this http request to a worker thread (off the io thread) | ||
rootHandler = new BlockingHandler(firstHandler); | ||
} | ||
|
||
@Override | ||
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception { | ||
rootHandler.handleRequest(httpServerExchange); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
modApiServer/src/org/aion/api/server/http/undertow/AionUndertowRpcHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package org.aion.api.server.http.undertow; | ||
|
||
import io.undertow.server.HttpHandler; | ||
import io.undertow.server.HttpServerExchange; | ||
import io.undertow.util.Headers; | ||
import io.undertow.util.HttpString; | ||
import io.undertow.util.Methods; | ||
import io.undertow.util.StatusCodes; | ||
import org.aion.api.server.rpc.RpcProcessor; | ||
|
||
import java.util.Map; | ||
|
||
class AionUndertowRpcHandler implements HttpHandler { | ||
private final boolean corsEnabled; | ||
private final Map<HttpString, String> corsHeaders; | ||
private final RpcProcessor rpcProcessor; | ||
|
||
public AionUndertowRpcHandler(boolean corsEnabled, Map<HttpString, String> corsHeaders, RpcProcessor rpcProcessor) { | ||
this.corsEnabled = corsEnabled; | ||
this.corsHeaders = corsHeaders; | ||
this.rpcProcessor = rpcProcessor; | ||
} | ||
|
||
private void addCorsHeaders(HttpServerExchange exchange) { | ||
for (Map.Entry<HttpString, String> header: corsHeaders.entrySet()) { | ||
exchange.getResponseHeaders().put(header.getKey(), header.getValue()); | ||
} | ||
} | ||
|
||
@Override | ||
public void handleRequest(HttpServerExchange exchange) throws Exception { | ||
boolean isPost = Methods.POST.equals(exchange.getRequestMethod()); | ||
boolean isOptions = Methods.OPTIONS.equals(exchange.getRequestMethod()); | ||
|
||
// only support POST & OPTIONS requests | ||
if (!isPost && !isOptions) { | ||
exchange.setStatusCode(StatusCodes.METHOD_NOT_ALLOWED); | ||
exchange.setPersistent(false); // don't need to keep-alive connection in case of error. | ||
exchange.endExchange(); | ||
return; | ||
} | ||
|
||
// respond to cors-preflight request | ||
if (corsEnabled && isOptions) { | ||
addCorsHeaders(exchange); | ||
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain"); | ||
exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, "0"); | ||
exchange.getResponseSender().send(""); | ||
return; | ||
} | ||
|
||
/** respond to rpc call; {@link io.Undertow.BlockingReceiverImpl#receiveFullString} */ | ||
exchange.getRequestReceiver().receiveFullString((_exchange, body) -> { | ||
if (corsEnabled) addCorsHeaders(_exchange); | ||
_exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json"); | ||
_exchange.getResponseSender().send(rpcProcessor.process(body)); | ||
}); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
modApiServer/src/org/aion/api/server/http/undertow/RequestLimitingConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.aion.api.server.http.undertow; | ||
|
||
public class RequestLimitingConfiguration { | ||
private final boolean enabled; | ||
private final int maxConcurrentConnections; | ||
private final int queueSize; | ||
|
||
public RequestLimitingConfiguration(boolean enabled, int maxConcurrentConnections, int queueSize) { | ||
this.enabled = enabled; | ||
this.maxConcurrentConnections = maxConcurrentConnections; | ||
this.queueSize = queueSize; | ||
} | ||
|
||
public boolean isEnabled() { return enabled; } | ||
public int getMaxConcurrentConnections() { return maxConcurrentConnections; } | ||
public int getQueueSize() { return queueSize; } | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any exception being thrown here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed