Hello Laurent,
Your hunch is correct. You never want to block the I/O thread as each thread is shared
between many connections, and a pause prevents them from being processed. It’s totally
reasonable to call dispatch(), which transfers the exchange to the worker pool where you
can wait on a database reply, and in fact this is a normal pattern. The worker pool is
sized to be pretty large as its expected to host lots of waiters. You can of course tweak
this, or dispatch to your own special pool if you like. The big advantage to an async
database call, even with requiring a worker thread, is that you can do other work while
its running if your pattern fits (e.g. parallel db calls, iterative computation, etc).
Alternatively, if the database provides a callback on complete option, you can save
yourself a worker thread and reuse the thread they generate the callback from. At that
callback point you can write your response out to the exchange. Just note, that the
thread policy of an exchange is that only one thread at a time can interact with it. If
you have a use case where the a request bounces back and forth (e.g. a very long stream
containing multiple records that must be written to the database as they com in), then you
will need to coordinate locking around that. Such use-cases though should be weighed
against the simplicity of just blocking in a worker thread.
To answer a second question you have in a comment from your example, startBlocking() just
enables the use of a plain inputstream/outputstream, which can only be done once you have
dispatched and blocking i/o is now ok.
Hope this helps,
-Jason
On Dec 12, 2014, at 3:44 PM, Laurent Bedubourg
<laurent(a)labe.me> wrote:
Ok, I think my mail could be reduced to :
Is it possible possible to transfer the HttpServerExchange responsibility to another
thread ?
Regards
Laurent
On Fri Dec 12 2014 at 7:11:01 PM Laurent Bedubourg <laurent(a)labe.me> wrote:
Hello,
I am evaluating Undertow and trying to fit an async database (with scala, Activate and
https://github.com/mauricio/postgresql-async which use netty and nio).
The good news is that it more or less works.
My main concern is that the database system create threads using scala futures and that I
am forced to "Await" for the result of my Futures to send the result to the
HttpServerExchange.
I am forced to dispath() the request because Await locks the current thread and I
shouldn't lock the IO thread from my Handler, should I?
It made me wondering : is is really a good idea to use futures + Await with undertow and
more generaly nio?
If the thread pool is limited and I lock threads, even if the database driver is async
and uses nio, am I bitting my own leg?
Thanks for any input you can give me and sorry if it's too scala related :)
Regards
Laurent
PS: Here's the handleRequest I am using to test this, any comment or help welcome too
since I am discovering the API.
def handleRequest(x:io.undertow.server.HttpServerExchange){
if (x.isInIoThread()){
x.dispatch(this)
return
}
// useful or not? no change
// x.startBlocking()
// Ok, we are in worker thread we can work a little with database
// val f = asyncTransactionalChain { implicit context =>
// for (
// a <- asyncTransactional { new AMember("aaa") };
// b <- asyncById[AMember](a.id)
// ) yield b
// }
// Simulate database work with just a future
val f = future {
Some(1)
}(scala.concurrent.ExecutionContext.Implicits.global)
// send string to xchange
def sendReply(str:String){
x.getResponseHeaders().put(io.undertow.util.Headers.CONTENT_TYPE,
"text/plain")
x.getResponseSender().send(str)
// x.endExchange()
}
// // this fails
// f.onSuccess {
// case Some(result) => sendReply(result.toString)
// }(scala.concurrent.ExecutionContext.Implicits.global)
// // this works
val result = Await.result(f, Duration(1000, MILLISECONDS))
sendReply(result.toString)
}
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev
--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat