/**
* 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;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ewcms.publication.task.impl.NoneTask;
import com.ewcms.publication.task.impl.process.TaskProcessable;
import com.ewcms.publication.task.publish.SitePublishable;
/**
* 实现任务运行,任务按照先进先出顺序运行。
*
* @author wangwei
*/
public class QueueSiteTaskRunner implements SiteTaskRunnerable{
private static final Logger logger = LoggerFactory.getLogger(QueueSiteTaskRunner.class);
protected final LinkedBlockingQueue<Taskable> queue = new LinkedBlockingQueue<Taskable>();
private final SitePublishable sitePublish;
private final Semaphore limit;
private volatile Taskable taskRunning;
private volatile boolean closed = false;
public QueueSiteTaskRunner(SitePublishable sitePublish,Semaphore limit){
this.limit = limit;
this.sitePublish = sitePublish;
}
@Override
public List<Taskable> getTasks() {
List<Taskable> tasks = new ArrayList<Taskable>();
if(taskRunning != null){
tasks.add(new TaskInfoClone(taskRunning));
}
for(Taskable task : queue){
tasks.add(new TaskInfoClone(task));
}
return tasks;
}
private void publish(final Taskable task){
try {
sitePublish.publish(task);
} catch (TaskException e) {
logger.debug("Task published fail:{}",e);
}
}
@Override
public void run() {
logger.info("Site's runner start");
while(true){
try {
taskRunning = queue.take();
if(closed){
taskRunning = null;
break;
}
limit.acquire();
publish(taskRunning);
taskRunning = null;
} catch (InterruptedException e) {
logger.debug("Task runned fail:{}",e);
} finally{
limit.release();
}
}
}
@Override
public void add(Taskable task) {
queue.add(task);
}
@Override
public boolean remov(Taskable task) {
if(task.equals(taskRunning)){
logger.info("Task is running.");
sitePublish.cancelPublish();
taskRunning = null;
return true;
}
return queue.remove(task);
}
@Override
public Taskable get(String id){
logger.info("it will be getting task by {}",id);
for(Taskable task : queue){
if(task.getId() != null && task.getId().equals(id)){
return task;
}
}
if(taskRunning != null ){
logger.info("Task's {} is running ",taskRunning.getId());
if(taskRunning.getId().equals(id)){
return taskRunning;
}
}
return null;
}
public boolean contains(Taskable task){
return queue.contains(task) ||
(taskRunning != null && taskRunning.equals(task));
}
@Override
public void close() {
closed = true;
if(this.taskRunning != null){
sitePublish.cancelPublish();
}
//skip break
if(queue.isEmpty()){
queue.add(new NoneTask());
}
}
class TaskInfoClone implements Taskable{
private final String id;
private final String description;
private final boolean completed;
private final String username;
private final int progress;
private final List<Taskable> dependences = new ArrayList<Taskable>();
public TaskInfoClone(Taskable task){
this.id = task.getId();
this.description = task.getDescription();
this.completed = task.isCompleted();
this.username = task.getUsername();
this.progress = task.getProgress();
if(task.getDependenceTasks() != null && !task.getDependenceTasks().isEmpty()){
for(Taskable d : task.getDependenceTasks()){
TaskInfoClone dc = new TaskInfoClone(d);
dependences.add(dc);
}
}
}
@Override
public String getId() {
return id;
}
@Override
public String getDescription() {
return description;
}
@Override
public String getUsername() {
return username;
}
@Override
public int getProgress() {
return progress;
}
@Override
public boolean isCompleted() {
return completed;
}
@Override
public List<Taskable> getDependenceTasks() {
return dependences;
}
@Override
public List<TaskProcessable> toTaskProcess() throws TaskException {
throw new RuntimeException("it's not instance.");
}
}
}