aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java
diff options
context:
space:
mode:
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.java48
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 }