Fine-tuned handling of running state

Issue: SPR-14527
This commit is contained in:
Juergen Hoeller
2016-12-14 21:59:49 +01:00
parent 5a29069798
commit b366e159f8
2 changed files with 17 additions and 18 deletions

View File

@@ -37,11 +37,11 @@ import org.springframework.web.reactive.socket.adapter.JettyWebSocketHandlerAdap
import org.springframework.web.reactive.socket.server.RequestUpgradeStrategy; import org.springframework.web.reactive.socket.server.RequestUpgradeStrategy;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
/** /**
* A {@link RequestUpgradeStrategy} for use with Jetty. * A {@link RequestUpgradeStrategy} for use with Jetty.
* *
* @author Violeta Georgieva * @author Violeta Georgieva
* @author Rossen Stoyanchev
* @since 5.0 * @since 5.0
*/ */
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Lifecycle { public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Lifecycle {
@@ -54,7 +54,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
private ServletContext servletContext; private ServletContext servletContext;
private boolean running = false; private volatile boolean running = false;
private final Object lifecycleMonitor = new Object(); private final Object lifecycleMonitor = new Object();
@@ -69,7 +69,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
this.factory.setCreator((request, response) -> adapterHolder.get()); this.factory.setCreator((request, response) -> adapterHolder.get());
this.factory.start(); this.factory.start();
} }
catch (Exception ex) { catch (Throwable ex) {
throw new IllegalStateException("Unable to start WebSocketServerFactory", ex); throw new IllegalStateException("Unable to start WebSocketServerFactory", ex);
} }
} }
@@ -80,29 +80,25 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
public void stop() { public void stop() {
synchronized (this.lifecycleMonitor) { synchronized (this.lifecycleMonitor) {
if (isRunning()) { if (isRunning()) {
this.running = false;
try { try {
this.factory.stop(); this.factory.stop();
} }
catch (Exception ex) { catch (Throwable ex) {
throw new IllegalStateException("Failed to stop WebSocketServerFactory", ex); throw new IllegalStateException("Failed to stop WebSocketServerFactory", ex);
} }
finally {
this.running = false;
}
} }
} }
} }
@Override @Override
public boolean isRunning() { public boolean isRunning() {
synchronized (this.lifecycleMonitor) { return this.running;
return this.running;
}
} }
@Override @Override
public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler) { public Mono<Void> upgrade(ServerWebExchange exchange, WebSocketHandler handler) {
ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse(); ServerHttpResponse response = exchange.getResponse();
JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter(request, response, handler); JettyWebSocketHandlerAdapter adapter = new JettyWebSocketHandlerAdapter(request, response, handler);
@@ -146,7 +142,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Life
synchronized (this.lifecycleMonitor) { synchronized (this.lifecycleMonitor) {
if (this.servletContext == null) { if (this.servletContext == null) {
this.servletContext = request.getServletContext(); this.servletContext = request.getServletContext();
this.servletContext.setAttribute(DecoratedObjectFactory.ATTR, new DecoratedObjectFactory()); this.servletContext.setAttribute(DecoratedObjectFactory.ATTR, new DecoratedObjectFactory());
start(); start();
} }
} }

View File

@@ -65,9 +65,12 @@ import org.springframework.web.socket.server.RequestUpgradeStrategy;
*/ */
public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, ServletContextAware, Lifecycle { public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, ServletContextAware, Lifecycle {
private static final ThreadLocal<WebSocketHandlerContainer> wsContainerHolder = private static final ThreadLocal<WebSocketHandlerContainer> containerHolder =
new NamedThreadLocal<>("WebSocket Handler Container"); new NamedThreadLocal<>("WebSocketHandlerContainer");
// Configurable factory adapter due to Jetty 9.3.15+ API differences:
// using WebSocketServerFactory(ServletContext) as a version indicator
private final WebSocketServerFactoryAdapter factoryAdapter = private final WebSocketServerFactoryAdapter factoryAdapter =
(ClassUtils.hasConstructor(WebSocketServerFactory.class, ServletContext.class) ? (ClassUtils.hasConstructor(WebSocketServerFactory.class, ServletContext.class) ?
new ModernJettyWebSocketServerFactoryAdapter() : new LegacyJettyWebSocketServerFactoryAdapter()); new ModernJettyWebSocketServerFactoryAdapter() : new LegacyJettyWebSocketServerFactoryAdapter());
@@ -129,8 +132,8 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv
@Override @Override
public void stop() { public void stop() {
if (isRunning()) { if (isRunning()) {
this.running = false;
try { try {
this.running = false;
this.factoryAdapter.stop(); this.factoryAdapter.stop();
} }
catch (Throwable ex) { catch (Throwable ex) {
@@ -187,7 +190,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv
new WebSocketHandlerContainer(handlerAdapter, selectedProtocol, selectedExtensions); new WebSocketHandlerContainer(handlerAdapter, selectedProtocol, selectedExtensions);
try { try {
wsContainerHolder.set(container); containerHolder.set(container);
this.factoryAdapter.getFactory().acceptWebSocket(servletRequest, servletResponse); this.factoryAdapter.getFactory().acceptWebSocket(servletRequest, servletResponse);
} }
catch (IOException ex) { catch (IOException ex) {
@@ -195,7 +198,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv
"Response update failed during upgrade to WebSocket: " + request.getURI(), ex); "Response update failed during upgrade to WebSocket: " + request.getURI(), ex);
} }
finally { finally {
wsContainerHolder.remove(); containerHolder.remove();
} }
} }
@@ -263,7 +266,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy, Serv
this.factory.setCreator(new WebSocketCreator() { this.factory.setCreator(new WebSocketCreator() {
@Override @Override
public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) { public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response) {
WebSocketHandlerContainer container = wsContainerHolder.get(); WebSocketHandlerContainer container = containerHolder.get();
Assert.state(container != null, "Expected WebSocketHandlerContainer"); Assert.state(container != null, "Expected WebSocketHandlerContainer");
response.setAcceptedSubProtocol(container.getSelectedProtocol()); response.setAcceptedSubProtocol(container.getSelectedProtocol());
response.setExtensions(container.getExtensionConfigs()); response.setExtensions(container.getExtensionConfigs());