From: jsimomaa Date: Tue, 6 Nov 2018 13:15:35 +0000 (+0200) Subject: Initial support for concurrency in databoard, bindings and serializers X-Git-Tag: v1.43.0~136^2~292 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=48bb50bb6640506d1f150ca8e4fa5a6e878464be Initial support for concurrency in databoard, bindings and serializers * This fixes the parallellization problem in PlatformUtil.getAllGraphs where parallel streams can now be used. * VariableBinding is removed because it hasn't ever been used and it is deadlock prone and not very useful * Removed SerialisationSupport field from ResourceBinding as it has been commented out for ages now. If we need this at some point, let's add it back. gitlab #180 Change-Id: Ic4240921b5e60ea8d642feb85e9608f936272190 --- diff --git a/bundles/org.simantics.databoard/META-INF/MANIFEST.MF b/bundles/org.simantics.databoard/META-INF/MANIFEST.MF index 27a0534eb..e44b55bd4 100644 --- a/bundles/org.simantics.databoard/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.databoard/META-INF/MANIFEST.MF @@ -11,7 +11,8 @@ Require-Bundle: org.junit;resolution:=optional, org.eclipse.swt;bundle-version="3.7.1";resolution:=optional, org.eclipse.jface;bundle-version="3.7.0";resolution:=optional, org.eclipse.core.runtime;bundle-version="3.7.0";resolution:=optional, - org.apache.commons.collections;bundle-version="3.2.1" + org.apache.commons.collections;bundle-version="3.2.1", + org.slf4j.api Export-Package: org.simantics.databoard, org.simantics.databoard.accessor, org.simantics.databoard.accessor.binary, diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java index 138ca5c05..f9cf10023 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/Bindings.java @@ -71,7 +71,7 @@ import org.simantics.databoard.binding.reflection.VoidBinding; import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.serialization.SerializerConstructionException; -import org.simantics.databoard.serialization.SerializerFactory; +import org.simantics.databoard.serialization.SerializerScheme; import org.simantics.databoard.type.ArrayType; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.DataValueUtil; @@ -112,7 +112,7 @@ public class Bindings { public static final ClassBindingFactory classBindingFactory; /** Serializer Factory */ - public static final SerializerFactory serializationFactory; + public static final SerializerScheme serializationFactory; /** Adapter Factory */ public static final AdapterFactory adapterFactory; @@ -500,7 +500,7 @@ public class Bindings { * @throws SerializerConstructionException */ public static Serializer getSerializer(Binding binding) throws SerializerConstructionException { - return serializationFactory.construct(binding); + return serializationFactory.getSerializer(binding); } /** @@ -511,11 +511,7 @@ public class Bindings { * @throws RuntimeSerializerConstructionException */ public static Serializer getSerializerUnchecked(Binding binding) throws RuntimeSerializerConstructionException { - try { - return serializationFactory.construct(binding); - } catch (SerializerConstructionException e) { - throw new RuntimeSerializerConstructionException(e); - } + return serializationFactory.getSerializerUnchecked(binding); } /** @@ -528,7 +524,7 @@ public class Bindings { public static Serializer getSerializer(Class clazz) throws SerializerConstructionException { try { Binding binding = getBinding(clazz); - return serializationFactory.construct(binding); + return serializationFactory.getSerializer(binding); } catch (BindingConstructionException e) { throw new SerializerConstructionException( e ); } @@ -544,9 +540,7 @@ public class Bindings { public static Serializer getSerializerUnchecked(Class clazz) throws RuntimeSerializerConstructionException { try { Binding binding = getBinding(clazz); - return serializationFactory.construct(binding); - } catch (SerializerConstructionException e) { - throw new RuntimeSerializerConstructionException(e); + return serializationFactory.getSerializerUnchecked(binding); } catch (BindingConstructionException e) { throw new RuntimeSerializerConstructionException( new SerializerConstructionException(e) ); } diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/Databoard.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/Databoard.java index da488e0a8..195e87a17 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/Databoard.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/Databoard.java @@ -51,11 +51,11 @@ import org.simantics.databoard.binding.reflection.BindingProvider; import org.simantics.databoard.binding.reflection.BindingRequest; import org.simantics.databoard.binding.reflection.ClassBindingFactory; import org.simantics.databoard.binding.reflection.VoidBinding; -import org.simantics.databoard.serialization.DefaultSerializerFactory; +import org.simantics.databoard.serialization.DefaultConcurrentSerializerFactory; import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.serialization.SerializerConstructionException; -import org.simantics.databoard.serialization.SerializerFactory; +import org.simantics.databoard.serialization.SerializerScheme; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.Bean; import org.simantics.databoard.util.DataValueUtil; @@ -89,7 +89,8 @@ public class Databoard { public final ClassBindingFactory classBindingFactory = new ClassBindingFactory( bindingRepository, defaultBindingFactory ); /** Serializer Factory */ - public final SerializerFactory serializationFactory = new DefaultSerializerFactory( serializerRepository ); + //public final SerializerFactory serializationFactory = new DefaultSerializerFactory( serializerRepository ); + public final SerializerScheme serializationFactory = new DefaultConcurrentSerializerFactory(); /** Adapter Factory */ public final AdapterFactory adapterFactory = new AdapterFactory(); @@ -483,7 +484,7 @@ public class Databoard { * @throws SerializerConstructionException */ public Serializer getSerializer(Binding binding) throws SerializerConstructionException { - return serializationFactory.construct(binding); + return serializationFactory.getSerializer(binding); } /** @@ -494,11 +495,7 @@ public class Databoard { * @throws RuntimeSerializerConstructionException */ public Serializer getSerializerUnchecked(Binding binding) throws RuntimeSerializerConstructionException { - try { - return serializationFactory.construct(binding); - } catch (SerializerConstructionException e) { - throw new RuntimeSerializerConstructionException(e); - } + return serializationFactory.getSerializerUnchecked(binding); } /** @@ -511,7 +508,7 @@ public class Databoard { public Serializer getSerializer(Class clazz) throws SerializerConstructionException { try { Binding binding = getBinding(clazz); - return serializationFactory.construct(binding); + return serializationFactory.getSerializer(binding); } catch (BindingConstructionException e) { throw new SerializerConstructionException( e ); } @@ -527,9 +524,7 @@ public class Databoard { public Serializer getSerializerUnchecked(Class clazz) throws RuntimeSerializerConstructionException { try { Binding binding = getBinding(clazz); - return serializationFactory.construct(binding); - } catch (SerializerConstructionException e) { - throw new RuntimeSerializerConstructionException(e); + return serializationFactory.getSerializerUnchecked(binding); } catch (BindingConstructionException e) { throw new RuntimeSerializerConstructionException( new SerializerConstructionException(e) ); } diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/StringVariantBinding.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/StringVariantBinding.java index 05969341c..cf3b84c7b 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/StringVariantBinding.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/StringVariantBinding.java @@ -27,7 +27,7 @@ import org.simantics.databoard.binding.mutable.MutableVariant; import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; import org.simantics.databoard.serialization.Serializer; import org.simantics.databoard.serialization.SerializerConstructionException; -import org.simantics.databoard.serialization.SerializerFactory; +import org.simantics.databoard.serialization.SerializerScheme; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.Base64; import org.simantics.databoard.util.URIUtil; @@ -52,10 +52,10 @@ import org.simantics.databoard.util.binary.BinaryReadable; */ public class StringVariantBinding extends VariantBinding { - SerializerFactory serializationFactory; + SerializerScheme serializationFactory; VariantBinding variantBinding; - public StringVariantBinding(SerializerFactory serializationFactory, VariantBinding variantBinding) { + public StringVariantBinding(SerializerScheme serializationFactory, VariantBinding variantBinding) { this.serializationFactory = serializationFactory; this.variantBinding = variantBinding; } diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/ConcurrentSerializerFactory.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/ConcurrentSerializerFactory.java new file mode 100644 index 000000000..463b5c252 --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/ConcurrentSerializerFactory.java @@ -0,0 +1,106 @@ +package org.simantics.databoard.serialization; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.simantics.databoard.binding.Binding; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Jani Simomaa + */ +public abstract class ConcurrentSerializerFactory implements SerializerScheme { + + private Logger LOGGER = LoggerFactory.getLogger(getClass()); + + /** + * Repository where serializers are placed. + */ + private ConcurrentHashMap> repository = new ConcurrentHashMap<>(); + private ConcurrentHashMap inProgress = new ConcurrentHashMap<>(); + + /** + * Constructs a serilizer for a binding. Implement this. + * It should use the inprogress -map for construction of + * serializers that have component types. + * + * e.g. + * inprogress.put(binding, notCompletelyConstructedSerializer); + * Serializer componentSerializer = construct( componentBinding ); + * notCompletelyConstructedSerializer.setComponent( componentSerializer ); + * inprogress.remove(binding); + * + * try-finally is not needed. + * + * @param request + * @return + * @throws SerializerConstructionException + */ + protected abstract Serializer doConstruct(Binding request) throws SerializerConstructionException; + + protected Serializer construct(Binding request) throws SerializerConstructionException { + if (request.cachedSerializer() != null) { + return request.cachedSerializer(); + } else { + // this is required cause construct can be called from subclasses + repository.putIfAbsent(request, new CompletableFuture<>()); + // lets see if we are processing this already + Serializer binding = inProgress.get(request); + if (binding == null) { + binding = doConstruct(request); + request.cacheSerializer(binding); + CompletableFuture completableFuture = repository.get(request); + completableFuture.complete(binding); // this releases the waiters + } + return binding; + } + } + + protected void addInProgress(Binding request, Serializer serializer) { + inProgress.put(request, serializer); + } + + protected void finishInProgress(Binding request) { + Serializer remove = inProgress.remove(request); + request.cacheSerializer(remove); + CompletableFuture existing = repository.get(request); + if (existing != null) { + existing.complete(remove); + } else { + LOGGER.warn("Finishing binding request {} for serializer {} without CompletableFuture!", request, remove); + } + } + + @Override + public Serializer getSerializer(Binding binding) throws SerializerConstructionException { + if (binding.cachedSerializer() != null) + return binding.cachedSerializer(); + // this shouldn't be called that many time as serializers are cached on bindings + AtomicBoolean shouldConstruct = new AtomicBoolean(false); + CompletableFuture completableFuture = repository.computeIfAbsent(binding, t -> { + shouldConstruct.set(true); + return new CompletableFuture<>(); + }); + if (shouldConstruct.get()) { + // construct should complete the completable future and release the waiters + construct(binding); + } + // we should be ready at this point + try { + return completableFuture.get(); + } catch (Exception e) { + throw new SerializerConstructionException(e); + } + } + + public Serializer getSerializerUnchecked(Binding binding) throws RuntimeSerializerConstructionException { + try { + return getSerializer(binding); + } catch (SerializerConstructionException e) { + throw new RuntimeSerializerConstructionException(e); + } + } + +} diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/DefaultConcurrentSerializerFactory.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/DefaultConcurrentSerializerFactory.java new file mode 100644 index 000000000..65147b3f9 --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/DefaultConcurrentSerializerFactory.java @@ -0,0 +1,193 @@ +package org.simantics.databoard.serialization; + +import org.simantics.databoard.binding.ArrayBinding; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.BooleanBinding; +import org.simantics.databoard.binding.ByteBinding; +import org.simantics.databoard.binding.DoubleBinding; +import org.simantics.databoard.binding.FloatBinding; +import org.simantics.databoard.binding.IntegerBinding; +import org.simantics.databoard.binding.LongBinding; +import org.simantics.databoard.binding.MapBinding; +import org.simantics.databoard.binding.OptionalBinding; +import org.simantics.databoard.binding.RecordBinding; +import org.simantics.databoard.binding.StringBinding; +import org.simantics.databoard.binding.UnionBinding; +import org.simantics.databoard.binding.VariantBinding; +import org.simantics.databoard.binding.impl.BooleanArrayBinding; +import org.simantics.databoard.binding.impl.ByteArrayBinding; +import org.simantics.databoard.binding.impl.DoubleArrayBinding; +import org.simantics.databoard.binding.impl.FloatArrayBinding; +import org.simantics.databoard.binding.impl.IntArrayBinding; +import org.simantics.databoard.binding.impl.LongArrayBinding; +import org.simantics.databoard.serialization.impl.ArraySerializer; +import org.simantics.databoard.serialization.impl.BooleanArraySerializer; +import org.simantics.databoard.serialization.impl.BooleanSerializer; +import org.simantics.databoard.serialization.impl.ByteArraySerializer; +import org.simantics.databoard.serialization.impl.ByteSerializer; +import org.simantics.databoard.serialization.impl.DoubleArraySerializer; +import org.simantics.databoard.serialization.impl.DoubleSerializer; +import org.simantics.databoard.serialization.impl.FloatArraySerializer; +import org.simantics.databoard.serialization.impl.FloatSerializer; +import org.simantics.databoard.serialization.impl.GenericRecordSerializer; +import org.simantics.databoard.serialization.impl.IntArraySerializer; +import org.simantics.databoard.serialization.impl.IntSerializer; +import org.simantics.databoard.serialization.impl.LongArraySerializer; +import org.simantics.databoard.serialization.impl.LongSerializer; +import org.simantics.databoard.serialization.impl.MapSerializer; +import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer; +import org.simantics.databoard.serialization.impl.MutableVariantSerializer; +import org.simantics.databoard.serialization.impl.OptionalSerializer; +import org.simantics.databoard.serialization.impl.ReferableRecordSerializer; +import org.simantics.databoard.serialization.impl.UnionSerializer; +import org.simantics.databoard.serialization.impl.VariantSerializer; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.BooleanType; +import org.simantics.databoard.type.ByteType; +import org.simantics.databoard.type.DoubleType; +import org.simantics.databoard.type.FloatType; +import org.simantics.databoard.type.IntegerType; +import org.simantics.databoard.type.LongType; + +/** + * @author Jani Simomaa + */ +public class DefaultConcurrentSerializerFactory extends ConcurrentSerializerFactory { + + @Override + protected Serializer doConstruct(Binding binding) throws SerializerConstructionException { + + // Specialized serializers + if (binding instanceof SpecializedSerializerProvider) { + Serializer specializedSerializer = ((SpecializedSerializerProvider) binding).getSpecializedSerializer(); + if (specializedSerializer != null) + return specializedSerializer; + } + + // Primitives + if (binding instanceof BooleanBinding) + return new BooleanSerializer((BooleanBinding) binding); + if (binding instanceof ByteBinding) + return new ByteSerializer((ByteBinding) binding); + if (binding instanceof IntegerBinding) + return new IntSerializer((IntegerBinding) binding); + if (binding instanceof LongBinding) + return new LongSerializer((LongBinding) binding); + if (binding instanceof FloatBinding) + return new FloatSerializer((FloatBinding) binding); + if (binding instanceof DoubleBinding) + return new DoubleSerializer((DoubleBinding) binding); + if (binding instanceof StringBinding) + return new ModifiedUTF8StringSerializer((StringBinding) binding); + + // Record + if (binding instanceof RecordBinding) { + RecordBinding b = (RecordBinding) binding; + Binding[] componentBindings = b.getComponentBindings(); + int count = b.getComponentCount(); + + if (b.type().isReferable()) { + ReferableRecordSerializer result = new ReferableRecordSerializer(b, null); + addInProgress(binding, result); + result.componentSerializers = new Serializer[count]; + for (int i = 0; i < count; i++) { + result.componentSerializers[i] = construct(componentBindings[i]); + } + result.finalizeConstruction(); + finishInProgress(binding); + return result; + } else { + GenericRecordSerializer result = new GenericRecordSerializer(b, null); + addInProgress(binding, result); + result.componentSerializers = new Serializer[count]; + for (int i = 0; i < count; i++) { + result.componentSerializers[i] = construct(componentBindings[i]); + } + result.finalizeConstruction(); + finishInProgress(binding); + return result; + } + } + + // Union + if (binding instanceof UnionBinding) { + UnionBinding b = (UnionBinding) binding; + Binding[] componentBindings = b.getComponentBindings(); + int count = b.getComponentCount(); + + UnionSerializer result = new UnionSerializer(b, null); + addInProgress(binding, result); + result.componentSerializers = new Serializer[count]; + for (int i = 0; i < count; i++) { + result.componentSerializers[i] = construct(componentBindings[i]); + } + result.finalizeConstruction(); + finishInProgress(binding); + return result; + } + + // Optional + if (binding instanceof OptionalBinding) { + OptionalBinding b = (OptionalBinding) binding; + OptionalSerializer result = new OptionalSerializer(b, null); + addInProgress(binding, result); + result.componentSerializer = construct(b.getComponentBinding()); + finishInProgress(binding); + return result; + } + + // Array + if (binding instanceof ArrayBinding) { + ArrayBinding b = (ArrayBinding) binding; + ArrayType type = (ArrayType) b.type(); + + if (b instanceof FloatArrayBinding && type.componentType instanceof FloatType) + return new FloatArraySerializer(b); + if (b instanceof DoubleArrayBinding && type.componentType instanceof DoubleType) + return new DoubleArraySerializer(b); + if (b instanceof IntArrayBinding && type.componentType instanceof IntegerType) + return new IntArraySerializer(b); + if (b instanceof ByteArrayBinding && type.componentType instanceof ByteType) + return new ByteArraySerializer(b); + if (b instanceof BooleanArrayBinding && type.componentType instanceof BooleanType) + return new BooleanArraySerializer(b); + if (b instanceof LongArrayBinding && type.componentType instanceof LongType) + return new LongArraySerializer(b); + + ArraySerializer result = new ArraySerializer(b, null); + addInProgress(binding, result); + result.componentSerializer = construct(b.getComponentBinding()); + result.finalizeConstruction(); + finishInProgress(binding); + return result; + } + + // Map + if (binding instanceof MapBinding) { + MapBinding b = (MapBinding) binding; + MapSerializer result = new MapSerializer(b, null, null); + addInProgress(binding, result); + result.keySerializer = construct(b.getKeyBinding()); + result.valueSerializer = construct(b.getValueBinding()); + result.finalizeConstruction(); + finishInProgress(binding); + return result; + } + + // Variant + if (binding instanceof VariantBinding) { + VariantSerializer result = binding.isImmutable() ? new VariantSerializer((VariantBinding) binding, this) + : new MutableVariantSerializer((VariantBinding) binding, this); + result.finalizeConstruction(); + return result; + } + + throw new SerializerConstructionException("Cannot serialize " + binding.getClass().getName()); + } + + @Override + public boolean supportsBinding(Binding binding) { + return true; + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/bindings/ResourceBinding.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/bindings/ResourceBinding.java index d623b439f..eca8a89da 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/bindings/ResourceBinding.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/bindings/ResourceBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * Copyright (c) 2007, 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 @@ -31,23 +31,13 @@ public class ResourceBinding extends LongBinding { public static final Datatype RESOURCE_TYPE; - //SerialisationSupport support; - /** - * Create resource binding. If session is not provided, this binding cannot instantiate resources. + * Create resource binding. * * @param session or null */ - public ResourceBinding(Session session) { + public ResourceBinding() { super(Datatypes.LONG); -// if (session != null) { -// support = session.peekService(SerialisationSupport.class); -// } - } - - public ResourceBinding(SerialisationSupport serializationSupport) { - super(Datatypes.LONG); -// this.support = serializationSupport; } /** @@ -56,10 +46,6 @@ public class ResourceBinding extends LongBinding { * if not able to return a current {@link SerialisationSupport} */ private SerialisationSupport getCurrentSupport() throws BindingException { - // FIXME: this is wrong but should be optimized if possible. -// if (support != null) -// return support; - Session s = SimanticsInternal.peekSession(); if ( s == null ) { throw new BindingException("Cannot instantiate Resource without an alive database Session."); @@ -118,8 +104,6 @@ public class ResourceBinding extends LongBinding { public Long getValue(Object o) throws BindingException { SerialisationSupport support = getCurrentSupport(); // NOTE: r.getResourceId() is unsafe for this purpose, it will just return 0 if it fails, thus corrupting anything serialized with this method -// Resource r = (Resource) o; -// return r.getResourceId(); try { return support.getRandomAccessId((Resource)o); } catch (DatabaseException e) { @@ -131,8 +115,6 @@ public class ResourceBinding extends LongBinding { public long getValue_(Object o) throws BindingException { SerialisationSupport support = getCurrentSupport(); // NOTE: r.getResourceId() is unsafe for this purpose, it will just return 0 if it fails, thus corrupting anything serialized with this method -// Resource r = (Resource) o; -// return r.getResourceId(); try { return support.getRandomAccessId((Resource)o); } catch (DatabaseException e) { diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableBinding.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableBinding.java deleted file mode 100644 index a1f43a2ed..000000000 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableBinding.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2011 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: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.db.layer0.variable; - -import org.simantics.databoard.Datatypes; -import org.simantics.databoard.binding.StringBinding; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.db.Session; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.request.ResourceURIToVariable; -import org.simantics.db.layer0.request.VariableURI; - -/** - * This class binds Variable to StringType - * - * @author toni.kalajainen - */ -public class VariableBinding extends StringBinding { - - Session session; - - public VariableBinding(Session session) { - super(Datatypes.STRING); - this.session = session; - } - - @Override - public boolean isImmutable() { - return true; - } - - @Override - public Object create(String value) throws BindingException { - if ( session == null ) throw new BindingException("Cannot create Variable without a Session"); - try { - return session.sync( new ResourceURIToVariable( value ) ); - } catch (DatabaseException e) { - throw new BindingException(e); - } - } - - @Override - public String getValue(Object o) throws BindingException { - if ( session == null ) throw new BindingException("Cannot create Variable without a Session"); - if (o instanceof Variable==false) throw new BindingException("Not a variable"); - Variable v = (Variable) o; - try { - return (String) session.sync( new VariableURI( v ) ); - } catch (DatabaseException e) { - throw new BindingException( e ); - } - } - - @Override - public void setValue(Object o, String newValue) throws BindingException { - throw new BindingException("Cannot set URI to Variable. URI is immutable"); - } - - @Override - public boolean isInstance(Object obj) { - return obj instanceof Variable; - } - -} diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java b/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java index 2f94ff967..af59dbfc1 100644 --- a/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java +++ b/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java @@ -325,11 +325,7 @@ public class PlatformUtil { AtomicReference problem = new AtomicReference<>(); Collection gbundles = Arrays.stream(getBundles()) - // #7806: Due to databoard Binding/Serializer construction process thread-unsafety - // not even the DataContainer.readHeader invocations can run in parallel, most likely - // due to recurring serializer construction for Variant datatypes. - // Therefore, we must disable parallel loading for now. - //.parallel() + .parallel() .map(b -> { try { return problem.get() == null ? getGraphs(b) : Collections.emptyList(); diff --git a/bundles/org.simantics/src/org/simantics/SimanticsBindings.java b/bundles/org.simantics/src/org/simantics/SimanticsBindings.java index cf81a68f8..92f97bc64 100644 --- a/bundles/org.simantics/src/org/simantics/SimanticsBindings.java +++ b/bundles/org.simantics/src/org/simantics/SimanticsBindings.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Copyright (c) 2007, 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 @@ -17,7 +17,6 @@ import org.simantics.databoard.binding.reflection.BindingProvider; import org.simantics.databoard.binding.reflection.BindingRequest; import org.simantics.databoard.binding.reflection.ClassBindingFactory; import org.simantics.db.Resource; -import org.simantics.db.Session; import org.simantics.db.layer0.bindings.ResourceBinding; /** @@ -26,28 +25,18 @@ import org.simantics.db.layer0.bindings.ResourceBinding; * @author toni.kalajainen */ public class SimanticsBindings implements BindingProvider { - + ResourceBinding resourceBinding; - //VariableBinding variableBinding; - - public SimanticsBindings(Session session) { - this.resourceBinding = new ResourceBinding((Session) null); - //this.variableBinding = new VariableBinding(session); + + public SimanticsBindings() { + this.resourceBinding = new ResourceBinding(); } - + public Binding provideBinding(ClassBindingFactory master, BindingRequest request) throws BindingConstructionException { if (Resource.class.isAssignableFrom( request.getClazz() )) { return resourceBinding; } - - // Tuukka: disabled because the implementation is deadlock prone - // and therefore Variables should not be used directly in Bean classes - // until we figure out a way to fix VariableBinding or just throw it away. -// if (Variable.class.isAssignableFrom( request.getClazz() )) { -// return variableBinding; -// } - return null; - } + } } diff --git a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java index cc5a0e270..8b1ac1bce 100644 --- a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java +++ b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java @@ -186,7 +186,6 @@ public class SimanticsPlatform implements LifecycleListener { /** Session specific bindings */ public SimanticsBindings simanticsBindings; - public SimanticsBindings simanticsBindings2; public Thread mainThread; @@ -864,17 +863,11 @@ public class SimanticsPlatform implements LifecycleListener { Simantics.setSessionContext(sessionContext); // 1. Put ResourceBinding that throws an exception to General Bindings - simanticsBindings = new SimanticsBindings( null ); + simanticsBindings = new SimanticsBindings(); Bindings.classBindingFactory.addFactory( simanticsBindings ); - - // 2. Create session-specific second Binding context (Databoard) and - // put that to Session as a service Session session = sessionContext.getSession(); - Databoard sessionDataboard = new Databoard(); - session.registerService(Databoard.class, sessionDataboard); - simanticsBindings2 = new SimanticsBindings( session ); - sessionDataboard.classBindingFactory.addFactory( simanticsBindings2 ); + session.registerService(Databoard.class, Bindings.databoard); // Register datatype bindings Bindings.defaultBindingFactory.getRepository().put(RGB.Integer.BINDING.type(), RGB.Integer.BINDING); @@ -982,12 +975,9 @@ public class SimanticsPlatform implements LifecycleListener { running = false; progress.subTask("Close Database Session"); - Databoard databoard = null; if (sessionContext != null) { Session s = sessionContext.peekSession(); if (s != null) { - databoard = s.peekService(Databoard.class); - progress.subTask("Flushing Index Caches"); try { Simantics.flushIndexCaches(progress.newChild(20), s); @@ -1005,13 +995,6 @@ public class SimanticsPlatform implements LifecycleListener { Bindings.classBindingFactory.removeFactory( simanticsBindings ); simanticsBindings = null; } - if (databoard != null) { - if (simanticsBindings2 != null) { - databoard.classBindingFactory.removeFactory( simanticsBindings2 ); - simanticsBindings2 = null; - } - databoard.clear(); - } // Make sure Simantics clipboard doesn't store unwanted session data references. Simantics.setClipboard(new SimanticsClipboardImpl());