1 /*******************************************************************************
2 * Copyright (c) 2018 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.impl;
14 import org.simantics.db.AsyncReadGraph;
15 import org.simantics.db.exception.DatabaseException;
16 import org.simantics.db.impl.graph.BarrierTracing;
17 import org.simantics.db.impl.graph.ReadGraphImpl;
18 import org.simantics.db.impl.query.AsyncReadEntry;
19 import org.simantics.db.impl.query.PendingTaskSupport;
20 import org.simantics.db.procedure.AsyncProcedure;
21 import org.simantics.db.request.AsyncRead;
23 public class BlockingAsyncProcedure<Result> implements AsyncProcedure<Result>, Runnable {
25 private static final Object NO_RESULT = new Object();
27 private final Object key;
28 private final ReadGraphImpl queryGraph;
29 private final ReadGraphImpl callerGraph;
30 private final AsyncReadEntry<Result> entry;
31 private final AsyncProcedure<Result> procedure;
32 private PendingTaskSupport pendingTaskSupport;
33 private final boolean needsToBlock;
34 private Object result = NO_RESULT;
35 private Throwable exception = null;
37 public BlockingAsyncProcedure(ReadGraphImpl callerGraph, AsyncReadEntry<Result> entry, AsyncProcedure<Result> procedure, Object key, boolean needsToBlock) {
39 // A new graph for evaluating the query with correct parent and asyncBarrier
40 queryGraph = callerGraph.withParent(entry, this, needsToBlock);
41 queryGraph.asyncBarrier.inc();
43 // This makes sure that caller does not quit before dispatch
44 callerGraph.asyncBarrier.inc();
47 this.procedure = procedure;
49 this.queryGraph.asyncBarrier.inc();
50 this.callerGraph = callerGraph;
51 this.needsToBlock = needsToBlock;
52 if (BarrierTracing.BOOKKEEPING) {
53 BarrierTracing.registerBAP(this);
58 public void execute(AsyncReadGraph graph_, Result result) {
61 queryGraph.asyncBarrier.dec();
66 public void exception(AsyncReadGraph graph_, Throwable t) {
69 queryGraph.asyncBarrier.dec();
73 public void waitBarrier() {
74 queryGraph.asyncBarrier.waitBarrier(key, queryGraph);
79 queryGraph.asyncBarrier.dec();
83 @SuppressWarnings("unchecked")
84 public Result get() throws DatabaseException {
87 queryGraph.asyncBarrier.waitBarrier(key, queryGraph);
89 if(exception != null) {
90 if(exception instanceof DatabaseException) throw (DatabaseException)exception;
91 throw new DatabaseException(exception);
93 return (Result)result;
98 @SuppressWarnings("unchecked")
99 public Result getResult() {
100 return (Result)result;
103 public Throwable getException() {
108 public String toString() {
109 return "." + procedure;
115 AsyncProcedure<Result> procedure__ = entry != null ? entry : procedure;
117 ReadGraphImpl executeGraph = callerGraph.withParent(callerGraph.parent, null, needsToBlock);
118 executeGraph.asyncBarrier.inc();
120 // This counters the inc in the constructor
121 callerGraph.asyncBarrier.dec();
124 if(procedure__ != null) {
125 procedure__.execute(executeGraph, get());
127 } catch (DatabaseException e) {
128 if(procedure__ != null) procedure__.exception(executeGraph, e);
130 } catch (Throwable t) {
131 DatabaseException dbe = new DatabaseException(t);
132 if(procedure__ != null) procedure__.exception(executeGraph, dbe);
137 assert(entry.isReady());
138 // This does not throw
139 entry.performFromCache(executeGraph, procedure);
142 executeGraph.asyncBarrier.dec();
144 executeGraph.asyncBarrier.waitBarrier(procedure__, executeGraph);
147 if (BarrierTracing.BOOKKEEPING) {
148 BarrierTracing.unregisterBAP(this);
153 public void print() {
154 System.err.println("BlockingAsyncProcedure");
155 System.err.println("-key: " + key);
156 System.err.println("-queryGraph: " + queryGraph);
157 System.err.println("-callerGraph: " + callerGraph);
158 System.err.println("-procedure: " + procedure);
159 System.err.println("-pendingTaskSupport: " + pendingTaskSupport);
160 System.err.println("-result: " + result);
161 System.err.println("-exception: " + exception);
164 public Result performSync(AsyncRead<Result> request) throws DatabaseException {
166 request.perform(queryGraph, this);
173 public void performAsync(AsyncRead<Result> request) throws DatabaseException {
175 request.perform(queryGraph, this);