]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java
Merge branch 'private/db-threads' into private/threads-testing
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / graph / ReadGraphImpl.java
index e3e7d50ecbc04998d62a650a9695ce939b6667ac..6998ee55e127afa761b7aad2499264bc816588d8 100644 (file)
@@ -26,6 +26,7 @@ import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
 
@@ -45,7 +46,6 @@ import org.simantics.databoard.util.binary.BinaryFile;
 import org.simantics.databoard.util.binary.RandomAccessBinary;
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.DevelopmentKeys;
-import org.simantics.db.ExternalValue;
 import org.simantics.db.ExternalValueSupport;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RelationContext;
@@ -88,6 +88,7 @@ import org.simantics.db.common.primitiverequest.UniqueAdapter;
 import org.simantics.db.common.primitiverequest.Value;
 import org.simantics.db.common.primitiverequest.ValueImplied;
 import org.simantics.db.common.primitiverequest.VariantValueImplied;
+import org.simantics.db.common.procedure.BlockingAsyncProcedure;
 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
@@ -112,6 +113,7 @@ import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
 import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure;
 import org.simantics.db.common.request.AdaptValue;
 import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.utils.Functions;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.common.validation.L0Validations;
@@ -135,13 +137,16 @@ import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.internal.RandomAccessValueSupport;
 import org.simantics.db.impl.internal.ResourceData;
 import org.simantics.db.impl.procedure.CallWrappedSingleQueryProcedure4;
+import org.simantics.db.impl.procedure.InternalProcedure;
 import org.simantics.db.impl.procedure.ResultCallWrappedQueryProcedure4;
 import org.simantics.db.impl.procedure.ResultCallWrappedSingleQueryProcedure4;
 import org.simantics.db.impl.query.CacheEntry;
 import org.simantics.db.impl.query.QueryCache;
+import org.simantics.db.impl.query.QueryCacheBase;
 import org.simantics.db.impl.query.QueryProcessor;
 import org.simantics.db.impl.query.QuerySupport;
 import org.simantics.db.impl.query.TripleIntProcedure;
+import org.simantics.db.impl.query.QueryProcessor.SessionTask;
 import org.simantics.db.impl.support.ResourceSupport;
 import org.simantics.db.procedure.AsyncListener;
 import org.simantics.db.procedure.AsyncMultiListener;
@@ -179,6 +184,7 @@ import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
 import org.simantics.scl.reflection.ReflectionUtils;
 import org.simantics.scl.reflection.ValueNotFoundException;
+import org.simantics.scl.runtime.function.Function1;
 import org.simantics.scl.runtime.function.Function3;
 import org.simantics.utils.DataContainer;
 import org.simantics.utils.Development;
@@ -280,8 +286,17 @@ public class ReadGraphImpl implements ReadGraph {
 
                try {
 
-                       return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
-                                       id));
+//                     assert (id != null);
+//                     assert (procedure != null);
+//
+//                     processor.forResource(this, id, procedure);
+//
+////                   return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
+////                                   id));
+                       
+                       Integer rid = QueryCache.resultURIToResource(this, id, parent, null);
+                       if(rid == 0) throw new ResourceNotFoundException(id);
+                       return processor.querySupport.getResource(rid);
 
                } catch (ResourceNotFoundException e) {
 
@@ -311,8 +326,10 @@ public class ReadGraphImpl implements ReadGraph {
 
                try {
 
-                       return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
-                                       id));
+                       return getResource(id);
+                       
+//                     return syncRequest(new org.simantics.db.common.primitiverequest.Resource(
+//                                     id));
 
                } catch (ResourceNotFoundException e) {
                        
@@ -333,6 +350,32 @@ public class ReadGraphImpl implements ReadGraph {
                }
 
        }
+       
+       @Override
+       public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
+               
+               assert (resource != null);
+
+               try {
+
+                       int rId = processor.querySupport.getId(resource);
+                       return QueryCache.resultChildMap(this, rId, parent, null);
+
+               } catch (ValidationException e) {
+
+                       throw new ValidationException(e);
+
+               } catch (ServiceException e) {
+
+                       throw new ServiceException(e);
+
+               } catch (DatabaseException e) {
+
+                       throw new ServiceException(INTERNAL_ERROR_STRING, e);
+
+               }
+               
+       }
 
        final public Resource getRootLibrary() {
                return processor.getRootLibraryResource();
@@ -2031,7 +2074,7 @@ public class ReadGraphImpl implements ReadGraph {
                                        throw (DatabaseException) exception;
                                else
                                        throw new DatabaseException(
-                                                       "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
+                                                       "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
                                                        exception);
                        }
                }
