]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/ReadEntry.java
Merge "Trying to wait for procedures"
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / ReadEntry.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2018 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.query;
13
14 import org.simantics.db.AsyncReadGraph;
15 import org.simantics.db.exception.DatabaseException;
16 import org.simantics.db.impl.graph.ReadGraphImpl;
17 import org.simantics.db.procedure.AsyncProcedure;
18 import org.simantics.db.request.Read;
19 import org.simantics.db.request.ReadExt;
20 import org.simantics.db.request.RequestFlags;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 public final class ReadEntry<T> extends CacheEntryBase<AsyncProcedure<T>> implements AsyncProcedure<T> {
25
26     private static final Logger LOGGER = LoggerFactory.getLogger(ReadEntry.class);
27
28     protected Read<T> request;
29
30     public ReadEntry(Read<T> request) {
31         this.request = request;
32     }
33
34     @Override
35     int makeHash() {
36         return request.hashCode();
37     }
38
39     @Override
40     public Object getOriginalRequest() {
41         return request;
42     }
43
44     @Override
45     public void discard() {
46         super.discard();
47         setResult(null);
48     }
49
50     @Override
51     final public Query getQuery() {
52
53         return new Query() {
54
55             @Override
56             public void recompute(ReadGraphImpl graph) {
57
58                 try {
59
60                     T result = request.perform(graph);
61                     setResult(result);
62                     setReady();
63
64                 } catch (Throwable t) {
65
66                     except(t);
67
68                 }
69
70             }
71
72             @Override
73             public void removeEntry(QueryProcessor processor) {
74                 processor.cache.remove(ReadEntry.this);
75             }
76
77             @Override
78             public int type() {
79                 if (request instanceof ReadExt) {
80                     return ((ReadExt) request).getType();
81                 } else {
82                     return RequestFlags.INVALIDATE;
83                 }
84             }
85
86             @Override
87             public String toString() {
88                 if (request == null)
89                     return "DISCARDED";
90                 else
91                     return request.toString() + statusOrException;
92             }
93
94         };
95
96     }
97
98     public static <T> T computeForEach(ReadGraphImpl graph, Read<T> request, ReadEntry<T> entry,
99             AsyncProcedure<T> procedure_) throws DatabaseException {
100
101         AsyncProcedure<T> procedure = entry != null ? entry : procedure_;
102
103         ReadGraphImpl queryGraph = graph.withParent(entry);
104         queryGraph.asyncBarrier.inc();
105
106         ReadGraphImpl executeGraph = graph.withParent(graph.parent);
107         executeGraph.asyncBarrier.inc();
108         
109         try {
110
111             // This throws
112             T result = request.perform(queryGraph);
113
114             if(procedure != null) procedure.execute(executeGraph, result);
115             return (T)result;
116
117         } catch (DatabaseException e) {
118
119             if(procedure != null) procedure.exception(executeGraph, e);
120             throw e;
121
122         } catch (Throwable t) {
123
124             DatabaseException dbe = new DatabaseException(t);
125             if(procedure != null) procedure.exception(executeGraph, dbe);
126             throw dbe;
127
128         } finally {
129
130             queryGraph.asyncBarrier.dec();
131
132             try {
133             
134                 if (entry != null) {
135                     // This also throws so must dec barrier finally
136                     entry.performFromCache(executeGraph, procedure_);
137                 }
138             
139             } finally {
140  
141                 executeGraph.asyncBarrier.dec();
142                 executeGraph.asyncBarrier.waitBarrier(procedure, executeGraph);
143
144             }
145                 
146  
147         }
148
149     }
150
151     public Object performFromCache(ReadGraphImpl graph, AsyncProcedure<T> procedure) throws DatabaseException {
152
153         AsyncProcedure<T> proc = (AsyncProcedure<T>) procedure;
154
155         if (isExcepted()) {
156                 if(proc != null) {
157                     try {
158                         proc.exception(graph, (Throwable) getResult());
159                     } catch (Throwable t) {
160                         LOGGER.error("performFromCache proc.exception failed", t);
161                     }
162                 }
163                 Throwable t = (Throwable) getResult();
164                 if(t instanceof DatabaseException) {
165                     throw (DatabaseException)t;
166                 } else {
167                     throw new DatabaseException(t);
168                 }
169         } else {
170                 if(proc != null) {
171                     try {
172                         proc.execute(graph, (T) getResult());
173                     } catch (Throwable t) {
174                         LOGGER.error("performFromCache proc.execute failed", t);
175                     }
176                 }
177                 return (T)getResult();
178         }
179
180     }
181
182     @Override
183     public String toString() {
184         if (request == null)
185             return "DISCARDED";
186         else
187             return request.toString() + " - " + statusOrException;
188     }
189
190     public Object get(ReadGraphImpl graph, AsyncProcedure<T> procedure) throws DatabaseException {
191         if (procedure != null)
192             performFromCache(graph, procedure);
193         checkAndThrow();
194         return getResult();
195     }
196
197     @Override
198     boolean isImmutable(ReadGraphImpl graph) throws DatabaseException {
199         if (request instanceof ReadExt) {
200             return ((ReadExt) request).isImmutable(graph);
201         }
202         return false;
203     }
204
205     @Override
206     public void execute(AsyncReadGraph graph, T result) {
207         setResult(result);
208         setReady();
209     }
210
211     @Override
212     public void exception(AsyncReadGraph graph, Throwable throwable) {
213         except(throwable);
214     }
215
216 }