/**
* Copyright (c)2010-2011 Enterprise Website Content Management System(EWCMS), All rights reserved.
* EWCMS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* http://www.ewcms.com
*/
package com.ewcms.publication.task.publish;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ewcms.core.site.model.SiteServer;
import com.ewcms.publication.task.TaskException;
import com.ewcms.publication.task.Taskable;
import com.ewcms.publication.task.impl.process.TaskProcessable;
/**
* 实现多线程站点任务发布
*
* @author wangwei
*/
public class SiteMultiPublish extends SitePublish{
private static final Logger logger = LoggerFactory.getLogger(SiteMultiPublish.class);
private static final int DEFAULT_TASK_NUMBER = 4;
private List<Future<Boolean>> tasks;
private final ExecutorService executorService;
public SiteMultiPublish(SiteServer server) {
this(server, DEFAULT_TASK_NUMBER);
}
public SiteMultiPublish(SiteServer server, int taskNumber) {
super(server);
this.executorService = Executors.newFixedThreadPool(taskNumber);
}
private List<Future<Boolean>> submitTaskProcesses(
CompletionService<Boolean> completionService,
List<TaskProcessable> processes) throws TaskException {
tasks = new ArrayList<Future<Boolean>>();
for (final TaskProcessable process : processes) {
Future<Boolean> task= completionService.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return process.execute(operator);
}
});
tasks.add(task);
}
return tasks;
}
@Override
protected void execute(Taskable task)throws TaskException{
List<TaskProcessable> processes = task.toTaskProcess();
CompletionService<Boolean> completionService =
new ExecutorCompletionService<Boolean>(executorService);
submitTaskProcesses(completionService,processes);
try{
int count = processes.size();
for(int i = 0 ; i < count ; i++){
Future<Boolean> f = completionService.take();
Boolean success = f.get();
logger.debug("publish success is {}",success);
}
}catch(InterruptedException e){
logger.error("publish is fail,{} ",e.toString());
Thread.currentThread().interrupt();
}catch(ExecutionException e){
Throwable t = e.getCause();
if(t instanceof RuntimeException){
logger.error("publish is RuntimeException,{} ",e.toString());
throw (RuntimeException)t;
}else if(t instanceof Error){
logger.error("publish is Error,{} ",e.toString());
throw (Error)t;
}else{
throw new IllegalStateException("Not unchecked",t);
}
}finally{
tasks = null;
}
}
@Override
public void cancelPublish() {
if(tasks != null){
for(Future<Boolean> t : tasks){
if(t.isCancelled() || t.isDone()){
continue;
}
t.cancel(false);
}
}
}
}