diff options
Diffstat (limited to 'subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java')
-rw-r--r-- | subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java index 0135d8f5..a3792bac 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java | |||
@@ -42,6 +42,8 @@ public class TransactionExecutor implements IDisposable, PrecomputationListener | |||
42 | 42 | ||
43 | private final List<XtextWebPushMessage> pendingPushMessages = new ArrayList<>(); | 43 | private final List<XtextWebPushMessage> pendingPushMessages = new ArrayList<>(); |
44 | 44 | ||
45 | private volatile boolean disposed; | ||
46 | |||
45 | public TransactionExecutor(ISession session, IResourceServiceProvider.Registry resourceServiceProviderRegistry) { | 47 | public TransactionExecutor(ISession session, IResourceServiceProvider.Registry resourceServiceProviderRegistry) { |
46 | this.session = session; | 48 | this.session = session; |
47 | this.resourceServiceProviderRegistry = resourceServiceProviderRegistry; | 49 | this.resourceServiceProviderRegistry = resourceServiceProviderRegistry; |
@@ -52,10 +54,13 @@ public class TransactionExecutor implements IDisposable, PrecomputationListener | |||
52 | } | 54 | } |
53 | 55 | ||
54 | public void handleRequest(XtextWebRequest request) throws ResponseHandlerException { | 56 | public void handleRequest(XtextWebRequest request) throws ResponseHandlerException { |
57 | if (disposed) { | ||
58 | return; | ||
59 | } | ||
55 | var serviceContext = new SimpleServiceContext(session, request.getRequestData()); | 60 | var serviceContext = new SimpleServiceContext(session, request.getRequestData()); |
56 | var ping = serviceContext.getParameter("ping"); | 61 | var ping = serviceContext.getParameter("ping"); |
57 | if (ping != null) { | 62 | if (ping != null) { |
58 | responseHandler.onResponse(new XtextWebOkResponse(request, new PongResult(ping))); | 63 | onResponse(new XtextWebOkResponse(request, new PongResult(ping))); |
59 | return; | 64 | return; |
60 | } | 65 | } |
61 | synchronized (callPendingLock) { | 66 | synchronized (callPendingLock) { |
@@ -72,23 +77,36 @@ public class TransactionExecutor implements IDisposable, PrecomputationListener | |||
72 | var serviceDispatcher = injector.getInstance(XtextServiceDispatcher.class); | 77 | var serviceDispatcher = injector.getInstance(XtextServiceDispatcher.class); |
73 | var service = serviceDispatcher.getService(new SubscribingServiceContext(serviceContext, this)); | 78 | var service = serviceDispatcher.getService(new SubscribingServiceContext(serviceContext, this)); |
74 | var serviceResult = service.getService().apply(); | 79 | var serviceResult = service.getService().apply(); |
75 | responseHandler.onResponse(new XtextWebOkResponse(request, serviceResult)); | 80 | onResponse(new XtextWebOkResponse(request, serviceResult)); |
76 | } catch (InvalidRequestException e) { | 81 | } catch (InvalidRequestException e) { |
77 | responseHandler.onResponse(new XtextWebErrorResponse(request, XtextWebErrorKind.REQUEST_ERROR, e)); | 82 | onResponse(new XtextWebErrorResponse(request, XtextWebErrorKind.REQUEST_ERROR, e)); |
78 | } catch (RuntimeException e) { | 83 | } catch (RuntimeException e) { |
79 | responseHandler.onResponse(new XtextWebErrorResponse(request, XtextWebErrorKind.SERVER_ERROR, e)); | 84 | onResponse(new XtextWebErrorResponse(request, XtextWebErrorKind.SERVER_ERROR, e)); |
80 | } finally { | 85 | } finally { |
81 | synchronized (callPendingLock) { | 86 | flushPendingPushMessages(); |
82 | for (var message : pendingPushMessages) { | 87 | } |
83 | try { | 88 | } |
84 | responseHandler.onResponse(message); | 89 | |
85 | } catch (ResponseHandlerException | RuntimeException e) { | 90 | private void onResponse(XtextWebResponse response) throws ResponseHandlerException { |
86 | LOG.error("Error while flushing push message", e); | 91 | if (!disposed) { |
87 | } | 92 | responseHandler.onResponse(response); |
93 | } | ||
94 | } | ||
95 | |||
96 | private void flushPendingPushMessages() { | ||
97 | synchronized (callPendingLock) { | ||
98 | for (var message : pendingPushMessages) { | ||
99 | if (disposed) { | ||
100 | return; | ||
101 | } | ||
102 | try { | ||
103 | responseHandler.onResponse(message); | ||
104 | } catch (ResponseHandlerException | RuntimeException e) { | ||
105 | LOG.error("Error while flushing push message", e); | ||
88 | } | 106 | } |
89 | pendingPushMessages.clear(); | ||
90 | callPending = false; | ||
91 | } | 107 | } |
108 | pendingPushMessages.clear(); | ||
109 | callPending = false; | ||
92 | } | 110 | } |
93 | } | 111 | } |
94 | 112 | ||
@@ -134,7 +152,7 @@ public class TransactionExecutor implements IDisposable, PrecomputationListener | |||
134 | * @throws UnknownLanguageException if the Xtext language cannot be determined | 152 | * @throws UnknownLanguageException if the Xtext language cannot be determined |
135 | */ | 153 | */ |
136 | protected Injector getInjector(IServiceContext context) { | 154 | protected Injector getInjector(IServiceContext context) { |
137 | IResourceServiceProvider resourceServiceProvider = null; | 155 | IResourceServiceProvider resourceServiceProvider; |
138 | var resourceName = context.getParameter("resource"); | 156 | var resourceName = context.getParameter("resource"); |
139 | if (resourceName == null) { | 157 | if (resourceName == null) { |
140 | resourceName = ""; | 158 | resourceName = ""; |
@@ -164,10 +182,12 @@ public class TransactionExecutor implements IDisposable, PrecomputationListener | |||
164 | 182 | ||
165 | @Override | 183 | @Override |
166 | public void dispose() { | 184 | public void dispose() { |
185 | disposed = true; | ||
167 | for (var subscription : subscriptions.values()) { | 186 | for (var subscription : subscriptions.values()) { |
168 | var document = subscription.get(); | 187 | var document = subscription.get(); |
169 | if (document != null) { | 188 | if (document != null) { |
170 | document.removePrecomputationListener(this); | 189 | document.removePrecomputationListener(this); |
190 | document.dispose(); | ||
171 | } | 191 | } |
172 | } | 192 | } |
173 | } | 193 | } |