-
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
Issue #7344 - wait for forked jetty process #7374
Issue #7344 - wait for forked jetty process #7374
Conversation
Signed-off-by: Jan Bartel <[email protected]>
Signed-off-by: Jan Bartel <[email protected]>
jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java
Outdated
Show resolved
Hide resolved
{ | ||
getLog().error(e); | ||
out.write(command.getBytes()); | ||
out.flush(); |
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.
No, TCP is not very friendly with open/write/close.
You should always read to have a confirmation that the other peer received the data (even if it's only reading -1).
The other machine could be overloaded, so SYN+PSH+FIN may be received by the recipient at OS level (but not yet at application level), but because the machine is overloaded timeouts may happen, so the OS decides to RST back to the sender, which has already closed.
The net result is that the sender does not know that something went wrong, the recipient never received the data at the application level, and everything went into /dev/null.
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.
If the sender is interested in getting confirmation from the remote jetty, then they configure a non-zero stopWait
timeout, in which case we set the socket soTimeout and read from it to get the "Shutting down" message. Alternatively, if we have been able to obtain the pid, we send the message and then wait up to stopWait
seconds on the process itself to stop. So in either case, there will be a wait for either a response message, or the process to die. If no wait is configured, then we don't wait for any response, we just send the message and exit.
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.
You are assuming that the message you send reaches the other end. I'm saying that it may not.
Now, if you care whether the message reaches the other end, you should read, at least a -1.
If you don't care whether the message reaches the other end, then you may not read (like the code above), just don't assume that send()
actually produces the results you want.
It's not about getting confirmation about the specific command.
It's about getting a confirmation that the message even arrived to the other process.
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.
So @sbordet how long does the sender need to wait to read from the socket to ensure that the message was sent? The behaviour of the ShutdownMonitor
is to stop jetty before replying with "Stopped" and exiting. In the case where the caller has not configured a stopWait
time they do not want to wait until the socket is closed etc.
* org.eclipse.jetty.server.ShutdownMonitor. | ||
* | ||
*/ | ||
public class MockShutdownMonitor |
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.
Why can't we use ShutdownMonitor
?
It should be possible because there are tests that use ShutdownMonitor
directly and not a mock.
We really want to test the real ShutdownMonitor
, not this mock class.
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 I'm not interested in testing ShutdownMonitor - we have other tests for that ;). The unit test it relates to is of the JettyStopMojo - all I want to do is to test the behaviour of the JettyStopMojo, and for that I need to control the behaviour of the ShutdownMonitor and its ShutdownMonitorRunnable. I can't do that by subclassing because ShutdownMonitor is effectively not extensible, hence the mocks.
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 made ShutdownMonitor.start()
and stop()
public and I can rewrite these tests using directly ShutdownMonitor
without 200 lines of mock code that must to be bug-free and maintained.
I'd prefer to fix ShutdownMonitor
than adding a mock for it.
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 I have changed the final test testStopWait
to talk to the real ShutdownMonitor
. None of the other tests can use the real class because I need to test failure/fallback modes, and ShutdownMonitor
is unsubclassable (private no-args constructor).
jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java
Outdated
Show resolved
Hide resolved
if (handle.isAlive()) | ||
{ | ||
handle = future.get(stopWait, TimeUnit.SECONDS); | ||
} |
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.
Don't think this block is correct.
future.get(wait, unit)
throws TimeoutException
if the time elapses, but the code seems to hint something like "if timeout and still alive, do something", so the "do something" will be skipped.
Have you considered using ProcessHandle.destroy[Forcibly]()
if the timeout expires?
Perhaps along with CompletableFuture.orTimeout()
?
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 this would be a behaviour change of the JettyStopMojo: it has always just made a best effort to stop the remote jetty, waiting up to the configured time to get an acknowledgement from jetty that it is shutting down before giving up. I suppose we could add a new configuration option to forcibly destroy the process after the timeout expires, but I think that might be in another issue.
Signed-off-by: Jan Bartel <[email protected]>
* org.eclipse.jetty.server.ShutdownMonitor. | ||
* | ||
*/ | ||
public class MockShutdownMonitor |
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 made ShutdownMonitor.start()
and stop()
public and I can rewrite these tests using directly ShutdownMonitor
without 200 lines of mock code that must to be bug-free and maintained.
I'd prefer to fix ShutdownMonitor
than adding a mock for it.
jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestJettyStopMojo.java
Outdated
Show resolved
Hide resolved
jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestJettyStopMojo.java
Outdated
Show resolved
Hide resolved
jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestJettyStopMojo.java
Outdated
Show resolved
Hide resolved
jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/TestJettyStopMojo.java
Outdated
Show resolved
Hide resolved
...y-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/MockShutdownMonitorRunnable.java
Show resolved
Hide resolved
...y-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/MockShutdownMonitorRunnable.java
Outdated
Show resolved
Hide resolved
jetty-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/MockShutdownMonitor.java
Outdated
Show resolved
Hide resolved
...y-maven-plugin/src/test/java/org/eclipse/jetty/maven/plugin/MockShutdownMonitorRunnable.java
Outdated
Show resolved
Hide resolved
jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyStopMojo.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Jan Bartel <[email protected]>
…7344-wait-for-forked-jetty-process
@sbordet latest release has gone out - can you now approve this pr? |
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.
@janbartel a few suggested fixes have not been addressed (e.g. javadocs, semicolons, unnecessary types, etc.)?
* Issue #7344 Make plugin wait for forked jetty process to stop Signed-off-by: Jan Bartel <[email protected]> (cherry picked from commit 0b33877)
Closes #7344
Change
org.eclipse.jetty.server.ShutdownMonitor
to add a new command:pid
. This reports the process id of the running jetty process. Changed theorg.eclipse.jetty.maven.plugin.JettyStopMojo
to first send this command to the running jetty process to obtain its id before sending astop
command. If thepid
is retrievable, the stop mojo will wait (a configurable amount of time) for the jetty process to exit before terminating. If thepid
is bad or missing, then the stop mojo falls back to it's previous behaviour of waiting a configurable amount of time to receive theStopped
message from the jetty process before terminating.