@@ -2047,10 +2090,12 @@ public class ReadGraphImpl implements ReadGraph {
                        throws DatabaseException {
 
                assert (request != null);
-               AsyncReadProcedure<T> procedure = new AsyncReadProcedure<T>();
-               syncRequest(request, procedure);
-               procedure.checkAndThrow();
-               return procedure.result;
+//             AsyncReadProcedure<T> procedure = new AsyncReadProcedure<T>();
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, null, request);
+               syncRequest(request, ap);
+               return ap.get();
+//             procedure.checkAndThrow();
+//             return procedure.result;
                
 //             return syncRequest(request, new AsyncProcedureAdapter<T>());
 
@@ -2082,14 +2127,18 @@ public class ReadGraphImpl implements ReadGraph {
 
                ListenerBase listener = getListenerBase(procedure);
 
-               final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
-                               procedure, request);
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
+               
+//             final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
+//                             procedure, request);
                
-               QueryCache.runnerAsyncReadEntry(this, request, parent, listener, wrapper);
+               QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true);
                
                //processor.query(this, request, parent, wrapper, listener);
                
-               return wrapper.getResult();
+               return ap.get();
+               
+//             return wrapper.getResult();
 
 //             if (parent != null || listener != null || ((request.getFlags() & RequestFlags.SCHEDULE) > 0)) {
 //
@@ -2157,10 +2206,14 @@ public class ReadGraphImpl implements ReadGraph {
                ListenerBase listener = getListenerBase(procedure);
                assert(listener == null);
 
+               BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
+               
 //             final ResultCallWrappedSingleQueryProcedure4<T> wrapper = new ResultCallWrappedSingleQueryProcedure4<T>(
 //                             procedure, request);
 
-               QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure);
+               QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true);
+               
+               ap.get();
 
        }
 
