From: Tuukka Lehtonen Date: Tue, 17 Mar 2020 10:54:14 +0000 (+0000) Subject: Merge "Fixed ProfileObserver.update race with multiple query threads" X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=15af8a20abe8b2ba24b52c9da8bce6c92351dc43;hp=e83110633e844749640f830e186423643e1b7cbe Merge "Fixed ProfileObserver.update race with multiple query threads" --- diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java index e9523c0c8..dfb5780f9 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java @@ -33,7 +33,6 @@ import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter; import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.CancelTransactionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncListener; @@ -63,9 +62,13 @@ import org.simantics.db.request.WriteOnlyResult; import org.simantics.db.request.WriteResult; import org.simantics.utils.DataContainer; import org.simantics.utils.datastructures.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MergingGraphRequestProcessor implements AsyncRequestProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(MergingGraphRequestProcessor.class); + private static class SyncWriteRequestAdapter implements Write { private Semaphore semaphore = new Semaphore(0); @@ -128,7 +131,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { try { semaphore.acquire(); } catch (InterruptedException e) { - Logger.defaultLogError(e); + LOGGER.error("SyncWriteRequestAdapter interrupted", e); } } @@ -223,7 +226,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { try { MergingGraphRequestProcessor.this.wait(transactionKeepalivePeriod); } catch (InterruptedException e) { - Logger.defaultLogError(e); + LOGGER.error("MergedRead interrupted", e); } if (requestQueue.isEmpty()) break; @@ -262,7 +265,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("MergedRead failed", t); // if(currentRequest.second instanceof AsyncProcedure) { // ((AsyncProcedure)currentRequest.second).exception(graph, t); @@ -281,7 +284,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { } else { - try{ + try { if(currentRequest.second instanceof AsyncProcedure) { if(currentRequest.first instanceof AsyncRead) { @@ -298,7 +301,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("MergedRead failed", t); // if(currentRequest.second instanceof AsyncProcedure) { // ((AsyncProcedure)currentRequest.second).exception(graph, t); @@ -355,7 +358,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { try { MergingGraphRequestProcessor.this.wait(transactionKeepalivePeriod); } catch (InterruptedException e) { - Logger.defaultLogError(e); + LOGGER.error("RunnerWriteGraphRequest interrupted", e); } if (requestQueue.isEmpty()) break; @@ -385,7 +388,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { graph.syncRequest(adapter); if(callback != null) callback.accept(null); } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("RunnerWriteGraphRequest failed", t); if(callback != null) callback.accept(t); } @@ -399,7 +402,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { else if(currentRequest.first instanceof DelayedWrite) graph.syncRequest((DelayedWrite)currentRequest.first); if(callback != null) callback.accept(null); } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("RunnerWriteGraphRequest failed", t); if(callback != null) callback.accept(t); } @@ -572,7 +575,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncMultiRead, AsyncMultiProcedure) failed", t); throw new RuntimeException(t.getMessage()); } @@ -625,7 +628,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncRead, AsyncProcedure) failed", t); throw new RuntimeException(t.getMessage()); } @@ -691,7 +694,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { @Override public void exception(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("asyncRequest(AsyncRead) failed", t); } }); @@ -736,7 +739,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncRead) failed", t); throw new RuntimeException(t.getMessage()); } @@ -775,7 +778,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncMultiRead) failed", t); throw new RuntimeException(t.getMessage()); } @@ -878,7 +881,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { @Override public void exception(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("asyncRequest(Read) failed", t); } }); @@ -1305,4 +1308,9 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { throw new UnsupportedOperationException(); } + @Override + public T l0() { + return processor.l0(); + } + } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java index 1f00ff008..f47ebb3f3 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java @@ -46,6 +46,11 @@ import org.simantics.db.request.WriteResult; public class ProcessorBase implements AsyncRequestProcessor { + @Override + public T l0() { + throw new UnsupportedOperationException(); + } + @Override public void asyncRequest(AsyncMultiRead request, AsyncMultiProcedure procedure) { throw new UnsupportedOperationException(); diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java index b3eba37fb..aeea33f02 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java @@ -14,7 +14,7 @@ import org.simantics.scl.runtime.function.FunctionImpl3; * @author Hannu Niemistö */ public class AdaptValue extends ResourceRead { - + public AdaptValue(Resource resource) { super(resource); } @@ -31,14 +31,14 @@ public class AdaptValue extends ResourceRead { } }; - + @Override public Object perform(ReadGraph graph) throws DatabaseException { - String uri = graph.getURI(resource); - if(Layer0.URIs.Functions_functionApplication.equals(uri)) return functionApplication; + Layer0 L0 = graph.l0(); + if (L0.Functions_functionApplication.equalsResource(resource)) + return functionApplication; ComputationalValue ev = graph.adapt(resource, ComputationalValue.class); return ev.getValue(graph, resource); - } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java index 110e1d59b..61580bfdc 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java @@ -6387,4 +6387,10 @@ public class ReadGraphImpl implements AsyncReadGraph { else return getTopLevelGraphStatic(impl.parentGraph); } + @SuppressWarnings("unchecked") + @Override + public T l0() { + return (T) processor.getL0(); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java index 6345b7375..6d9560940 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java @@ -4054,6 +4054,10 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap return L0; } + public Layer0 getL0() { + return L0; + } + public static ThreadLocal thread = new ThreadLocal() { protected Integer initialValue() { return -1; diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java index 517ce761e..6ad6315b9 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java @@ -27,41 +27,43 @@ import org.simantics.scl.runtime.function.FunctionImpl3; */ public abstract class ContextualRelatedValue implements ConverterComputationalValue { - @SuppressWarnings("unchecked") - @Override - public T getValue(ReadGraph graph, Resource resource) throws DatabaseException { - return (T) new FunctionImpl3() { - @Override - public Object apply(ReadGraph graph, Resource converter, Object context) { - SCLContext sclContext = SCLContext.getCurrent(); - Object oldGraph = sclContext.get("graph"); - try { - if (context instanceof Variable) { - Variable variable = (Variable)context; - try { - Function1 fn = getFunction(graph, variable.getParent(graph).getRepresents(graph), variable.getRepresents(graph), variable.getPredicateResource(graph)); - sclContext.put("graph", graph); - return fn.apply(variable); - } catch (DatabaseException e) { - throw new RuntimeDatabaseException(e); - } - } if (context instanceof Resource) { - Resource resource = (Resource)context; - try { - // Here converter is the object and context is the subject - Function1 fn = getFunction(graph, resource, converter, null); - return fn.apply(resource); - } catch (DatabaseException e) { - throw new RuntimeDatabaseException(e); - } - } else { - throw new IllegalStateException("Unknown context " + context); + private final FunctionImpl3 function = new FunctionImpl3() { + @Override + public Object apply(ReadGraph graph, Resource converter, Object context) { + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.get("graph"); + try { + if (context instanceof Variable) { + Variable variable = (Variable)context; + try { + Function1 fn = getFunction(graph, variable.getParent(graph).getRepresents(graph), variable.getRepresents(graph), variable.getPredicateResource(graph)); + sclContext.put("graph", graph); + return fn.apply(variable); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); + } + } if (context instanceof Resource) { + Resource resource = (Resource)context; + try { + // Here converter is the object and context is the subject + Function1 fn = getFunction(graph, resource, converter, null); + return fn.apply(resource); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); } - } finally { - sclContext.put("graph", oldGraph); + } else { + throw new IllegalStateException("Unknown context " + context); } + } finally { + sclContext.put("graph", oldGraph); } - }; + } + }; + + @SuppressWarnings("unchecked") + @Override + public T getValue(ReadGraph graph, Resource resource) throws DatabaseException { + return (T) function; } } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java index 4e775e08a..f52148c2a 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java @@ -139,7 +139,7 @@ public class All { return graph.getValue2(object, variable); } else { for (Pair assertion : assertions.values()) { - if (assertion.first.predicate.equals(variable.property.predicate)) { + if (assertion.first.predicate.equals(variable.getPossiblePredicateResource(graph))) { return graph.getValue2(assertion.second, variable); } } @@ -201,7 +201,7 @@ public class All { return graph.getValue2(object, variable, binding); } else { for (Pair assertion : assertions.values()) { - if (assertion.first.predicate.equals(variable.property.predicate)) { + if (assertion.first.predicate.equals(variable.getPossiblePredicateResource(graph))) { return graph.getValue2(assertion.second, variable, binding); } } @@ -1164,8 +1164,11 @@ public class All { if(property instanceof StandardGraphPropertyVariable) { StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)property; if (variable.parentResource != null) { - Statement stm = graph.getPossibleStatement(variable.parentResource, variable.property.predicate); - return stm != null && stm.isAsserted(variable.parentResource); + Resource predicate = variable.getPossiblePredicateResource(graph); + if (predicate != null) { + Statement stm = graph.getPossibleStatement(variable.parentResource, predicate); + return stm != null && stm.isAsserted(variable.parentResource); + } } } return Boolean.FALSE; @@ -1313,7 +1316,7 @@ public class All { throw new InvalidVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ")."); try { - return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable); + return graph.getRelatedValue2(variable.parentResource, variable.getPredicateResource(graph), variable); } catch (NoSingleResultException e) { throw new MissingVariableValueException(variable.getPossibleURI(graph), e); } catch (DoesNotContainValueException e) { @@ -1334,9 +1337,10 @@ public class All { if (variable.parentResource == null) throw new MissingVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").", context.getPossibleRepresents(graph)); + try { - return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable); + return graph.getRelatedValue2(variable.parentResource, variable.getPredicateResource(graph), variable); } catch (NoSingleResultException e) { throw new MissingVariableValueException(variable.getPossibleURI(graph), e); } catch (DoesNotContainValueException e) { diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java new file mode 100644 index 000000000..a1b74638f --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java @@ -0,0 +1,34 @@ +package org.simantics.db.layer0.variable; + +import org.simantics.db.Resource; +import org.simantics.db.exception.AssumptionException; + +public class NoPredicateResourceException extends AssumptionException { + + private static final long serialVersionUID = -374051341908276908L; + + public NoPredicateResourceException(Throwable cause) { + super(cause); + } + + public NoPredicateResourceException(String message, Throwable cause, Resource... rs) { + super(message, cause, rs); + } + + public NoPredicateResourceException(String message, Resource... resources) { + super(message, resources); + } + + public NoPredicateResourceException(String message, Throwable cause) { + super(message, cause); + } + + public NoPredicateResourceException(String message, int... args) { + super(message, args); + } + + public NoPredicateResourceException(String message) { + super(message); + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java index b7eaf075e..c9214e398 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java @@ -21,6 +21,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.DatatypeNotFoundException; import org.simantics.db.exception.ValidationException; import org.simantics.db.layer0.exception.InvalidVariableException; +import org.simantics.db.layer0.exception.MissingVariableException; import org.simantics.db.layer0.exception.MissingVariableValueException; import org.simantics.db.layer0.exception.PendingVariableException; import org.simantics.db.layer0.function.All; @@ -100,11 +101,15 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { @Override public String getPossibleLabel(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + return null; return graph.getPossibleRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING); } @Override public String getLabel(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + throw new NoPredicateResourceException("No predicate resource for property " + getName(graph)); return graph.getRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING); } @@ -124,10 +129,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -145,10 +152,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -183,10 +192,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -200,10 +211,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -324,11 +337,15 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { @Override public Variable getPredicate(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + throw new MissingVariableException("No predicate for property " + getName(graph)); return Variables.getVariable(graph, graph.getURI(property.predicate)); } @Override public Resource getPredicateResource(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + throw new NoPredicateResourceException("No predicate for property " + getName(graph)); return property.predicate; } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java index 92c5e9dda..0178e805f 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java @@ -18,7 +18,6 @@ import org.simantics.db.SessionManager; import org.simantics.db.SessionReference; import org.simantics.db.VirtualGraph; import org.simantics.db.authentication.UserAuthenticationAgent; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InvalidAuthenticationException; import org.simantics.db.exception.InvalidUserException; @@ -30,9 +29,13 @@ import org.simantics.db.impl.graph.WriteSupport; import org.simantics.db.impl.query.QueryProcessor; import org.simantics.db.impl.query.QuerySupport; import org.simantics.db.service.ServerInformation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; final public class SessionImplDb extends SessionImplSocket { + private static final Logger LOGGER = LoggerFactory.getLogger(SessionImplDb.class); + /** * Cached ServerInformation structure fetched from the server at connection * time. It should never change during a single session and therefore it @@ -58,7 +61,7 @@ final public class SessionImplDb extends SessionImplSocket { try { newId = cluster.createResource(clusterTranslator); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("createResource failed", e); return null; } return new ResourceImpl(resourceSupport, newId); @@ -114,8 +117,7 @@ final public class SessionImplDb extends SessionImplSocket { // clusterTable.dispose(); clusterTable = null; // throw e; } catch (Throwable e) { - e.printStackTrace(); - Logger.defaultLogError("Unhandled error. See exception for details.", e); + LOGGER.error("Unhandled error. See exception for details.", e); graphSession = null; clusterTable.dispose(); clusterTable = null; throw new Exception(e); diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java index f8fd7d17d..29c70445b 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java @@ -328,7 +328,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule try { getClusterTable().refresh(csid, this, clusterUID); } catch (Throwable t) { - Logger.defaultLogError("Refesh failed.", t); + LOGGER.error("refresh({}, {}) failed", thread, csid, t); } } @@ -468,7 +468,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule assert (null != writer); } catch (Throwable t) { if (!(t instanceof CancelTransactionException)) - Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", t); + LOGGER.error("Write transaction caused an unexpected error, see exception.", t); writeState.except(t); } finally { writer.asyncBarrier.dec(); @@ -482,7 +482,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule // Log it first, just to be safe that the error is always logged. if (!(e instanceof CancelTransactionException)) - Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", e); + LOGGER.error("Write transaction caused an unexpected error, see exception.", e); // writeState.getGraph().state.barrier.dec(); // writeState.getGraph().waitAsync(request); @@ -626,7 +626,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if (t instanceof DatabaseException) callback.accept((DatabaseException) t); else callback.accept(new DatabaseException(t)); } else - Logger.defaultLogError("Unhandled exception", t); + LOGGER.error("Unhandled exception", t); } }; @@ -1324,7 +1324,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule callback.exception(new DatabaseException(e)); state.stopWriteTransaction(clusterStream); - Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", e); + LOGGER.error("Write transaction caused an unexpected error, see exception.", e); } finally { @@ -1530,7 +1530,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if(throwable != null) { throwable.set(th); } else { - Logger.defaultLogError("Unhandled exception", th); + LOGGER.error("Unhandled exception", th); } } @@ -1543,7 +1543,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if(throwable != null) { throwable.set(t); } else { - Logger.defaultLogError("Unhandled exception", t); + LOGGER.error("Unhandled exception", t); } try { @@ -1555,7 +1555,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if(throwable != null) { throwable.set(t2); } else { - Logger.defaultLogError("Unhandled exception", t2); + LOGGER.error("Unhandled exception", t2); } } @@ -2511,39 +2511,41 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule */ @SuppressWarnings("unchecked") @Override - public synchronized T peekService(Class api) { - - if(serviceKey1 == api) { - return (T)service1; - } else if (serviceKey2 == api) { - // Promote this key - Object result = service2; - service2 = service1; - serviceKey2 = serviceKey1; - service1 = result; - serviceKey1 = api; - return (T)result; - } + public T peekService(Class api) { + if (Layer0.class == api) + return (T) L0; - if (Layer0.class == api) - return (T) L0; - if (ServerInformation.class == api) - return (T) getCachedServerInformation(); - else if (WriteGraphImpl.class == api) - return (T) writeState.getGraph(); - else if (ClusterBuilder.class == api) - return (T)new ClusterBuilderImpl(this, (WriteOnlySupport)writeState.getGraph().writeSupport); - else if (ClusterBuilderFactory.class == api) - return (T)new ClusterBuilderFactoryImpl(this); + synchronized (this) { + if (serviceKey1 == api) { + return (T) service1; + } + if (serviceKey2 == api) { + // Promote this key + Object result = service2; + service2 = service1; + serviceKey2 = serviceKey1; + service1 = result; + serviceKey1 = api; + return (T)result; + } - service2 = service1; - serviceKey2 = serviceKey1; + if (ServerInformation.class == api) + return (T) getCachedServerInformation(); + else if (WriteGraphImpl.class == api) + return (T) writeState.getGraph(); + else if (ClusterBuilder.class == api) + return (T)new ClusterBuilderImpl(this, (WriteOnlySupport)writeState.getGraph().writeSupport); + else if (ClusterBuilderFactory.class == api) + return (T)new ClusterBuilderFactoryImpl(this); - service1 = serviceLocator.peekService(api); - serviceKey1 = api; + service2 = service1; + serviceKey2 = serviceKey1; - return (T)service1; + service1 = serviceLocator.peekService(api); + serviceKey1 = api; + return (T)service1; + } } /* @@ -2590,9 +2592,9 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule try { h.valuesChanged(ctx); } catch (Exception e) { - Logger.defaultLogError("monitor handler notification produced the following exception", e); + LOGGER.error("monitor handler notification produced the following exception", e); } catch (LinkageError e) { - Logger.defaultLogError("monitor handler notification produced a linkage error", e); + LOGGER.error("monitor handler notification produced a linkage error", e); } } } @@ -3579,4 +3581,10 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule state.setCombine(false); } + @SuppressWarnings("unchecked") + @Override + public T l0() { + return (T) L0; + } + } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java index 50184528e..d90f2c3a5 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java @@ -16,7 +16,6 @@ import java.io.IOException; import org.simantics.db.ServerI; import org.simantics.db.VirtualGraph; import org.simantics.db.authentication.UserAuthenticationAgent; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InvalidAuthenticationException; import org.simantics.db.exception.InvalidUserException; @@ -24,6 +23,8 @@ import org.simantics.db.impl.ResourceImpl; import org.simantics.db.impl.VirtualGraphImpl; import org.simantics.db.impl.query.QueryProcessor; import org.simantics.db.service.ServerInformation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import fi.vtt.simantics.procore.BackdoorAuthenticator; import fi.vtt.simantics.procore.ProCoreServerReference; @@ -31,6 +32,9 @@ import fi.vtt.simantics.procore.ProCoreSessionReference; import fi.vtt.simantics.procore.SessionManagerSource; public class SessionImplVirtual extends SessionImplSocket { + + private static final Logger LOGGER = LoggerFactory.getLogger(SessionImplVirtual.class); + protected VirtualGraphImpl virtualGraphImpl; public SessionImplVirtual(UserAuthenticationAgent authAgent) throws DatabaseException { @@ -75,12 +79,11 @@ public class SessionImplVirtual extends SessionImplSocket { } catch (InvalidUserException e) { throw e; } catch (IOException e) { - Logger.defaultLogError("I/O error. See exception for details.", e); + LOGGER.error("I/O error. See exception for details.", e); graphSession = null; throw new DatabaseException(e); } catch (Throwable e) { - e.printStackTrace(); - Logger.defaultLogError("Unhandled error. See exception for details.", e); + LOGGER.error("Unhandled error. See exception for details.", e); graphSession = null; throw new DatabaseException(e); } @@ -108,7 +111,7 @@ public class SessionImplVirtual extends SessionImplSocket { try { return gs.getServerInformation(); } catch (DatabaseException e) { - Logger.defaultLogError("Failed to get server info.", e); + LOGGER.error("Failed to get server info.", e); return null; } } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java index ea4319ace..247df4645 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java @@ -8,7 +8,6 @@ import org.simantics.db.VirtualGraph; import org.simantics.db.WriteGraph; import org.simantics.db.common.MetadataUtils; import org.simantics.db.common.exception.DebugException; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ImmutableException; import org.simantics.db.exception.ServiceException; @@ -28,9 +27,13 @@ import org.simantics.db.request.WriteOnly; import org.simantics.db.request.WriteResult; import org.simantics.db.request.WriteTraits; import org.simantics.db.service.ByteReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class WriteSupportImpl implements WriteSupport { + private static final Logger LOGGER = LoggerFactory.getLogger(WriteSupportImpl.class); + final private SessionImplSocket session; final private QueryProcessor queryProcessor; final private State state; @@ -122,7 +125,7 @@ public class WriteSupportImpl implements WriteSupport { try { addSetValue(((ResourceImpl) resource).id, value, value.length); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("writeOnly setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e); } } } else { @@ -134,7 +137,7 @@ public class WriteSupportImpl implements WriteSupport { try { addSetValue(((ResourceImpl) resource).id, value, value.length); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e); } } queryProcessor.releaseWrite(session.writeState.getGraph()); @@ -199,7 +202,7 @@ public class WriteSupportImpl implements WriteSupport { try { cluster.removeValue(key, session.clusterTranslator); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("denyValue({}, {}) failed", provider, resource, e); return; } queryProcessor.updateValue(key); @@ -460,7 +463,7 @@ public class WriteSupportImpl implements WriteSupport { if (null != c && c != cluster) session.clusterTable.replaceCluster(c); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("claimImpl({}, {}, {}) failed", subject, predicate, object, e); throw new RuntimeException(e); } queryProcessor.updateStatements(subject, predicate); @@ -480,7 +483,7 @@ public class WriteSupportImpl implements WriteSupport { if (null != c && c != cluster) session.clusterTable.replaceCluster(c); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("claimImpl2({}, {}, {}) failed", subject, predicate, object, e); } if (cluster.isWriteOnly()) return; @@ -504,7 +507,7 @@ public class WriteSupportImpl implements WriteSupport { try { cluster.denyRelation(subject, predicate, object, session.clusterTranslator); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("removeStatement({}, {}, {}) failed", subject, predicate, object, e); return false; } queryProcessor.updateStatements(subject, predicate); diff --git a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java index 5e818cb99..924ccffb0 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java +++ b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java @@ -62,7 +62,7 @@ import org.simantics.db.request.WriteInterface; * @see MergingGraphRequestProcessor * @see AsyncRequestProcessor */ -public interface RequestProcessor extends RequestProcessorSpecific, ServiceLocator { +public interface RequestProcessor extends RequestProcessorSpecific, ServiceLocator, ResourceLocator { Resource getRootLibrary(); diff --git a/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java b/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java new file mode 100644 index 000000000..8a8b0fa48 --- /dev/null +++ b/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2020 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; + +/** + * @author Tuukka Lehtonen + * @since 1.43.0 + */ +public interface ResourceLocator { + + /** + * Layer0 is an integral part of Simantics database modelling and for performance + * reasons deserves simplest possible access to its resource class. + * + * @return returns the internally cached + * org.simantics.layer0.Layer0 instance + */ + public T l0(); + +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java index e8c54fa98..6256891b8 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java @@ -3,6 +3,7 @@ package org.simantics.modeling; import gnu.trove.map.hash.THashMap; import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.db.layer0.request.PropertyInfoRequest; @@ -21,19 +22,28 @@ public class ProceduralSubstructureMapRequest extends VariableRead> perform(ReadGraph graph) throws DatabaseException { THashMap> propertyMap = new THashMap>(); for(Variable child : variable.getChildren(graph)) { - for(Variable property : child.getProperties(graph)) { - PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(property.getPredicateResource(graph))); + for(Variable property : child.getProperties(graph)) { + Resource predicate = property.getPossiblePredicateResource(graph); + if (predicate == null) + continue; + + PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(predicate)); propertyMap.put(child.getName(graph) + "." + propertyInfo.name, Pair.make("/" + child.getName(graph) + "#" + propertyInfo.name, SCLTypeUtils.getType(propertyInfo))); - } + } } - for(Variable property : variable.getProperties(graph)) { - PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(property.getPredicateResource(graph))); + for(Variable property : variable.getProperties(graph)) { + Resource predicate = property.getPossiblePredicateResource(graph); + if (predicate == null) + continue; + + PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(predicate)); propertyMap.put(propertyInfo.name, Pair.make("#" + propertyInfo.name, SCLTypeUtils.getType(propertyInfo))); - } + } + return propertyMap; }