X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2FBlockingAsyncProcedure.java;h=8f96bb9e6d3a51a48c7b98baa40f962fc83f5617;hb=4a2d5e0ab04119c571da0ec2d2289c71c55dc3f9;hp=4ae530317908ce32118b867edaa6c85b52932d0d;hpb=9f0fd59be54719b1fe9322d8fd37e4950857308c;p=simantics%2Fplatform.git 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 index 4ae530317..8f96bb9e6 100644 --- 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 @@ -12,56 +12,82 @@ 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.BarrierTracing; import org.simantics.db.impl.graph.ReadGraphImpl; +import org.simantics.db.impl.query.AsyncReadEntry; +import org.simantics.db.impl.query.PendingTaskSupport; import org.simantics.db.procedure.AsyncProcedure; - +import org.simantics.db.request.AsyncRead; public class BlockingAsyncProcedure implements AsyncProcedure { private static final Object NO_RESULT = new Object(); private final Object key; - private final ReadGraphImpl graph; + private final ReadGraphImpl queryGraph; + private final ReadGraphImpl callerGraph; private final AsyncProcedure procedure; - + private PendingTaskSupport pendingTaskSupport; + private final boolean needsToBlock; private Object result = NO_RESULT; private Throwable exception = null; - public BlockingAsyncProcedure(ReadGraphImpl graph, AsyncProcedure procedure, Object key) { + private ReadGraphImpl queryGraph() { + return queryGraph; + } + + public BlockingAsyncProcedure(ReadGraphImpl callerGraph, AsyncReadEntry entry, AsyncProcedure procedure, Object key, boolean needsToBlock) { + + // A new graph for evaluating the query with correct parent and asyncBarrier + queryGraph = callerGraph.withParent(entry, () -> { + + dispatchProcedure(queryGraph(), callerGraph, entry, procedure, needsToBlock); + + }, needsToBlock); + + queryGraph.asyncBarrier.inc(); + this.procedure = procedure; this.key = key; - this.graph = ReadGraphImpl.newAsync(graph); - this.graph.asyncBarrier.inc(); + this.queryGraph.asyncBarrier.inc(); + this.callerGraph = callerGraph; + this.needsToBlock = needsToBlock; + if (BarrierTracing.BOOKKEEPING) { + BarrierTracing.registerBAP(this); + } } @Override - public void execute(AsyncReadGraph graph, Result result) { + 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); - } + queryGraph.asyncBarrier.dec(); + } @Override - public void exception(AsyncReadGraph graph, Throwable t) { + 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(); - } + queryGraph.asyncBarrier.dec(); + + } + + public void waitBarrier() { + queryGraph.asyncBarrier.waitBarrier(key, queryGraph); + } + + public void dec() { + + queryGraph.asyncBarrier.dec(); + } @SuppressWarnings("unchecked") public Result get() throws DatabaseException { - graph.asyncBarrier.waitBarrier(key, graph); + if(needsToBlock) + queryGraph.asyncBarrier.waitBarrier(key, queryGraph); if(exception != null) { if(exception instanceof DatabaseException) throw (DatabaseException)exception; @@ -85,5 +111,69 @@ public class BlockingAsyncProcedure implements AsyncProcedure { public String toString() { return "." + procedure; } + + private void dispatchProcedure(ReadGraphImpl queryGraph, ReadGraphImpl parentGraph, AsyncReadEntry entry, AsyncProcedure procedure_, boolean needsToBlock) { + + AsyncProcedure procedure = entry != null ? entry : procedure_; + + ReadGraphImpl executeGraph = parentGraph.withParent(parentGraph.parent, null, needsToBlock); + executeGraph.asyncBarrier.inc(); + try { + if(procedure != null) { + procedure.execute(executeGraph, get()); + } + } catch (DatabaseException e) { + if(procedure != null) procedure.exception(executeGraph, e); + exception = e; + } catch (Throwable t) { + DatabaseException dbe = new DatabaseException(t); + if(procedure != null) procedure.exception(executeGraph, dbe); + exception = dbe; + } finally { + + if (entry != null) { + assert(entry.isReady()); + // This does not throw + entry.performFromCache(executeGraph, procedure_); + } + + executeGraph.asyncBarrier.dec(); + if(needsToBlock) + executeGraph.asyncBarrier.waitBarrier(procedure, executeGraph); + } + + if (BarrierTracing.BOOKKEEPING) { + BarrierTracing.unregisterBAP(this); + } + + } + + public void print() { + System.err.println("BlockingAsyncProcedure"); + System.err.println("-key: " + key); + System.err.println("-queryGraph: " + queryGraph); + System.err.println("-callerGraph: " + callerGraph); + System.err.println("-procedure: " + procedure); + System.err.println("-pendingTaskSupport: " + pendingTaskSupport); + System.err.println("-result: " + result); + System.err.println("-exception: " + exception); + } + + public Result performSync(AsyncRead request) throws DatabaseException { + try { + request.perform(queryGraph, this); + } finally { + dec(); + } + return get(); + } + + public void performAsync(AsyncRead request) throws DatabaseException { + try { + request.perform(queryGraph, this); + } finally { + dec(); + } + } }