@@ -2526,28 +2579,38 @@ public class ReadGraphImpl implements ReadGraph {
        final public <T> T syncRequest(final ExternalRead<T> request,
                        final Procedure<T> procedure) throws DatabaseException {
 
-               assert (request != null);
-
-               ListenerBase listener = getListenerBase(procedure);
-               
-               final DataContainer<Throwable> exception = new DataContainer<Throwable>();
-               final DataContainer<T> result = new DataContainer<T>();
-
-               processor.query(this, request, parent, new Procedure<T>() {
-
-                       @Override
-                       public void exception(Throwable throwable) {
-                               exception.set(throwable);
-                               procedure.exception(throwable);
-                       }
+        assert (request != null);
 
-                       @Override
-                       public void execute(T t) {
-                               result.set(t);
-                               procedure.execute(t);
-                       }
+        ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
+        return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
 
-               }, listener);
+//         
+//         ListenerBase listener = getListenerBase(procedure);
+//         
+//         return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
+           
+//             assert (request != null);
+//
+//             ListenerBase listener = getListenerBase(procedure);
+//             
+//             final DataContainer<Throwable> exception = new DataContainer<Throwable>();
+//             final DataContainer<T> result = new DataContainer<T>();
+//
+//             processor.query(this, request, parent, new Procedure<T>() {
+//
+//                     @Override
+//                     public void exception(Throwable throwable) {
+//                             exception.set(throwable);
+//                             procedure.exception(throwable);
+//                     }
+//
+//                     @Override
+//                     public void execute(T t) {
+//                             result.set(t);
+//                             procedure.execute(t);
+//                     }
+//
+//             }, listener);
                
 
 
@@ -2581,18 +2644,18 @@ public class ReadGraphImpl implements ReadGraph {
 //                     }
 //
 //             }
-
-               Throwable t = exception.get();
-               if (t != null) {
-                       if (t instanceof DatabaseException)
-                               throw (DatabaseException) t;
-                       else
-                               throw new DatabaseException(
-                                               "Unexpected exception in ReadGraph.syncRequest(Read)",
-                                               t);
-               }
-
-               return result.get();            
+//
+//             Throwable t = exception.get();
+//             if (t != null) {
+//                     if (t instanceof DatabaseException)
+//                             throw (DatabaseException) t;
+//                     else
+//                             throw new DatabaseException(
+//                                             "Unexpected exception in ReadGraph.syncRequest(Read)",
+//                                             t);
+//             }
+//
+//             return result.get();            
 
        }
 
@@ -5387,47 +5450,20 @@ public class ReadGraphImpl implements ReadGraph {
 
                assert (request != null);
                assert (procedure != null);
+       
+               processor.schedule(new SessionTask(false) {
 
-               final ListenerBase listener = getListenerBase(procedure);
-
-               if (parent != null || listener != null) {
-
-                       try {
-                               QueryCache.runnerReadEntry(this, request, parent, listener, procedure);
-                               //processor.query(this, request, parent, procedure,listener);
-                       } catch (DatabaseException e) {
-                               Logger.defaultLogError(e);
-                               // This throwable has already been transferred to procedure at this point - do nothing about it
-                               //
-                       }
-                       
-               } else {
-
-//                     final ReadGraphImpl newGraph = newSync();
-
-                       try {
-
-                               T result = request.perform(this);
-                               
-                               try {
-                                       procedure.execute(this, result);
-                               } catch (Throwable t) {
-                                       Logger.defaultLogError(t);
-                               }
-
-                       } catch (Throwable t) {
-
+                       @Override
+                       public void run(int thread) {
                                try {
-                                       procedure.exception(this, t);
-                               } catch (Throwable t2) {
-                                       Logger.defaultLogError(t2);
+                                       final ListenerBase listener = getListenerBase(procedure);
+                                       QueryCache.runnerReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
+                               } catch (DatabaseException e) {
+                                       Logger.defaultLogError(e);
                                }
-
-                       } finally {
-
                        }
-
-               }
+                       
+               });
 
        }
 
@@ -5499,38 +5535,19 @@ public class ReadGraphImpl implements ReadGraph {
                assert (request != null);
                assert (procedure != null);
 
-               final ListenerBase listener = getListenerBase(procedure);
-
-               if (parent != null || listener != null) {
-
-                       try {
-                               QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure);
-                               //processor.query(this, request, parent, procedure, listener);
-                       } catch (DatabaseException e) {
-                               Logger.defaultLogError(e);
-                       }
-
-               } else {
-
-                       try {
-                               
-                               request.perform(this, new CallWrappedSingleQueryProcedure4<T>(procedure, request));
-
-                       } catch (Throwable t) {
-
-                               if (t instanceof DatabaseException)
-                                       procedure.exception(this, t);
-                               else
-                                       procedure
-                                                       .exception(
-                                                                       this,
-                                                                       new DatabaseException(
-                                                                                       "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
-                                                                                       t));
+               processor.schedule(new SessionTask(false) {
 
+                       @Override
+                       public void run(int thread) {
+                               try {
+                                       final ListenerBase listener = getListenerBase(procedure);
+                                       QueryCache.runnerAsyncReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
+                               } catch (DatabaseException e) {
+                                       Logger.defaultLogError(e);
+                               }
                        }
-
-               }
+                       
+               });
 
        }
 
@@ -5761,56 +5778,125 @@ public class ReadGraphImpl implements ReadGraph {
        final public <T> void asyncRequest(final ExternalRead<T> request,
                        final Procedure<T> procedure) {
 
-               assert (request != null);
-               assert (procedure != null);
-
-               ListenerBase listener = getListenerBase(procedure);
-
-               if (parent != null || listener != null) {
-
-                       processor.query(this, request, parent, procedure, listener);
-
-               } else {
-
-                       try {
+           
+        assert (request != null);
+        assert (procedure != null);
 
-                               request.register(this, new Listener<T>() {
+        final ListenerBase listener = getListenerBase(procedure);
 
-                                       @Override
-                                       public void execute(T result) {
-                                               procedure.execute(result);
-                                       }
+        if (parent != null || listener != null) {
 
-                                       @Override
-                                       public void exception(Throwable t) {
-                                               procedure.exception(t);
-                                       }
+            try {
+                QueryCacheBase.resultExternalReadEntry(this, request, parent, listener, procedure);
+                //processor.query(this, request, parent, procedure,listener);
+            } catch (DatabaseException e) {
+                Logger.defaultLogError(e);
+                // This throwable has already been transferred to procedure at this point - do nothing about it
+                //
+            }
+            
+        } else {
 
-                                       @Override
-                                       public String toString() {
-                                               return "asyncRequest(PrimitiveRead) -> " + request;
-                                       }
+            request.register(this, new Listener<T>() {
+                //
+                @Override
+                public void execute(T result) {
+                    procedure.execute(result);
+                }
 
-                                       @Override
-                                       public boolean isDisposed() {
-                                               return true;
-                                       }
+                @Override
+                public void exception(Throwable t) {
+                    procedure.exception(t);
+                }
 
-                               });
+                @Override
+                public String toString() {
+                    return "asyncRequest(PrimitiveRead) -> " + request;
+                }
 
-                       } catch (Throwable t) {
+                @Override
+                public boolean isDisposed() {
+                    return true;
+                }
 
-                               if (t instanceof DatabaseException)
-                                       procedure.exception(t);
-                               else
-                                       procedure
-                                                       .exception(new DatabaseException(
-                                                                       "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
-                                                                       t));
+            });            
+            
+//          final ReadGraphImpl newGraph = newSync();
 
-                       }
+//            try {
+//
+//                T result = request.perform(this);
+//                
+//                try {
+//                    procedure.execute(this, result);
+//                } catch (Throwable t) {
+//                    Logger.defaultLogError(t);
+//                }
+//
+//            } catch (Throwable t) {
+//
+//                try {
+//                    procedure.exception(this, t);
+//                } catch (Throwable t2) {
+//                    Logger.defaultLogError(t2);
+//                }
+//
+//            } finally {
+//
+//            }
 
-               }
+        }
+           
+//             assert (request != null);
+//             assert (procedure != null);
+//
+//             ListenerBase listener = getListenerBase(procedure);
+//
+//             if (parent != null || listener != null) {
+//
+//                     processor.query(this, request, parent, procedure, listener);
+//
+//             } else {
+//
+//                     try {
+//
+//                             request.register(this, new Listener<T>() {
+//
+//                                     @Override
+//                                     public void execute(T result) {
+//                                             procedure.execute(result);
+//                                     }
+//
+//                                     @Override
+//                                     public void exception(Throwable t) {
+//                                             procedure.exception(t);
+//                                     }
+//
+//                                     @Override
+//                                     public String toString() {
+//                                             return "asyncRequest(PrimitiveRead) -> " + request;
+//                                     }
+//
+//                                     @Override
+//                                     public boolean isDisposed() {
+//                                             return true;
+//                                     }
+//
+//                             });
+//
+//                     } catch (Throwable t) {
+//
+//                             if (t instanceof DatabaseException)
+//                                     procedure.exception(t);
+//                             else
+//                                     procedure
+//                                                     .exception(new DatabaseException(
+//                                                                     "Unexpected exception in ReadGraph.asyncRequest(SingleAsyncRead, SingleProcedure)",
+//                                                                     t));
+//
+//                     }
+//
+//             }
 
        }
 
@@ -6454,8 +6540,7 @@ public class ReadGraphImpl implements ReadGraph {
             for(Resource converter : graph.getObjects(resource, L0.ConvertsToValueWith)) {
                 try {
                        if(L0.Functions_functionApplication.equals(converter)) {
-                               return AdaptValue.functionApplication;
-                               //return (Function3<ReadGraph,Resource,Object,T>)graph.syncRequest(new AdaptValue(resource));
+                               return (Function3<ReadGraph,Resource,Object,T>)graph.syncRequest(new AdaptValue(resource));
                        } else {
                                return graph.getValue2(converter, resource);
                        }
@@ -6513,11 +6598,9 @@ public class ReadGraphImpl implements ReadGraph {
                }
        } else if(types.contains(L0.ExternalValue)) {
                try {
-                       ExternalValue ev = adapt(r, ExternalValue.class);
-                       return ev.getValue(this, r);
-                       //return (T)ReflectionUtils.getValue(getURI(r)).getValue();
-//             } catch(ValueNotFoundException e) {
-//                     throw new DatabaseException(e);
+                       return (T)ReflectionUtils.getValue(getURI(r)).getValue();
+               } catch(ValueNotFoundException e) {
+                       throw new DatabaseException(e);
                } catch(ClassCastException e) {
                        throw new DatabaseException(e);
                }
@@ -6662,16 +6745,22 @@ public class ReadGraphImpl implements ReadGraph {
         }
     }
     
+    private static ThreadLocal<Boolean> syncGraph = new ThreadLocal<Boolean>() {
+        protected Boolean initialValue() {
+            return true;
+        }
+    };
+
     @Override
     public boolean setSynchronous(boolean value) {
-        boolean old = processor.synch;
-        processor.synch = value;
+        boolean old = getSynchronous();
+        syncGraph.set(value);
         return old;
     }
     
     @Override
     public boolean getSynchronous() {
-        return processor.synch;
+        return syncGraph.get();
     }
     
     public void ensureLoaded(int resource) {
@@ -6702,5 +6791,10 @@ public class ReadGraphImpl implements ReadGraph {
     public Object getModificationCounter() {
        return processor.getSession().getModificationCounter();
     }
+
+       @Override
+       public boolean performPending() {
+               return processor.performPending(processor.thread.get());
+       }
     
 }