diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-11-22 19:16:47 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-11-22 19:21:42 +0100 |
commit | a8ffe38e6e5401011352cda5bc92a0a7a88ef40e (patch) | |
tree | 97f14cfb809f365aebfdbfaed43c8733aec930e6 /subprojects/language-web | |
parent | fix(frontend): mobx 6.7.0 typing (diff) | |
download | refinery-a8ffe38e6e5401011352cda5bc92a0a7a88ef40e.tar.gz refinery-a8ffe38e6e5401011352cda5bc92a0a7a88ef40e.tar.zst refinery-a8ffe38e6e5401011352cda5bc92a0a7a88ef40e.zip |
chore: upgrade to Java 19
Use Java 19 and Jetty 12 to take advantage of Project Loom preview
features to reduce CPU usage due to XtextWebDocumentAccess thread pools.
Diffstat (limited to 'subprojects/language-web')
9 files changed, 112 insertions, 84 deletions
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java index ec55036f..706413a9 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/ProblemWebModule.java | |||
@@ -3,12 +3,13 @@ | |||
3 | */ | 3 | */ |
4 | package tools.refinery.language.web; | 4 | package tools.refinery.language.web; |
5 | 5 | ||
6 | import org.eclipse.xtext.ide.ExecutorServiceProvider; | ||
6 | import org.eclipse.xtext.web.server.XtextServiceDispatcher; | 7 | import org.eclipse.xtext.web.server.XtextServiceDispatcher; |
7 | import org.eclipse.xtext.web.server.model.IWebDocumentProvider; | 8 | import org.eclipse.xtext.web.server.model.IWebDocumentProvider; |
8 | import org.eclipse.xtext.web.server.model.XtextWebDocumentAccess; | 9 | import org.eclipse.xtext.web.server.model.XtextWebDocumentAccess; |
9 | import org.eclipse.xtext.web.server.occurrences.OccurrencesService; | 10 | import org.eclipse.xtext.web.server.occurrences.OccurrencesService; |
10 | |||
11 | import tools.refinery.language.web.occurrences.ProblemOccurrencesService; | 11 | import tools.refinery.language.web.occurrences.ProblemOccurrencesService; |
12 | import tools.refinery.language.web.xtext.VirtualThreadExecutorServiceProvider; | ||
12 | import tools.refinery.language.web.xtext.server.push.PushServiceDispatcher; | 13 | import tools.refinery.language.web.xtext.server.push.PushServiceDispatcher; |
13 | import tools.refinery.language.web.xtext.server.push.PushWebDocumentAccess; | 14 | import tools.refinery.language.web.xtext.server.push.PushWebDocumentAccess; |
14 | import tools.refinery.language.web.xtext.server.push.PushWebDocumentProvider; | 15 | import tools.refinery.language.web.xtext.server.push.PushWebDocumentProvider; |
@@ -20,16 +21,20 @@ public class ProblemWebModule extends AbstractProblemWebModule { | |||
20 | public Class<? extends IWebDocumentProvider> bindIWebDocumentProvider() { | 21 | public Class<? extends IWebDocumentProvider> bindIWebDocumentProvider() { |
21 | return PushWebDocumentProvider.class; | 22 | return PushWebDocumentProvider.class; |
22 | } | 23 | } |
23 | 24 | ||
24 | public Class<? extends XtextWebDocumentAccess> bindXtextWebDocumentAccess() { | 25 | public Class<? extends XtextWebDocumentAccess> bindXtextWebDocumentAccess() { |
25 | return PushWebDocumentAccess.class; | 26 | return PushWebDocumentAccess.class; |
26 | } | 27 | } |
27 | 28 | ||
28 | public Class<? extends XtextServiceDispatcher> bindXtextServiceDispatcher() { | 29 | public Class<? extends XtextServiceDispatcher> bindXtextServiceDispatcher() { |
29 | return PushServiceDispatcher.class; | 30 | return PushServiceDispatcher.class; |
30 | } | 31 | } |
31 | 32 | ||
32 | public Class<? extends OccurrencesService> bindOccurrencesService() { | 33 | public Class<? extends OccurrencesService> bindOccurrencesService() { |
33 | return ProblemOccurrencesService.class; | 34 | return ProblemOccurrencesService.class; |
34 | } | 35 | } |
36 | |||
37 | public Class<? extends ExecutorServiceProvider> bindExecutorServiceProvider() { | ||
38 | return VirtualThreadExecutorServiceProvider.class; | ||
39 | } | ||
35 | } | 40 | } |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java index 58c8ea4e..5da16850 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java | |||
@@ -5,20 +5,21 @@ package tools.refinery.language.web; | |||
5 | 5 | ||
6 | import jakarta.servlet.DispatcherType; | 6 | import jakarta.servlet.DispatcherType; |
7 | import jakarta.servlet.SessionTrackingMode; | 7 | import jakarta.servlet.SessionTrackingMode; |
8 | import org.eclipse.jetty.ee10.servlet.DefaultServlet; | ||
9 | import org.eclipse.jetty.ee10.servlet.ServletContextHandler; | ||
10 | import org.eclipse.jetty.ee10.servlet.ServletHolder; | ||
11 | import org.eclipse.jetty.ee10.servlet.SessionHandler; | ||
12 | import org.eclipse.jetty.ee10.websocket.server.config.JettyWebSocketServletContainerInitializer; | ||
8 | import org.eclipse.jetty.server.Server; | 13 | import org.eclipse.jetty.server.Server; |
9 | import org.eclipse.jetty.server.session.SessionHandler; | 14 | import org.eclipse.jetty.util.VirtualThreads; |
10 | import org.eclipse.jetty.servlet.DefaultServlet; | ||
11 | import org.eclipse.jetty.servlet.ServletContextHandler; | ||
12 | import org.eclipse.jetty.servlet.ServletHolder; | ||
13 | import org.eclipse.jetty.util.resource.Resource; | 15 | import org.eclipse.jetty.util.resource.Resource; |
14 | import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; | 16 | import org.eclipse.jetty.util.resource.ResourceFactory; |
15 | import org.slf4j.Logger; | 17 | import org.slf4j.Logger; |
16 | import org.slf4j.LoggerFactory; | 18 | import org.slf4j.LoggerFactory; |
17 | import tools.refinery.language.web.config.BackendConfigServlet; | 19 | import tools.refinery.language.web.config.BackendConfigServlet; |
18 | import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet; | 20 | import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet; |
19 | 21 | ||
20 | import java.io.File; | 22 | import java.io.File; |
21 | import java.io.IOException; | ||
22 | import java.net.InetSocketAddress; | 23 | import java.net.InetSocketAddress; |
23 | import java.net.URI; | 24 | import java.net.URI; |
24 | import java.net.URISyntaxException; | 25 | import java.net.URISyntaxException; |
@@ -42,13 +43,18 @@ public class ServerLauncher { | |||
42 | 43 | ||
43 | private final Server server; | 44 | private final Server server; |
44 | 45 | ||
45 | public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource, String[] allowedOrigins, | 46 | public ServerLauncher(InetSocketAddress bindAddress, String[] allowedOrigins, String webSocketUrl) { |
46 | String webSocketUrl) { | ||
47 | server = new Server(bindAddress); | 47 | server = new Server(bindAddress); |
48 | if (server.getThreadPool() instanceof VirtualThreads.Configurable virtualThreadsConfigurable) { | ||
49 | // Change this to setVirtualThreadsExecutor once | ||
50 | // https://github.com/eclipse/jetty.project/commit/83154b4ffe4767ef44981598d6c26e6a5d32e57c gets released. | ||
51 | virtualThreadsConfigurable.setUseVirtualThreads(VirtualThreads.areSupported()); | ||
52 | } | ||
48 | var handler = new ServletContextHandler(); | 53 | var handler = new ServletContextHandler(); |
49 | addSessionHandler(handler); | 54 | addSessionHandler(handler); |
50 | addProblemServlet(handler, allowedOrigins); | 55 | addProblemServlet(handler, allowedOrigins); |
51 | addBackendConfigServlet(handler, webSocketUrl); | 56 | addBackendConfigServlet(handler, webSocketUrl); |
57 | var baseResource = getBaseResource(); | ||
52 | if (baseResource != null) { | 58 | if (baseResource != null) { |
53 | handler.setBaseResource(baseResource); | 59 | handler.setBaseResource(baseResource); |
54 | handler.setWelcomeFiles(new String[]{"index.html"}); | 60 | handler.setWelcomeFiles(new String[]{"index.html"}); |
@@ -95,6 +101,35 @@ public class ServerLauncher { | |||
95 | handler.addServlet(defaultServletHolder, "/"); | 101 | handler.addServlet(defaultServletHolder, "/"); |
96 | } | 102 | } |
97 | 103 | ||
104 | private Resource getBaseResource() { | ||
105 | var factory = ResourceFactory.of(server); | ||
106 | var baseResourceOverride = System.getenv("BASE_RESOURCE"); | ||
107 | if (baseResourceOverride != null) { | ||
108 | // If a user override is provided, use it. | ||
109 | return factory.newResource(baseResourceOverride); | ||
110 | } | ||
111 | var indexUrlInJar = ServerLauncher.class.getResource("/webapp/index.html"); | ||
112 | if (indexUrlInJar != null) { | ||
113 | // If the app is packaged in the jar, serve it. | ||
114 | URI webRootUri = null; | ||
115 | try { | ||
116 | webRootUri = URI.create(indexUrlInJar.toURI().toASCIIString().replaceFirst("/index.html$", "/")); | ||
117 | } catch (URISyntaxException e) { | ||
118 | throw new IllegalStateException("Jar has invalid base resource URI", e); | ||
119 | } | ||
120 | return factory.newResource(webRootUri); | ||
121 | } | ||
122 | // Look for unpacked production artifacts (convenience for running from IDE). | ||
123 | var unpackedResourcePathComponents = new String[]{System.getProperty("user.dir"), "build", "webpack", | ||
124 | "production"}; | ||
125 | var unpackedResourceDir = new File(String.join(File.separator, unpackedResourcePathComponents)); | ||
126 | if (unpackedResourceDir.isDirectory()) { | ||
127 | return factory.newResource(unpackedResourceDir.toPath()); | ||
128 | } | ||
129 | // Fall back to just serving a 404. | ||
130 | return null; | ||
131 | } | ||
132 | |||
98 | public void start() throws Exception { | 133 | public void start() throws Exception { |
99 | server.start(); | 134 | server.start(); |
100 | LOG.info("Server started on {}", server.getURI()); | 135 | LOG.info("Server started on {}", server.getURI()); |
@@ -104,10 +139,9 @@ public class ServerLauncher { | |||
104 | public static void main(String[] args) { | 139 | public static void main(String[] args) { |
105 | try { | 140 | try { |
106 | var bindAddress = getBindAddress(); | 141 | var bindAddress = getBindAddress(); |
107 | var baseResource = getBaseResource(); | ||
108 | var allowedOrigins = getAllowedOrigins(); | 142 | var allowedOrigins = getAllowedOrigins(); |
109 | var webSocketUrl = getWebSocketUrl(); | 143 | var webSocketUrl = getWebSocketUrl(); |
110 | var serverLauncher = new ServerLauncher(bindAddress, baseResource, allowedOrigins, webSocketUrl); | 144 | var serverLauncher = new ServerLauncher(bindAddress, allowedOrigins, webSocketUrl); |
111 | serverLauncher.start(); | 145 | serverLauncher.start(); |
112 | } catch (Exception exception) { | 146 | } catch (Exception exception) { |
113 | LOG.error("Fatal server error", exception); | 147 | LOG.error("Fatal server error", exception); |
@@ -137,29 +171,6 @@ public class ServerLauncher { | |||
137 | return new InetSocketAddress(listenAddress, listenPort); | 171 | return new InetSocketAddress(listenAddress, listenPort); |
138 | } | 172 | } |
139 | 173 | ||
140 | private static Resource getBaseResource() throws IOException, URISyntaxException { | ||
141 | var baseResourceOverride = System.getenv("BASE_RESOURCE"); | ||
142 | if (baseResourceOverride != null) { | ||
143 | // If a user override is provided, use it. | ||
144 | return Resource.newResource(baseResourceOverride); | ||
145 | } | ||
146 | var indexUrlInJar = ServerLauncher.class.getResource("/webapp/index.html"); | ||
147 | if (indexUrlInJar != null) { | ||
148 | // If the app is packaged in the jar, serve it. | ||
149 | var webRootUri = URI.create(indexUrlInJar.toURI().toASCIIString().replaceFirst("/index.html$", "/")); | ||
150 | return Resource.newResource(webRootUri); | ||
151 | } | ||
152 | // Look for unpacked production artifacts (convenience for running from IDE). | ||
153 | var unpackedResourcePathComponents = new String[]{System.getProperty("user.dir"), "build", "webpack", | ||
154 | "production"}; | ||
155 | var unpackedResourceDir = new File(String.join(File.separator, unpackedResourcePathComponents)); | ||
156 | if (unpackedResourceDir.isDirectory()) { | ||
157 | return Resource.newResource(unpackedResourceDir); | ||
158 | } | ||
159 | // Fall back to just serving a 404. | ||
160 | return null; | ||
161 | } | ||
162 | |||
163 | private static String getPublicHost() { | 174 | private static String getPublicHost() { |
164 | var publicHost = System.getenv("PUBLIC_HOST"); | 175 | var publicHost = System.getenv("PUBLIC_HOST"); |
165 | if (publicHost != null) { | 176 | if (publicHost != null) { |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/VirtualThreadExecutorServiceProvider.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/VirtualThreadExecutorServiceProvider.java new file mode 100644 index 00000000..ead98927 --- /dev/null +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/VirtualThreadExecutorServiceProvider.java | |||
@@ -0,0 +1,20 @@ | |||
1 | package tools.refinery.language.web.xtext; | ||
2 | |||
3 | import org.eclipse.xtext.ide.ExecutorServiceProvider; | ||
4 | |||
5 | import java.util.concurrent.ExecutorService; | ||
6 | import java.util.concurrent.Executors; | ||
7 | |||
8 | public class VirtualThreadExecutorServiceProvider extends ExecutorServiceProvider { | ||
9 | private static final String THREAD_POOL_NAME = "xtextWeb"; | ||
10 | |||
11 | @Override | ||
12 | protected ExecutorService createInstance(String key) { | ||
13 | var name = key == null ? THREAD_POOL_NAME : THREAD_POOL_NAME + "-" + key; | ||
14 | return Executors.newThreadPerTaskExecutor(Thread.ofVirtual() | ||
15 | .allowSetThreadLocals(true) | ||
16 | .inheritInheritableThreadLocals(false) | ||
17 | .name(name + "-", 0) | ||
18 | .factory()); | ||
19 | } | ||
20 | } | ||
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java index 82391d8b..1d9e0463 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java | |||
@@ -3,10 +3,10 @@ package tools.refinery.language.web.xtext.servlet; | |||
3 | import com.google.gson.Gson; | 3 | import com.google.gson.Gson; |
4 | import com.google.gson.JsonIOException; | 4 | import com.google.gson.JsonIOException; |
5 | import com.google.gson.JsonParseException; | 5 | import com.google.gson.JsonParseException; |
6 | import org.eclipse.jetty.websocket.api.Session; | 6 | import org.eclipse.jetty.ee10.websocket.api.Session; |
7 | import org.eclipse.jetty.websocket.api.StatusCode; | 7 | import org.eclipse.jetty.ee10.websocket.api.StatusCode; |
8 | import org.eclipse.jetty.websocket.api.WriteCallback; | 8 | import org.eclipse.jetty.ee10.websocket.api.WriteCallback; |
9 | import org.eclipse.jetty.websocket.api.annotations.*; | 9 | import org.eclipse.jetty.ee10.websocket.api.annotations.*; |
10 | import org.eclipse.xtext.resource.IResourceServiceProvider; | 10 | import org.eclipse.xtext.resource.IResourceServiceProvider; |
11 | import org.eclipse.xtext.web.server.ISession; | 11 | import org.eclipse.xtext.web.server.ISession; |
12 | import org.slf4j.Logger; | 12 | import org.slf4j.Logger; |
@@ -17,7 +17,6 @@ import tools.refinery.language.web.xtext.server.TransactionExecutor; | |||
17 | import tools.refinery.language.web.xtext.server.message.XtextWebRequest; | 17 | import tools.refinery.language.web.xtext.server.message.XtextWebRequest; |
18 | import tools.refinery.language.web.xtext.server.message.XtextWebResponse; | 18 | import tools.refinery.language.web.xtext.server.message.XtextWebResponse; |
19 | 19 | ||
20 | import java.io.IOException; | ||
21 | import java.io.Reader; | 20 | import java.io.Reader; |
22 | 21 | ||
23 | @WebSocket | 22 | @WebSocket |
@@ -108,12 +107,7 @@ public class XtextWebSocket implements WriteCallback, ResponseHandler { | |||
108 | throw new ResponseHandlerException("Trying to send message when websocket is disconnected"); | 107 | throw new ResponseHandlerException("Trying to send message when websocket is disconnected"); |
109 | } | 108 | } |
110 | var responseString = gson.toJson(response); | 109 | var responseString = gson.toJson(response); |
111 | try { | 110 | webSocketSession.getRemote().sendPartialString(responseString, true, this); |
112 | webSocketSession.getRemote().sendPartialString(responseString, true, this); | ||
113 | } catch (IOException e) { | ||
114 | throw new ResponseHandlerException( | ||
115 | "Cannot initiate async write to websocket " + webSocketSession.getRemoteAddress(), e); | ||
116 | } | ||
117 | } | 111 | } |
118 | 112 | ||
119 | @Override | 113 | @Override |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java index a2ad2943..9a32b937 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocketServlet.java | |||
@@ -2,7 +2,7 @@ package tools.refinery.language.web.xtext.servlet; | |||
2 | 2 | ||
3 | import jakarta.servlet.ServletConfig; | 3 | import jakarta.servlet.ServletConfig; |
4 | import jakarta.servlet.ServletException; | 4 | import jakarta.servlet.ServletException; |
5 | import org.eclipse.jetty.websocket.server.*; | 5 | import org.eclipse.jetty.ee10.websocket.server.*; |
6 | import org.eclipse.xtext.resource.IResourceServiceProvider; | 6 | import org.eclipse.xtext.resource.IResourceServiceProvider; |
7 | import org.slf4j.Logger; | 7 | import org.slf4j.Logger; |
8 | import org.slf4j.LoggerFactory; | 8 | import org.slf4j.LoggerFactory; |
diff --git a/subprojects/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java b/subprojects/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java index 652fc13b..6dfce780 100644 --- a/subprojects/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java +++ b/subprojects/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java | |||
@@ -1,17 +1,17 @@ | |||
1 | package tools.refinery.language.web; | 1 | package tools.refinery.language.web; |
2 | 2 | ||
3 | import org.eclipse.jetty.ee10.servlet.ServletContextHandler; | ||
4 | import org.eclipse.jetty.ee10.servlet.ServletHolder; | ||
5 | import org.eclipse.jetty.ee10.websocket.api.Session; | ||
6 | import org.eclipse.jetty.ee10.websocket.api.StatusCode; | ||
7 | import org.eclipse.jetty.ee10.websocket.api.annotations.WebSocket; | ||
8 | import org.eclipse.jetty.ee10.websocket.api.exceptions.UpgradeException; | ||
9 | import org.eclipse.jetty.ee10.websocket.client.ClientUpgradeRequest; | ||
10 | import org.eclipse.jetty.ee10.websocket.client.WebSocketClient; | ||
11 | import org.eclipse.jetty.ee10.websocket.server.config.JettyWebSocketServletContainerInitializer; | ||
3 | import org.eclipse.jetty.http.HttpHeader; | 12 | import org.eclipse.jetty.http.HttpHeader; |
4 | import org.eclipse.jetty.http.HttpStatus; | 13 | import org.eclipse.jetty.http.HttpStatus; |
5 | import org.eclipse.jetty.server.Server; | 14 | import org.eclipse.jetty.server.Server; |
6 | import org.eclipse.jetty.servlet.ServletContextHandler; | ||
7 | import org.eclipse.jetty.servlet.ServletHolder; | ||
8 | import org.eclipse.jetty.websocket.api.Session; | ||
9 | import org.eclipse.jetty.websocket.api.StatusCode; | ||
10 | import org.eclipse.jetty.websocket.api.annotations.WebSocket; | ||
11 | import org.eclipse.jetty.websocket.api.exceptions.UpgradeException; | ||
12 | import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; | ||
13 | import org.eclipse.jetty.websocket.client.WebSocketClient; | ||
14 | import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; | ||
15 | import org.eclipse.xtext.testing.GlobalRegistries; | 15 | import org.eclipse.xtext.testing.GlobalRegistries; |
16 | import org.eclipse.xtext.testing.GlobalRegistries.GlobalStateMemento; | 16 | import org.eclipse.xtext.testing.GlobalRegistries.GlobalStateMemento; |
17 | import org.junit.jupiter.api.AfterEach; | 17 | import org.junit.jupiter.api.AfterEach; |
diff --git a/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java b/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java index b70d0ed5..ebf36f13 100644 --- a/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java +++ b/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/AwaitTerminationExecutorServiceProvider.java | |||
@@ -1,16 +1,15 @@ | |||
1 | package tools.refinery.language.web.tests; | 1 | package tools.refinery.language.web.tests; |
2 | 2 | ||
3 | import com.google.inject.Singleton; | ||
4 | import org.eclipse.xtext.ide.ExecutorServiceProvider; | ||
5 | |||
3 | import java.util.ArrayList; | 6 | import java.util.ArrayList; |
4 | import java.util.List; | 7 | import java.util.List; |
5 | import java.util.concurrent.ExecutorService; | 8 | import java.util.concurrent.ExecutorService; |
6 | 9 | ||
7 | import org.eclipse.xtext.ide.ExecutorServiceProvider; | ||
8 | |||
9 | import com.google.inject.Singleton; | ||
10 | |||
11 | @Singleton | 10 | @Singleton |
12 | public class AwaitTerminationExecutorServiceProvider extends ExecutorServiceProvider { | 11 | public class AwaitTerminationExecutorServiceProvider extends ExecutorServiceProvider { |
13 | private List<RestartableCachedThreadPool> servicesToShutDown = new ArrayList<>(); | 12 | private final List<RestartableCachedThreadPool> servicesToShutDown = new ArrayList<>(); |
14 | 13 | ||
15 | @Override | 14 | @Override |
16 | protected ExecutorService createInstance(String key) { | 15 | protected ExecutorService createInstance(String key) { |
diff --git a/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java b/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java index 1468273d..8e5038ae 100644 --- a/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java +++ b/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/RestartableCachedThreadPool.java | |||
@@ -1,45 +1,44 @@ | |||
1 | package tools.refinery.language.web.tests; | 1 | package tools.refinery.language.web.tests; |
2 | 2 | ||
3 | import java.util.Collection; | ||
4 | import java.util.List; | ||
5 | import java.util.concurrent.Callable; | ||
6 | import java.util.concurrent.ExecutionException; | ||
7 | import java.util.concurrent.ExecutorService; | ||
8 | import java.util.concurrent.Executors; | ||
9 | import java.util.concurrent.Future; | ||
10 | import java.util.concurrent.TimeUnit; | ||
11 | import java.util.concurrent.TimeoutException; | ||
12 | |||
13 | import org.slf4j.Logger; | 3 | import org.slf4j.Logger; |
14 | import org.slf4j.LoggerFactory; | 4 | import org.slf4j.LoggerFactory; |
15 | 5 | ||
6 | import java.util.Collection; | ||
7 | import java.util.List; | ||
8 | import java.util.concurrent.*; | ||
9 | |||
10 | @SuppressWarnings("NullableProblems") | ||
16 | public class RestartableCachedThreadPool implements ExecutorService { | 11 | public class RestartableCachedThreadPool implements ExecutorService { |
17 | private static final Logger LOG = LoggerFactory.getLogger(RestartableCachedThreadPool.class); | 12 | private static final Logger LOG = LoggerFactory.getLogger(RestartableCachedThreadPool.class); |
18 | 13 | ||
19 | private ExecutorService delegate; | 14 | private ExecutorService delegate; |
20 | 15 | ||
21 | public RestartableCachedThreadPool() { | 16 | public RestartableCachedThreadPool() { |
22 | delegate = createExecutorService(); | 17 | delegate = createExecutorService(); |
23 | } | 18 | } |
24 | 19 | ||
25 | public void waitForAllTasksToFinish() { | 20 | public void waitForAllTasksToFinish() { |
26 | delegate.shutdown(); | 21 | delegate.shutdown(); |
27 | waitForTermination(); | 22 | waitForTermination(); |
28 | delegate = createExecutorService(); | 23 | delegate = createExecutorService(); |
29 | } | 24 | } |
30 | 25 | ||
31 | public void waitForTermination() { | 26 | public void waitForTermination() { |
27 | boolean result = false; | ||
32 | try { | 28 | try { |
33 | delegate.awaitTermination(1, TimeUnit.SECONDS); | 29 | result = delegate.awaitTermination(1, TimeUnit.SECONDS); |
34 | } catch (InterruptedException e) { | 30 | } catch (InterruptedException e) { |
35 | LOG.warn("Interrupted while waiting for delegate executor to stop", e); | 31 | LOG.warn("Interrupted while waiting for delegate executor to stop", e); |
36 | } | 32 | } |
33 | if (!result) { | ||
34 | throw new IllegalStateException("Failed to shut down Xtext thread pool"); | ||
35 | } | ||
37 | } | 36 | } |
38 | 37 | ||
39 | protected ExecutorService createExecutorService() { | 38 | protected ExecutorService createExecutorService() { |
40 | return Executors.newCachedThreadPool(); | 39 | return Executors.newCachedThreadPool(); |
41 | } | 40 | } |
42 | 41 | ||
43 | @Override | 42 | @Override |
44 | public boolean awaitTermination(long arg0, TimeUnit arg1) throws InterruptedException { | 43 | public boolean awaitTermination(long arg0, TimeUnit arg1) throws InterruptedException { |
45 | return delegate.awaitTermination(arg0, arg1); | 44 | return delegate.awaitTermination(arg0, arg1); |
diff --git a/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java b/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java index 74695c9a..f19c10ca 100644 --- a/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java +++ b/subprojects/language-web/src/test/java/tools/refinery/language/web/tests/WebSocketIntegrationTestClient.java | |||
@@ -1,10 +1,10 @@ | |||
1 | package tools.refinery.language.web.tests; | 1 | package tools.refinery.language.web.tests; |
2 | 2 | ||
3 | import org.eclipse.jetty.websocket.api.Session; | 3 | import org.eclipse.jetty.ee10.websocket.api.Session; |
4 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; | 4 | import org.eclipse.jetty.ee10.websocket.api.annotations.OnWebSocketClose; |
5 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; | 5 | import org.eclipse.jetty.ee10.websocket.api.annotations.OnWebSocketConnect; |
6 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; | 6 | import org.eclipse.jetty.ee10.websocket.api.annotations.OnWebSocketError; |
7 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; | 7 | import org.eclipse.jetty.ee10.websocket.api.annotations.OnWebSocketMessage; |
8 | 8 | ||
9 | import java.io.IOException; | 9 | import java.io.IOException; |
10 | import java.time.Duration; | 10 | import java.time.Duration; |