-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Jetty 12 handler as boolean processor #9035
Conversation
a35b2e9
to
c6d691d
Compare
All Handlers are Processors, which now return a boolean to indicate the request has been accepted. The request/response/callback are no longer modal, so there is no race with the boolean return.
0ed443b
to
4b4a46a
Compare
<properties> | ||
<bundle-symbolic-name>${project.groupId}.asciidoctor.extensions</bundle-symbolic-name> | ||
</properties> | ||
|
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.
Hmm I've still missed some changes in HEAD?
Fixes from bad squash
…ler-as-boolean-processor
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 really like the way this is going. The code is much simpler. It has to also be faster.
jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
Show resolved
Hide resolved
Minor renames to reduce differences
"Core enter http://0.0.0.0/", | ||
"EE9 enter /", | ||
"EE9 exit /", | ||
"Core exit http://0.0.0.0/", | ||
// Enter again for process(request, response, callback) |
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.
This one makes me smile :)
Minor cleanups to reduce differences
Fixed race in test
Fixed missed merge
Non generic DelayedHandler
restored comment
inlined the Handler.Processor class
@sbordet @lorban I've been looking at redoing this branch from HEAD, and I really don't think that is the right way to go. There is a lot of work and consideration in this branch that will take a huge effort to redo from scratch. I know there is some risk of some changes being lost in this branch, but I honestly think that is less if we review this branch and check for them, than if we redo the changes to the many hundreds of handlers. Whilst much of it can be done with tools, ultimately you need to visit most of the handlers to check them. I've visited many hundreds of handlers and believe I have them mostly right. Redoing all that work will not remove the need for a detailed review to recheck them all. I don't think there is any significant kruft from previous branches left, and if there is it needs to be reviewed, identified and labelled as kruft anyway (rather than a change to be remade). Again, I don't think it is less work to redo the branch rather than review this one. |
…te/handler/Rule.java Co-authored-by: Simone Bordet <simone.bordet@gmail.com>
…b.com/eclipse/jetty.project into jetty-12-handler-as-boolean-processor
Avoid iterations if only ServletPathSpec instances Avoid tests for empty mappings. Better reset implementation
Avoid iterations if only ServletPathSpec instances Avoid tests for empty mappings. Better reset implementation
Improve suffix matching
Improve exact matching
…ler-as-boolean-processor
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.
LGTM. I have a few nits, but I'll fix them myself.
* which is appropriate for wall clock time.</p> | ||
* @return The timestamp that the request was received/created in nanoseconds, relative to {@link System#nanoTime()}. | ||
*/ | ||
default long getNanoTimeStamp() |
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.
Rename to getNanoTime()
.
*/ | ||
default long getNanoTimeStamp() | ||
{ | ||
return NanoTime.now() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis() - getTimeStamp()); |
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 think this implementation is correct, since currentTimeMillis()
can drift.
Must use another field to store the creation/received nanoTime.
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.
@sbordet we do. It is in the HttpStream. This is just used for test code.
jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java
Outdated
Show resolved
Hide resolved
if (stream != null) | ||
return stream.getNanoTimeStamp(); | ||
|
||
return NanoTime.now() - TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis() - getTimeStamp()); |
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.
Should call super
instead?
As we don't want to duplicate the (wrong) logic 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.
Does super call a default implementation? I don't think so.
Renamed HttpStream.getNanoTimeStamp() to getNanoTime(). Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
…sor'. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
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.
LGTM
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Another alternative Handler architecture inspired by #8978 for #8929
This PR removed the modal nature of
Request
,Response
andCallback
, so that they need not be accepted (via API or returning aProcessor
) before they are fully active. Not only does this avoid a lot of locking on many methods and on the state change, but it also allows for a boolean return fromprocess
to no longer be a race condition.If a
handler.process(request,response,callback)
returnstrue
, then the callback will be called and the caller must no longer act on the request/response/callback. Iffalse
is returned, then the handler will never act on the request/response/callback so the caller must either handle the request itself (e.g. 404) or it is free to try another handler.If an exception is thrown, then the caller cannot know if the callback will be called and must assume not and race with any lingering async process to write an error and complete the callback.
In #8978, I tried having a separate
Handler.Conditional
type that would have a method on it to accept requests and only then callprocess
which had to handle the request. This is probably workable but had several cons:So this branch is simpler, as essentially all handlers are conditional.