Skip to content
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

Implement destroy() method for graceful shutdown of MetricsStreamServlet #128

Merged
merged 1 commit into from
Mar 20, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,25 @@ public class HystrixMetricsStreamServlet extends HttpServlet {
private static AtomicInteger concurrentConnections = new AtomicInteger(0);
private static DynamicIntProperty maxConcurrentConnections = DynamicPropertyFactory.getInstance().getIntProperty("hystrix.stream.maxConcurrentConnections", 5);

private volatile boolean isDestroyed = false;

/**
* Handle incoming GETs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
handleRequest(request, response);
}

/**
* Handle servlet being undeployed by gracefully releasing connections so poller threads stop.
*/
@Override
public void destroy() {
/* set marker so the loops can break out */
isDestroyed = true;
super.destroy();
}

/**
* - maintain an open connection with the client
Expand Down Expand Up @@ -115,7 +127,7 @@ private void handleRequest(HttpServletRequest request, HttpServletResponse respo
// we will use a "single-writer" approach where the Servlet thread does all the writing
// by fetching JSON messages from the MetricJsonListener to write them to the output
try {
while (poller.isRunning()) {
while (poller.isRunning() && !isDestroyed) {
List<String> jsonMessages = jsonListener.getJsonMetrics();
if (jsonMessages.isEmpty()) {
// https://github.com/Netflix/Hystrix/issues/85 hystrix.stream holds connection open if no metrics
Expand All @@ -126,8 +138,15 @@ private void handleRequest(HttpServletRequest request, HttpServletResponse respo
response.getWriter().println("data: " + json + "\n");
}
}

/* shortcut breaking out of loop if we have been destroyed */
if(isDestroyed) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this if really necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's not. I put it there just so destroying wouldn't potentially wait for the Thread.sleep but that's generally 500ms to maybe 2000ms - but someone could theoretically inject a very long delay. That's the only edge case this doesn't gracefully handle (someone putting in a 10000ms delay for example) since we don't interrupt the threads (and we don't track them all) but I don't know that this edge case is a big concern.

Short answer - probably not worth the optimization.

break;
}

// after outputting all the messages we will flush the stream
response.flushBuffer();

// now wait the 'delay' time
Thread.sleep(delay);
}
Expand Down