com.skymobi.monitor.service.TaskService.java Source code

Java tutorial

Introduction

Here is the source code for com.skymobi.monitor.service.TaskService.java

Source

/**
 * Copyright (C) 2012 skymobi LTD
 *
 * Licensed under GNU GENERAL PUBLIC LICENSE  Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/licenses/gpl-3.0.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.skymobi.monitor.service;

import com.google.common.collect.Maps;
import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import com.skymobi.monitor.model.Project;
import com.skymobi.monitor.model.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @author Hill.Hu
 */
@SuppressWarnings("unchecked")
public class TaskService {
    private static Logger logger = LoggerFactory.getLogger(TaskService.class);
    private ConcurrentTaskScheduler executor = new ConcurrentTaskScheduler();
    private final static Map<String, ScheduledFuture> futures = Maps.newHashMap();

    public void scheduledTask(final Project project, final Task task) {
        final String projectName = project.getName();
        //first,cancel old task
        removeScheduled(projectName, task);
        String taskKey = getTaskKey(projectName, task);
        ScheduledFuture<?> future = executor.schedule(new Runnable() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();
                try {
                    FutureTask _fuFutureTask = TaskService.this.runScript(task.getScript(), project);
                    _fuFutureTask.get(task.getTimeout(), TimeUnit.SECONDS);
                } catch (TimeoutException e) {
                    logger.error("execute task timeout,use  {} (second), project={} , script={}",
                            new Object[] { (System.currentTimeMillis() - startTime) / 1000, projectName, task });
                } catch (Exception e) {
                    logger.error("execute task ERROR,use  {} (second), project={} , script={}",
                            new Object[] { (System.currentTimeMillis() - startTime) / 1000, projectName, task });
                    logger.error("execute task fail", e);
                }
                logger.info("execute task success,use {} (second) , project={} , taskName={}", new Object[] {
                        (System.currentTimeMillis() - startTime) / 1000, projectName, task.getName() });
            }
        }, new CronTrigger(task.getCron()));
        logger.info("add a new task {}", taskKey);
        futures.put(taskKey, future);
    }

    public FutureTask<CommandResult> runScript(final String script, final Project project) {
        FutureTask<CommandResult> _fuFutureTask = new FutureTask(new Callable() {

            @Override
            public CommandResult call() throws Exception {

                logger.debug("run mongo script = {}", script);
                CommandResult result = project.fetchMongoTemplate().getDb().doEval(script,
                        new BasicDBObject().append("nolock", true));
                logger.debug("mongo task response {}", result);
                return result;
            }
        });
        executor.submit(_fuFutureTask);
        return _fuFutureTask;
    }

    private String getTaskKey(String projectName, Task task) {
        return projectName + "_" + task.getName();
    }

    public void removeScheduled(String projectName, Task task) {
        String taskKey = getTaskKey(projectName, task);
        if (futures.containsKey(taskKey)) {
            logger.info("remove old task {}", taskKey);
            futures.get(taskKey).cancel(true);
        }

    }

    public void startTasks(Project project) {
        try {
            logger.info("start task of project {}", project.getName());
            for (final Task task : project.getTasks()) {
                logger.debug("schedule task {} ,cron ={}", task.getName(), task.getCron());
                scheduledTask(project, task);
            }
        } catch (Exception e) {
            logger.error("start task of  project fail name={} {}", project.getName(), e);
        }
    }

    public void setExecutor(ConcurrentTaskScheduler executor) {
        this.executor = executor;
    }
}