1 |
| package org.jboss.cache.loader; |
2 |
| |
3 |
| import junit.framework.TestCase; |
4 |
| import org.jboss.cache.CacheException; |
5 |
| import org.jboss.cache.CacheImpl; |
6 |
| import org.jboss.cache.DefaultCacheFactory; |
7 |
| import org.jboss.cache.Fqn; |
8 |
| import org.jboss.cache.Modification; |
9 |
| import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig; |
10 |
| |
11 |
| import java.io.ObjectInputStream; |
12 |
| import java.io.ObjectOutputStream; |
13 |
| import java.util.ArrayList; |
14 |
| import java.util.Collection; |
15 |
| import java.util.Collections; |
16 |
| import java.util.Iterator; |
17 |
| import java.util.List; |
18 |
| import java.util.Map; |
19 |
| import java.util.Set; |
20 |
| |
21 |
| |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| |
27 |
| |
28 |
| |
29 |
| public class InterceptorSynchronizationTest extends TestCase |
30 |
| { |
31 |
| |
32 |
| final int CACHELOADER_WAITTIME = 2000; |
33 |
| final int numThreadsPerTopLevelNode = 5; |
34 |
| |
35 |
| |
36 |
1
| public void testBlockingProblem() throws Exception
|
37 |
| { |
38 |
| |
39 |
1
| CacheImpl cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
|
40 |
1
| cache.setCacheLoader(new TestSlowCacheLoader());
|
41 |
1
| cache.start();
|
42 |
| |
43 |
1
| long begin = System.currentTimeMillis();
|
44 |
1
| Collection threads = new ArrayList();
|
45 |
| |
46 |
| |
47 |
| |
48 |
| |
49 |
| |
50 |
1
| for (int i = 0; i < numThreadsPerTopLevelNode; i++)
|
51 |
| { |
52 |
5
| Thread thread = new Thread(new Retriever(cache, "/Moo/" + i));
|
53 |
5
| threads.add(thread);
|
54 |
5
| Thread thread2 = new Thread(new Retriever(cache, "/Meow/" + i));
|
55 |
5
| threads.add(thread2);
|
56 |
| } |
57 |
1
| for (Iterator iter = threads.iterator(); iter.hasNext();)
|
58 |
| { |
59 |
10
| Thread thread = (Thread) iter.next();
|
60 |
10
| thread.start();
|
61 |
| |
62 |
| } |
63 |
1
| for (Iterator iter = threads.iterator(); iter.hasNext();)
|
64 |
| { |
65 |
10
| Thread thread = (Thread) iter.next();
|
66 |
10
| thread.join();
|
67 |
| } |
68 |
| |
69 |
1
| long end = System.currentTimeMillis();
|
70 |
1
| long timeTaken = (end - begin);
|
71 |
| |
72 |
| |
73 |
| |
74 |
| |
75 |
| |
76 |
| |
77 |
| |
78 |
1
| int totalTimeExpectedToWaitIfNotSerialized = 3 * CACHELOADER_WAITTIME;
|
79 |
1
| assertTrue("If it was parallel, it should have finished quicker than this:" + timeTaken, timeTaken < totalTimeExpectedToWaitIfNotSerialized);
|
80 |
| } |
81 |
| |
82 |
| |
83 |
| |
84 |
| |
85 |
| |
86 |
| |
87 |
| public class TestSlowCacheLoader extends AbstractCacheLoader |
88 |
| { |
89 |
0
| public void setConfig(IndividualCacheLoaderConfig config)
|
90 |
| { |
91 |
| } |
92 |
| |
93 |
0
| public IndividualCacheLoaderConfig getConfig()
|
94 |
| { |
95 |
0
| return null;
|
96 |
| } |
97 |
| |
98 |
0
| public Set getChildrenNames(Fqn arg0) throws Exception
|
99 |
| { |
100 |
0
| return null;
|
101 |
| } |
102 |
| |
103 |
0
| public Object get(Fqn arg0, Object arg1) throws Exception
|
104 |
| { |
105 |
0
| return null;
|
106 |
| } |
107 |
| |
108 |
10
| public Map get(Fqn arg0) throws Exception
|
109 |
| { |
110 |
10
| Thread.sleep(CACHELOADER_WAITTIME);
|
111 |
10
| return Collections.singletonMap("foo", "bar");
|
112 |
| } |
113 |
| |
114 |
0
| public boolean exists(Fqn arg0) throws Exception
|
115 |
| { |
116 |
0
| return true;
|
117 |
| } |
118 |
| |
119 |
0
| public Object put(Fqn arg0, Object arg1, Object arg2) throws Exception
|
120 |
| { |
121 |
0
| return null;
|
122 |
| } |
123 |
| |
124 |
0
| public void put(Fqn arg0, Map arg1) throws Exception
|
125 |
| { |
126 |
| |
127 |
| } |
128 |
| |
129 |
0
| public void put(List<Modification> modifications) throws Exception
|
130 |
| { |
131 |
| } |
132 |
| |
133 |
0
| public Object remove(Fqn arg0, Object arg1) throws Exception
|
134 |
| { |
135 |
0
| return null;
|
136 |
| } |
137 |
| |
138 |
0
| public void remove(Fqn arg0) throws Exception
|
139 |
| { |
140 |
| |
141 |
| } |
142 |
| |
143 |
0
| public void removeData(Fqn arg0) throws Exception
|
144 |
| { |
145 |
| |
146 |
| } |
147 |
| |
148 |
0
| public void prepare(Object tx, List<Modification> modifications, boolean one_phase) throws Exception
|
149 |
| { |
150 |
| } |
151 |
| |
152 |
0
| public void commit(Object arg0) throws Exception
|
153 |
| { |
154 |
| |
155 |
| } |
156 |
| |
157 |
0
| public void rollback(Object arg0)
|
158 |
| { |
159 |
| } |
160 |
| |
161 |
| |
162 |
| |
163 |
| |
164 |
| |
165 |
| |
166 |
| |
167 |
| |
168 |
| |
169 |
| |
170 |
| |
171 |
| |
172 |
| |
173 |
| |
174 |
| |
175 |
| |
176 |
| |
177 |
| |
178 |
0
| public void loadEntireState(ObjectOutputStream os) throws Exception
|
179 |
| { |
180 |
| |
181 |
| } |
182 |
| |
183 |
0
| public void loadState(Fqn subtree, ObjectOutputStream os) throws Exception
|
184 |
| { |
185 |
| |
186 |
| } |
187 |
| |
188 |
0
| public void storeEntireState(ObjectInputStream is) throws Exception
|
189 |
| { |
190 |
| |
191 |
| } |
192 |
| |
193 |
0
| public void storeState(Fqn subtree, ObjectInputStream is) throws Exception
|
194 |
| { |
195 |
| |
196 |
| } |
197 |
| |
198 |
1
| public void create() throws Exception
|
199 |
| { |
200 |
| |
201 |
| } |
202 |
| |
203 |
1
| public void start() throws Exception
|
204 |
| { |
205 |
| |
206 |
| } |
207 |
| |
208 |
0
| public void stop()
|
209 |
| { |
210 |
| |
211 |
| } |
212 |
| |
213 |
0
| public void destroy()
|
214 |
| { |
215 |
| |
216 |
| } |
217 |
| |
218 |
| } |
219 |
| |
220 |
| |
221 |
| private static class Retriever implements Runnable |
222 |
| { |
223 |
| private final String fqn; |
224 |
| private CacheImpl cache; |
225 |
| |
226 |
10
| private Retriever(CacheImpl cache, String fqn)
|
227 |
| { |
228 |
10
| this.fqn = fqn;
|
229 |
10
| this.cache = cache;
|
230 |
| } |
231 |
| |
232 |
10
| public void run()
|
233 |
| { |
234 |
10
| try
|
235 |
| { |
236 |
10
| cache.get(fqn, "foo");
|
237 |
| } |
238 |
| catch (CacheException e) |
239 |
| { |
240 |
0
| throw new RuntimeException("Unexpected", e);
|
241 |
| } |
242 |
| |
243 |
| } |
244 |
| } |
245 |
| } |