Correctly shutting down a websocket handler
by Robin Anil
When a client disconnects, I see that onClose is not being fired. The only
way this seems to be firing if client sents a close frame.
Is there any way to detect disconnection and immediately close all the
opened resources.
Robin
Robin Anil | Software Engineer
1 year, 2 months
embedded undertow async hello world
by seth/nqzero
i'm doing a quick survey of java webserver performance baselines, with a
focus on async, inspired somewhat by the Techempower plaintext benchmark.
i've already done jetty (both sync and async), jetty-comsat (ie quasar),
the kilim (another bytecode based fiber implementation) http server, and
sync undertow (copied from the techempower github impl). i'd like to add an
undertow async
for jetty i've used the servlet api for async, since i didn't see any other
option. but i'd prefer the non-servlet api for undertow. the docs for
undertow seem limited, esp for async. so i wanted to vet my solution. i'm
more interested in being canonical than squeezing the last bit of
performance (because eg: all the solutions are plenty fast, it's a terrible
benchmark, ease of implementation is a bigger factor than absolute
performance)
open to any general comments, but specifically wondering:
- is my use of dispatch() correct
- do i need to be calling isInIoThread()
- is it safe to access the exchange directly in reply() ? ie, in a
non-undertow thread
this is a somewhat simplified example that gets 75-80k req/s vs 85-90 for
the more verbose version, but the use of the async api is the same
____my code is below___
import io.undertow.Handlers;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.Headers;
import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;
public final class UtowAsync implements HttpHandler {
public static void main(String[] args) throws Exception {
Undertow.builder()
.addHttpListener(9097,"0.0.0.0")
.setHandler(Handlers.path().addPrefixPath("/hello",new UtowAsync()))
.build()
.start();
}
int num = 0;
HttpServerExchange acv[] = new HttpServerExchange[10000];
byte [] bytes = "hello world".getBytes();
ByteBuffer buf = ByteBuffer.allocate(bytes.length).put(bytes);
{ buf.flip(); }
synchronized void store(HttpServerExchange async) {
if (async==null) while (num > 0) {
reply(acv[--num]);
acv[num] = null;
}
else acv[num++] = async;
}
void reply(HttpServerExchange exchange) {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE,
"text/plain");
exchange.getResponseSender().send(buf.duplicate());
}
public void handleRequest(final HttpServerExchange exchange) throws
Exception {
store(exchange);
exchange.dispatch();
}
{
new Timer().schedule(new TimerTask() { public void run() {
UtowAsync.this.store(null);
} },10,10);
}
}
8 years, 11 months
UNDERTOW-577 - response code from SAM
by arjan tijms
Hi,
I wonder if it would make sense to port the (small) fix for UNDERTOW-577
back to Undertow 1.3.x, and hopefully still include this with WF 10 final.
This concerns one of the last (known) larger bugs with JASPIC in WildFly.
Without this being fixed, something like the 403 or 404 from a SAM is not
possible, Returning a 403 is specifically needed for the BASIC scheme.
For instance, the following JSR 375 authentication mechanism now works on
GlassFish, but throws a "UT010019: Response already commited" on WildFly
10rc4/Undertow 1.3.11:
public AuthStatus validateRequest(HttpServletRequest request,
HttpServletResponse response, HttpMsgContext httpMsgContext) throws
AuthException {
String[] credentials = getCredentials(request);
if (!isEmpty(credentials)) {
IdentityStore identityStore =
CDI.current().select(IdentityStore.class).get();
CredentialValidationResult result = identityStore.validate(
new UsernamePasswordCredential(credentials[0], new
Password(credentials[1])));
if (result.getStatus() == VALID) {
return httpMsgContext.notifyContainerAboutLogin(
result.getCallerName(), result.getCallerGroups());
}
}
if (httpMsgContext.isProtected()) {
response.setHeader("WWW-Authenticate", basicHeaderValue);
return httpMsgContext.responseUnAuthorized();
}
return httpMsgContext.doNothing();
}
The problem is the "httpMsgContext.responseUnAuthorized();" which does:
try {
getResponse().sendError(SC_UNAUTHORIZED);
} catch (IOException e) {
throw new IllegalStateException(e);
}
return SEND_FAILURE;
I'm not really sure what the schedule is for Undertow 1.4 vs a potential WF
11 and/or EAP 7. If WF 11 is still far away and EAP 7 will be based on WF
10, then it would really be great if this small but rather important fix
could still be included in WF 10.
Kind regards,
Arjan Tijms
8 years, 11 months
Efficient and easy way to set and get thread local variables
by Girish Sharma
Hi all,
I am really impressed by the throughput I am getting using standalone
undertow server using non-blocking IO and what not.
Now, I have a use case where I need to maintain a per call thread level
boolean flag which needs to be accessible from various parts of the code.
This flag is determined by an exchange attribute (say request header).
So the question is whether there is an easy and efficient way to get a
reference to any exchange attribute (or the exchange itself) from anywhere
in the code? I really don't want to rely on thread locals or custom caches
to do this if there is a way to get a reference. Or if Undertow natively
has similar functionality to set and retreive a thread level flags, I'd be
happy to use that too.
PS: I am still going through list archives, but the UI to go through all of
them is really tiresome :)
--
Girish Sharma
B.Tech(H), Civil Engineering,
Indian Institute of Technology, Kharagpur
8 years, 11 months
Undertow configuration
by Sascha Sadat-Guscheh
Hi!
We want to use undertow in the following scenario (numbers are from our current app running jetty as a front end):
- 24 core machine with ~60GB ram
- 10000 requests per second with an average execution time of 2-4 ms
- around 6000 concurrent http connections (keep-alive)
- incoming request size between 2000 and 4000 bytes
- response size around 4000 bytes
At the moment we just copied the configuration from the Undertow class (using a HttpOpenListener).
OptionMap socketOptions = OptionMap.builder()
.set(Options.WORKER_IO_THREADS, IO_THREADS)
.set(Options.TCP_NODELAY, true)
.set(Options.REUSE_ADDRESSES, true)
.set(Options.BALANCING_TOKENS, 1)
.set(Options.BALANCING_CONNECTIONS, 2)
.set(Options.BACKLOG, 1000)
.getMap();
OptionMap undertowOptions = OptionMap.builder().set(UndertowOptions.BUFFER_PIPELINED_DATA, true).getMap();
ByteBufferPool buffers = new DefaultByteBufferPool(true, 1024 * 16, -1, 4);
HttpOpenListener openListener = new HttpOpenListener(buffers, undertowOptions);
worker = xnio.createWorker(OptionMap.builder()
.set(Options.WORKER_IO_THREADS, IO_THREADS)
.set(Options.CONNECTION_HIGH_WATER, 1000000)
.set(Options.CONNECTION_LOW_WATER, 1000000)
.set(Options.WORKER_TASK_CORE_THREADS, IO_THREADS * 8)
.set(Options.WORKER_TASK_MAX_THREADS, IO_THREADS * 8)
.set(Options.TCP_NODELAY, true)
.set(Options.CORK, true)
.getMap());
Some of the options i don’t understand fully (BALANCING_TOKENS, BALANCING_CONNECTIONS) some may not be applicable to our scenario.
I dug around in the code a bit to find out what these settings do but i don’t feel very confident. A little help would be appreciated!
Enjoy your holidays, Sascha
8 years, 11 months
how to use futures with undertow?
by Sascha Sadat-Guscheh
Hi!
We want to use undertow as the http server for our application. Our current API is based on futures (java8 completable futures). My question is how do i combine futures with the concept of handlers. My rather naive implementation would be something like that.
class MyHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
exchange.getRequestReceiver().receiveFullString((exchange1, message) -> {
CompletableFuture<Response> responseFuture = doTheWork(message);
exchange1.dispatch();
responseFuture.whenCompleteAsync((response, throwable) -> {
exchange1.getResponseSender().send(response);
});
});
}
}
does this look reasonable? responseFuture.whenCompleteAsync() can be passed an Executor. Should i use an Executor from the HttpServerExchange for that? actually i tried to, but it’s always null. Another way would be:
class MyHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
exchange.getRequestReceiver().receiveFullString((exchange1, message) -> {
CompletableFuture<Response> responseFuture = doTheWork(message);
exchange1.dispatch(() -> {
exchange1.getResponseSender().send(responseFuture.get());
});
});
}
}
What’s the correct way to do it?
Thanks, Sascha
8 years, 12 months
Resizing undertow thread pool size dynamically
by Mohammed ElGhaouat
Hi,
I would like to know if there is a way to make undertow reducing the size
of the thread pool when the server is less loaded. Is there any
parameter(or other way) that make an idle thread die after some inactivity
time ?
Thanks.
Mohammed.
9 years