]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java
Multiple reader thread support for db client
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / BlockingAsyncProcedure.java
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/BlockingAsyncProcedure.java
new file mode 100644 (file)
index 0000000..4ae5303
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.impl;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.procedure.AsyncProcedure;
+
+public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result> {
+
+    private static final Object NO_RESULT = new Object();
+
+    private final Object key;
+    private final ReadGraphImpl graph;
+    private final AsyncProcedure<Result> procedure;
+
+    private Object result = NO_RESULT;
+    private Throwable exception = null;
+
+    public BlockingAsyncProcedure(ReadGraphImpl graph, AsyncProcedure<Result> procedure, Object key) {
+        this.procedure = procedure;
+        this.key = key;
+        this.graph = ReadGraphImpl.newAsync(graph);
+        this.graph.asyncBarrier.inc();
+    }
+
+    @Override
+    public void execute(AsyncReadGraph graph, Result result) {
+        this.result = result;
+        this.graph.asyncBarrier.dec();
+        try {
+            if(procedure != null) procedure.execute(graph, result);
+        } catch (Throwable throwable) {
+            Logger.defaultLogError("AsyncProcedure.execute threw for " + procedure, throwable);
+        }
+    }
+
+    @Override
+    public void exception(AsyncReadGraph graph, Throwable t) {
+        this.exception = t;
+        try {
+            if(procedure != null) procedure.exception(graph, t);
+        } catch (Throwable throwable) {
+            Logger.defaultLogError("AsyncProcedure.exception threw for " + procedure, throwable);
+        } finally {
+            this.graph.asyncBarrier.dec();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Result get() throws DatabaseException {
+
+        graph.asyncBarrier.waitBarrier(key, graph);
+
+        if(exception != null) {
+            if(exception instanceof DatabaseException) throw (DatabaseException)exception;
+            throw new DatabaseException(exception);
+        } else {
+            return (Result)result;
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public Result getResult() {
+        return (Result)result;
+    }
+
+    public Throwable getException() {
+        return exception;
+    }
+
+    @Override
+    public String toString() {
+        return "." + procedure; 
+    }
+
+}