Skip to content
This repository was archived by the owner on Dec 15, 2021. It is now read-only.

Commit e527196

Browse files
author
Ken Young
committed
Add repro project for SPR-9575
1 parent bb925df commit e527196

16 files changed

+612
-17
lines changed

SPR-9575/pom.xml

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,23 @@
5858
<scope>runtime</scope>
5959
</dependency>
6060

61+
<dependency>
62+
<groupId>com.google.guava</groupId>
63+
<artifactId>guava</artifactId>
64+
<version>12.0</version>
65+
</dependency>
66+
67+
<dependency>
68+
<groupId>ro.isdc.wro4j</groupId>
69+
<artifactId>wro4j-core</artifactId>
70+
<version>1.4.6</version>
71+
</dependency>
72+
<dependency>
73+
<groupId>ro.isdc.wro4j</groupId>
74+
<artifactId>wro4j-extensions</artifactId>
75+
<version>1.4.6</version>
76+
</dependency>
77+
6178
<!-- Servlet API -->
6279
<dependency>
6380
<groupId>javax.servlet</groupId>
@@ -66,7 +83,7 @@
6683
<scope>provided</scope>
6784
</dependency>
6885

69-
<!-- JSP API and JSTL
86+
<!-- JSP API and JSTL -->
7087
<dependency>
7188
<groupId>javax.servlet.jsp</groupId>
7289
<artifactId>jsp-api</artifactId>
@@ -78,7 +95,9 @@
7895
<artifactId>jstl</artifactId>
7996
<version>1.2</version>
8097
</dependency>
81-
-->
98+
99+
100+
82101

83102
<!-- Apache Tiles
84103
<dependency>
@@ -134,13 +153,13 @@
134153
</dependency>
135154
-->
136155

137-
<!-- Jackson JSON Processor
156+
<!-- Jackson JSON Processor-->
138157
<dependency>
139158
<groupId>org.codehaus.jackson</groupId>
140159
<artifactId>jackson-mapper-asl</artifactId>
141160
<version>1.8.1</version>
142161
</dependency>
143-
-->
162+
144163

145164
<!-- Rome Atom+RSS
146165
<dependency>

