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