]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java
Multiple reader thread support for db client
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / procedure / ResultCallWrappedSyncQueryProcedure.java
diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/procedure/ResultCallWrappedSyncQueryProcedure.java
new file mode 100644 (file)
index 0000000..d2034fb
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * 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.procedure;
+
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.procedure.SyncMultiProcedure;
+
+public class ResultCallWrappedSyncQueryProcedure<Result> implements SyncMultiProcedure<Result> {
+
+    private final ArrayList<Result> result;
+    private Throwable exception = null;
+    private final SyncMultiProcedure<Result> procedure;
+    private final AtomicBoolean latch;
+
+    public ResultCallWrappedSyncQueryProcedure(SyncMultiProcedure<Result> procedure) {
+        this.procedure = procedure;
+        latch = new AtomicBoolean(false);
+        result = new ArrayList<Result>();
+    }
+
+    @Override
+    public void execute(ReadGraph graph, Result result) {
+        try {
+            synchronized(this.result) {
+                this.result.add(result);
+            }
+            procedure.execute(graph, result);
+        } catch (Throwable t) {
+            Logger.defaultLogError("AsyncMultiProcedure.execute failed for " + procedure, t);
+        }
+    }
+
+    @Override
+    public void finished(ReadGraph graph) {
+        if(latch.compareAndSet(false, true)) {
+            try {
+                procedure.finished(graph);
+            } catch (Throwable t) {
+                Logger.defaultLogError("AsyncMultiProcedure.exception failed for " + procedure, t);
+            } finally {
+            }
+        } else {
+            Logger.defaultLogError("Finished or exception was called many times (this time is finished)");
+        }
+    }
+
+    @Override
+    public void exception(ReadGraph graph, Throwable t) {
+        if(latch.compareAndSet(false, true)) {
+            try {
+                this.exception = t;
+                procedure.exception(graph, t);
+            } catch (Throwable throwable) {
+                Logger.defaultLogError("AsyncMultiProcedure.exception failed for " + procedure, throwable);
+            } finally {
+            }
+        } else {
+            Logger.defaultLogError("Finished or exception was called many times (this time is exception)");
+        }
+    }
+
+    public ArrayList<Result> get() {
+        return result;
+    }
+
+    public Throwable getException() {
+        return exception;
+    }
+
+    @Override
+    public String toString() {
+        return "ResultCallWrappedQueryProcedure4[" + procedure + "]"; 
+    }
+
+}