SPR-9575/src/main/java/org/springframework/issues/AsyncProcess.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class AsyncProcess implements AsyncProcessInterface {
1616
*/
1717
//("portalAsyncExecutor")
1818

19-
@Async(value="portalPoolTaskExecutor")
19+
@Async("portalPoolTaskExecutor")
2020
public Future<String> findBalanceAsync(final String account) {
2121
long startTime = System.currentTimeMillis();
2222

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.springframework.issues;
2+
3+
4+
import java.util.concurrent.ExecutionException;
5+
import java.util.concurrent.Future;
6+
import java.util.concurrent.TimeUnit;
7+
import java.util.concurrent.TimeoutException;
8+
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.beans.factory.annotation.Qualifier;
11+
import org.springframework.stereotype.Service;
12+
13+
14+
15+
16+
@Service("asyncService")
17+
public class AsyncService {
18+
//@Qualifier("asyncProcessCopy")
19+
@Autowired
20+
@Qualifier("asyncProcess")
21+
private AsyncProcessInterface asyncProcess;
22+
23+
24+
25+
@Autowired
26+
@Qualifier("portletCache")
27+
private PortletCacheInterface portletCache;
28+
29+
public ResultDto findBalanceAsync(String targetDiv) throws Exception {
30+
31+
Future<String> future;
32+
ResultDto dto = new ResultDto();
33+
future = portletCache.get(targetDiv);
34+
if (future==null) {
35+
future = asyncProcess.findBalanceAsync(targetDiv);
36+
portletCache.put(targetDiv, future);
37+
}
38+
String result = "";
39+
try {
40+
result = future.get(3, TimeUnit.SECONDS);
41+
dto.setContent(result);
42+
dto.setProcessCode(ResultCode.COMPLETE);
43+
portletCache.remove(targetDiv);
44+
} catch (InterruptedException e) {
45+
e.printStackTrace();
46+
dto.setProcessCode(ResultCode.ERROR);
47+
} catch (ExecutionException e) {
48+
e.printStackTrace();
49+
dto.setProcessCode(ResultCode.ERROR);
50+
} catch (TimeoutException e) {
51+
result = "Processing ...";
52+
dto.setContent(result);
53+
dto.setProcessCode(ResultCode.PROCESSING);
54+
55+
}
56+
long size = portletCache.getSize();
57+
System.out.println("Cache Size: "+size+"; Result: "+result);
58+
59+
return dto;
60+
}
61+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.springframework.issues;
2+
3+
import java.util.concurrent.Callable;
4+
import java.util.concurrent.Future;
5+
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.beans.factory.annotation.Qualifier;
8+
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
9+
import org.springframework.stereotype.Component;
10+
11+
12+
13+
14+
@Component("asyncProcessCopy")
15+
public class CopyOfAsyncProcess implements AsyncProcessInterface {
16+
17+
@Autowired
18+
@Qualifier("portalAsyncExecutor")
19+
ThreadPoolTaskExecutor taskExecutor;
20+
21+
public Future<String> findBalanceAsync(final String account) {
22+
return taskExecutor.submit(new CopyOfAsyncTask(account));
23+
24+
}
25+
26+
private class CopyOfAsyncTask implements Callable<String> {
27+
28+
private String account;
29+
30+
CopyOfAsyncTask(String account) {
31+
this.account = account;
32+
}
33+
34+
35+
public String call() throws Exception {
36+
long startTime = System.currentTimeMillis();
37+
38+
String threadName = Thread.currentThread().getName();
39+
40+
long t = System.currentTimeMillis();
41+
long end = t + 10000;// 15 seconds
42+
if (account.equals("portlet2")) {
43+
end = t + 45000;
44+
}
45+
while (System.currentTimeMillis() < end) {
46+
// do something
47+
// pause to avoid churning
48+
49+
}
50+
long endTime = System.currentTimeMillis();
51+
String balance = Long.valueOf(endTime).toString()+" : "+threadName;
52+
System.out.println(threadName + " completes Async processing : "
53+
+ (endTime - startTime) / 1000 + " seconds for " + account);
54+
return balance;
55+
56+
}
57+
58+
}
59+
60+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package org.springframework.issues;
2+
3+
import java.util.concurrent.Future;
4+
import java.util.concurrent.TimeUnit;
5+
6+
import javax.annotation.PostConstruct;
7+
8+
import org.springframework.jmx.export.annotation.ManagedAttribute;
9+
import org.springframework.jmx.export.annotation.ManagedOperation;
10+
import org.springframework.jmx.export.annotation.ManagedResource;
11+
import org.springframework.stereotype.Component;
12+
13+
14+
import com.google.common.cache.Cache;
15+
import com.google.common.cache.CacheBuilder;
16+
17+
18+
19+
@Component("portletCache")
20+
@ManagedResource(objectName="bean:name=PortletCacheBean", description="PortalCache Bean")
21+
public class PortletCache implements PortletCacheInterface {
22+
23+
24+
25+
26+
private Cache<String,Future<String>> cache;
27+
28+
29+
/* (non-Javadoc)
30+
* @see com.solutionary.cache.PortletCacheInterface#exists(java.lang.String)
31+
*/
32+
33+
public boolean exists(String key){
34+
35+
return cache.getIfPresent(key)!=null;
36+
}
37+
38+
/* (non-Javadoc)
39+
* @see com.solutionary.cache.PortletCacheInterface#get(java.lang.String)
40+
*/
41+
42+
public Future<String> get(String key){
43+
return cache.getIfPresent(key);
44+
}
45+
46+
/* (non-Javadoc)
47+
* @see com.solutionary.cache.PortletCacheInterface#put(java.lang.String, java.util.concurrent.Future)
48+
*/
49+
50+
public void put(String key, Future<String> future){
51+
cache.put(key, future);
52+
}
53+
54+
/* (non-Javadoc)
55+
* @see com.solutionary.cache.PortletCacheInterface#getSize()
56+
*/
57+
58+
@ManagedAttribute(description="Cache Size")
59+
public long getSize(){
60+
return cache.size();
61+
}
62+
63+
64+
/* (non-Javadoc)
65+
* @see com.solutionary.cache.PortletCacheInterface#cleanUp()
66+
*/
67+
68+
@ManagedOperation(description="Flush Cache")
69+
public void cleanUp(){
70+
cache.cleanUp();
71+
}
72+
73+
/* (non-Javadoc)
74+
* @see com.solutionary.cache.PortletCacheInterface#initialize()
75+
*/
76+
77+
@PostConstruct
78+
public void initialize() {
79+
PortletCacheListener listener = new PortletCacheListener();
80+
cache = CacheBuilder.newBuilder().concurrencyLevel(4).softValues().maximumSize(60).removalListener(listener).expireAfterWrite(2, TimeUnit.MINUTES).build();
81+
82+
}
83+
84+
/* (non-Javadoc)
85+
* @see com.solutionary.cache.PortletCacheInterface#remove(java.lang.String)
86+
*/
87+
88+
public void remove(String targetDiv) {
89+
cache.invalidate(targetDiv);
90+
91+
92+
}
93+
94+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.springframework.issues;
2+
3+
import java.util.concurrent.Future;
4+
5+
public interface PortletCacheInterface {
6+
7+
void remove(String targetDiv);
8+
9+
long getSize();
10+
11+
void put(String targetDiv, Future<String> future);
12+
13+
Future<String> get(String targetDiv);
14+
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.springframework.issues;
2+
3+
import com.google.common.cache.RemovalListener;
4+
import com.google.common.cache.RemovalNotification;
5+
6+
public class PortletCacheListener implements RemovalListener<String,Object> {
7+
8+
9+
public void onRemoval(RemovalNotification<String, Object> arg0) {
10+
System.out.println(arg0.getKey() + " has been altered");
11+
}
12+
13+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package org.springframework.issues;
2+
3+
import javax.servlet.http.HttpServletRequest;
4+
import javax.servlet.http.HttpServletResponse;
5+
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.beans.factory.annotation.Qualifier;
8+
import org.springframework.cache.ehcache.EhCacheCacheManager;
9+
import org.springframework.stereotype.Controller;
10+
import org.springframework.ui.Model;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
import org.springframework.web.bind.annotation.RequestParam;
13+
import org.springframework.web.bind.annotation.ResponseBody;
14+
15+
16+
17+
18+
19+
20+
21+
22+
23+
24+
@Controller
25+
public class PortletController {
26+
27+
28+
@Autowired
29+
@Qualifier("asyncService")
30+
private AsyncService asyncService;
31+
32+
33+
34+
35+
@RequestMapping(value = "/async.mvc")
36+
public String async(Model model) {
37+
38+
return "general.definition.async";
39+
}
40+
41+
@RequestMapping(value = "/getAsync.mvc")
42+
public @ResponseBody
43+
ResultDto getAsync(
44+
@RequestParam(value = "portalWidth", required = false) String width,
45+
@RequestParam(value = "targetDiv", required = true) String targetDiv,
46+
HttpServletRequest request, HttpServletResponse response,
47+
Model model) {
48+
String threadName = Thread.currentThread().getName();
49+
50+
51+
ResultDto dto = new ResultDto();
52+
try {
53+
dto = asyncService.findBalanceAsync(targetDiv);
54+
} catch (Exception e) {
55+
// TODO Auto-generated catch block
56+
e.printStackTrace();
57+
58+
dto.setContent(e.getMessage());
59+
dto.setProcessCode(ResultCode.ERROR);
60+
}
61+
62+
return dto;
63+
}
64+
65+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.springframework.issues;
2+
3+
public enum ResultCode {
4+
COMPLETE,PROCESSING,ERROR
5+
}

0 commit comments

Comments
 (0)