1
2
3
4 package org.melati.poem.test;
5
6 import java.util.Enumeration;
7 import java.util.Random;
8
9 import org.melati.poem.AccessToken;
10 import org.melati.poem.CachedSelection;
11 import org.melati.poem.PoemTask;
12 import org.melati.poem.PoemThread;
13 import org.melati.poem.Table;
14 import org.melati.poem.UnexpectedExceptionPoemException;
15
16
17
18
19
20
21 public class MultiThreadedCachedSelectionTest extends EverythingTestCase {
22
23 private static String theResult;
24
25 protected static EverythingDatabase db;
26
27 public MultiThreadedCachedSelectionTest(String arg0) {
28 super(arg0);
29 }
30
31 protected void setUp() throws Exception {
32 super.setUp();
33 db = (EverythingDatabase)getDb();
34 }
35
36 protected void tearDown() throws Exception {
37 super.tearDown();
38 }
39
40 abstract static class PoemTaskThread extends Thread {
41
42 Table<?> table;
43
44 PoemTaskThread(Table<?> table) {
45 this.table = table;
46 }
47
48 abstract void run_() throws Exception;
49
50 public void run() {
51
52 table.getDatabase().inSession(AccessToken.root, new PoemTask() {
53 public void run() {
54 try {
55 run_();
56 } catch (Exception e) {
57 throw new UnexpectedExceptionPoemException(e);
58 }
59 }
60 });
61 }
62 }
63
64 static class Setter extends PoemTaskThread {
65
66 static class Signal {
67 }
68
69 static final Signal
70 set = new Signal(){ public String toString() {return "set";}},
71 add = new Signal(){ public String toString() {return "add";}},
72 delete = new Signal() { public String toString() {return "delete";}};
73
74 static Signal[] theSignal = new Signal[1];
75
76 int serial = 0;
77
78 Setter(Table<?> table) {
79 super(table);
80 }
81
82 void signal(Signal signal) {
83 System.err.println("Setter Signal changing from "
84 +theSignal[0] + " to " + signal);
85 synchronized (theSignal) {
86 theSignal[0] = signal;
87 theSignal.notifyAll();
88 }
89 }
90
91 void run_() throws Exception {
92 System.err.println("Setter thread name: "+ (int)Thread.currentThread().getName().charAt(0));
93 for (;;) {
94 synchronized (theSignal) {
95 theSignal.wait();
96 }
97
98 if (theSignal[0] == set) {
99 String fieldContent = "setWhatsit" + (serial++);
100 StringField t = (StringField)table.firstSelection(null);
101 if (t == null) {
102 System.out.println("\n*** setter: nothing to set\n");
103 synchronized (theResult) {
104 theResult += "\nNULL" + fieldContent;
105 }
106 } else {
107 System.out.println("\n*** setter: setting " + fieldContent);
108 t.setStringfield(fieldContent);
109 synchronized (theResult) {
110 theResult += "\n" + fieldContent;
111 }
112 }
113 } else if (theSignal[0] == add) {
114 String fieldContent = "addedWhatsit" + (serial++);
115 System.out.println("*** setter: adding " + fieldContent);
116 StringField t = (StringField)table.newPersistent();
117 t.setStringfield(fieldContent);
118 t.makePersistent();
119 synchronized (theResult) {
120 theResult += "\n" + fieldContent;
121 }
122 } else if (theSignal[0] == delete) {
123 StringField t = (StringField)table.firstSelection(null);
124 if (t == null) {
125 System.out.println("\n*** setter: nothing to delete");
126 synchronized (theResult) {
127 theResult += "\nempty delete";
128 }
129 } else {
130 System.out.println("*** setter: deleting");
131 t.delete_unsafe();
132 System.out.println("*** setter: done deleting");
133 synchronized (theResult) {
134 theResult += "\ndelete";
135 }
136 }
137 } else if (theSignal[0] == null) {
138 System.out.println("\n*** setter done");
139 break;
140 } else fail("WTF");
141
142 PoemThread.commit();
143 }
144 PoemThread.commit();
145 }
146 }
147
148 static class Getter extends PoemTaskThread {
149
150 static Object[] theSignal = new Object[1];
151
152 CachedSelection<?> cachedSelection;
153
154 @SuppressWarnings({ "rawtypes", "unchecked" })
155 Getter(Table<?> table) {
156 super(table);
157 cachedSelection = new CachedSelection(table, null, null, null);
158 }
159
160 void signal(Object signal) throws Exception {
161 System.err.println("Getter Signal changing from "
162 +theSignal[0] + " to " + signal);
163 synchronized (theSignal) {
164 theSignal[0] = signal;
165 theSignal.notifyAll();
166 }
167 }
168
169 void run_() throws Exception {
170 System.err.println("Getter thread name: "+ (int)Thread.currentThread().getName().charAt(0));
171 for (;;) {
172 synchronized (theSignal) {
173 theSignal.wait();
174 }
175
176 if (theSignal[0] == null) {
177 System.out.println("\n*** getter done\n");
178 signal("done");
179 break;
180 } else {
181 System.out.println("\n*** getter:");
182 Enumeration<?> them = cachedSelection.objects();
183
184 System.out.print("** got\n");
185 synchronized (theResult) {
186 theResult += "\ngot";
187 }
188
189 synchronized (theResult) {
190 while (them.hasMoreElements()) {
191 String s = " "
192 + ((StringField)them.nextElement()).getStringfield();
193 theResult += s;
194
195 }
196 }
197
198 }
199 PoemThread.commit();
200 }
201 PoemThread.commit();
202 }
203 }
204
205
206
207
208
209 public void testThem() throws Exception {
210 System.err.println("Start of test method");
211 theResult = "";
212
213 Setter setter = new Setter(db.getStringFieldTable());
214 Getter getter = new Getter(db.getStringFieldTable());
215
216 setter.start();
217 getter.start();
218
219 try {
220 Thread.sleep(nap());
221 setter.signal(Setter.add);
222 Thread.sleep(nap());
223 getter.signal(Boolean.TRUE);
224 Thread.sleep(nap());
225 getter.signal(Boolean.TRUE);
226 Thread.sleep(nap());
227 setter.signal(Setter.set);
228 Thread.sleep(nap());
229 getter.signal(Boolean.TRUE);
230 Thread.sleep(nap());
231 getter.signal(Boolean.TRUE);
232 Thread.sleep(nap());
233 setter.signal(Setter.add);
234 Thread.sleep(nap());
235 getter.signal(Boolean.TRUE);
236 Thread.sleep(nap());
237 getter.signal(Boolean.TRUE);
238 Thread.sleep(nap());
239 setter.signal(Setter.delete);
240 Thread.sleep(nap());
241 getter.signal(Boolean.TRUE);
242 Thread.sleep(nap());
243 getter.signal(Boolean.TRUE);
244 Thread.sleep(nap());
245 setter.signal(Setter.delete);
246 Thread.sleep(nap());
247 getter.signal(Boolean.TRUE);
248 Thread.sleep(nap());
249 getter.signal(Boolean.TRUE);
250 Thread.sleep(nap());
251
252 System.err.println(getDb().getFreeTransactionsCount() + "!=" + (getDb().transactionsMax() -1));
253 setter.signal(null);
254 getter.signal(null);
255 int max = getDb().transactionsMax() -1;
256 int trans = getDb().getFreeTransactionsCount();
257 while(trans != max) {
258 Thread.sleep(1000);
259 System.err.println("Slept because free transactions = " + trans);
260 trans = getDb().getFreeTransactionsCount();
261 }
262 } catch (Exception e) {
263 e.printStackTrace();
264 fail();
265 }
266 System.err.println("End of test method");
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 }
287
288 private int nap() {
289 Random generator = new Random();
290 int it = generator.nextInt(80);
291
292 return it;
293 }
294 }