Untitled

 avatar
unknown
plain_text
6 months ago
2.7 kB
2
Indexable
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;

@RestController
@RequestMapping("/api/tasks")
public class TaskController {

    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private final ConcurrentHashMap<String, Future<?>> tasks = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, StringBuilder> logs = new ConcurrentHashMap<>();

    @PostMapping("/execute")
    public String executeScript(@RequestParam String scriptPath) {
        // Prevent duplicate execution of the same script
        if (tasks.containsKey(scriptPath)) {
            return "Another instance of this script is already running.";
        }

        String taskId = generateTaskId();
        Future<?> future = executorService.submit(() -> {
            StringBuilder logBuilder = new StringBuilder();
            logs.put(taskId, logBuilder);

            try {
                ProcessBuilder processBuilder = new ProcessBuilder(scriptPath);
                Process process = processBuilder.start();
                BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

                String line;
                while ((line = reader.readLine()) != null) {
                    logBuilder.append(line).append("\n");
                }

                process.waitFor();
            } catch (Exception e) {
                logBuilder.append("Error: ").append(e.getMessage());
            } finally {
                tasks.remove(scriptPath);
            }
        });

        tasks.put(scriptPath, future);
        return taskId;
    }

    @PostMapping("/stop/{taskId}")
    public String stopScript(@PathVariable String taskId) {
        // Note: Stopping by taskId assumes you've implemented taskId-to-scriptPath mapping
        // This needs to be tracked to enable stopping by taskId effectively
        // You might need to adapt this part based on your specific requirements.
        
        Future<?> future = tasks.get(taskId); // Adjust based on how you manage taskId
        if (future != null) {
            future.cancel(true);
            tasks.remove(taskId);
            logs.remove(taskId);
            return "Task " + taskId + " stopped.";
        }
        return "Task not found.";
    }

    @GetMapping("/logs/{taskId}")
    public String getLogs(@PathVariable String taskId) {
        StringBuilder log = logs.get(taskId);
        return log != null ? log.toString() : "No logs found for task ID: " + taskId;
    }

    private String generateTaskId() {
        return String.valueOf(System.currentTimeMillis());
    }
}
Editor is loading...
Leave a Comment