Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.document.server / src / org / simantics / document / server / request / DocumentRequest.java
1 package org.simantics.document.server.request;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Set;
10
11 import org.simantics.db.AsyncReadGraph;
12 import org.simantics.db.ReadGraph;
13 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
14 import org.simantics.db.common.request.UnaryAsyncRead;
15 import org.simantics.db.exception.DatabaseException;
16 import org.simantics.db.layer0.request.VariableRead;
17 import org.simantics.db.layer0.variable.Variable;
18 import org.simantics.db.procedure.AsyncProcedure;
19 import org.simantics.document.server.JSONObject;
20
21 public class DocumentRequest extends VariableRead<List<JSONObject>> {
22         
23         public static boolean PROFILE = false;
24         // Thresholds in microseconds
25         public static int PROFILE_THRESHOLD_NODEREQUEST = 2000;
26         public static int PROFILE_THRESHOLD_VALUEREQUEST = 500;
27
28     public DocumentRequest(Variable var) {
29         super(var);
30         }
31
32     static class CollectNodesRequest extends UnaryAsyncRead<Collection<Variable>, Collection<JSONObject>> {
33
34         public CollectNodesRequest(Collection<Variable> nodes) {
35             super(nodes);
36         }
37
38         @Override
39         public void perform(AsyncReadGraph graph, AsyncProcedure<Collection<JSONObject>> procedure) {
40             HashSet<JSONObject> rs = new HashSet<JSONObject>(); // result
41
42             for(Variable node : parameter) {
43                 graph.asyncRequest(new NodeRequest(node), new AsyncProcedure<JSONObject> () {
44
45                     @Override
46                     public void execute(AsyncReadGraph graph, JSONObject result) {
47                         synchronized(rs) {
48                             rs.add(result);
49                         }
50                     }
51
52                     @Override
53                     public void exception(AsyncReadGraph graph, Throwable throwable) {
54                     }
55
56                 });
57
58             }
59             procedure.execute(graph, rs);
60
61         }
62
63     }
64
65     @Override
66     public List<JSONObject> perform(ReadGraph graph) throws DatabaseException {
67
68         long s = System.nanoTime();
69
70         Set<Variable> nodes = graph.syncRequest(new NodesRequest(variable), TransientCacheAsyncListener.<Set<Variable>>instance());
71         if(nodes.isEmpty()) {
72             return Collections.emptyList();
73         }
74
75         if(PROFILE) {
76             long dura = System.nanoTime()-s;
77             System.err.println("DocumentRequest1 " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph));
78         }
79
80         Collection<JSONObject> rs = graph.syncRequest(new CollectNodesRequest(nodes));
81
82         if(PROFILE) {
83             long dura = System.nanoTime()-s;
84             System.err.println("DocumentRequest2 " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph));
85         }
86
87                 ArrayList<JSONObject> result = new ArrayList<JSONObject>(rs);
88                 Collections.sort(result, new Comparator<JSONObject>() {
89
90                         @Override
91                         public int compare(JSONObject o1, JSONObject o2) {
92                                 return o1.id.compareTo(o2.id);
93                         }
94                         
95                 });
96         
97         if(PROFILE) {
98                 long dura = System.nanoTime()-s;
99                 System.err.println("DocumentRequest3 " + System.identityHashCode(this) + " in " + 1e-6*dura + "ms. " + variable.getURI(graph));
100         }
101
102                 return result;
103
104         }
105 }