package recreationaltech.plugin import groovy.util.logging.Slf4j import java.nio.file.Files import java.nio.file.Path /** * Provides runtime estimates for tasks based on task-name and input file size */ @Slf4j abstract class K8sRuntimeEstimator { /** * Returns an estimation of the task runtime in milliseconds * @param handler the task handler * @return estimated task runtime in milliseconds OR infinity if the task is unknown. */ double estimate(K8sTaskHandler handler) { long x = getTaskHandlerInputSize(handler) return estimate(handler.task.processor.name, x) } /** * Returns an estimation of the task runtime in milliseconds * @param taskName the name of the task * @param inputSize the total input size in bytes * @return estimated task runtime in milliseconds OR infinity if the task is unknown. */ abstract double estimate(String taskName, long inputSize); protected long getTaskHandlerInputSize(K8sTaskHandler handler) { long inputSizeSum = 0 // File input def inputFiles = handler.task.getInputFilesMap() for (Map.Entry f : inputFiles) { try { inputSizeSum += Files.size(f.value) } catch (IOException ex) { log.error "[K8s] failed to get size of input file ${f.value} of task ${task.task.name}: ${ex.message}" } } // Non file input def inputs = handler.task.getInputs() for (Map.Entry i : inputs) { inputSizeSum += i.value.toString().length() } return inputSizeSum } /// @brief Parses the runtime recording data file /// @return Map from task name to list of recordings, where each recording is a tuple (input-size, runtime-in-ms) protected HashMap>> parseDataFile(String dataFilePath) { HashMap>> data = new HashMap<>(); try { BufferedReader reader = new BufferedReader(new FileReader(dataFilePath)) String line = reader.readLine() while (line != null) { // ,, String[] elems = line.split(",") if (elems.length != 3) { log.warn "[K8s] ${dataFilePath}: Unexpected line ${line}" continue } ArrayList> taskData = data.get(elems[0]) if (taskData == null) { taskData = new ArrayList<>() data.put(elems[0], taskData) } try { taskData.add(new Tuple2(Long.parseLong(elems[1]), Long.parseLong(elems[2]))) } catch (NumberFormatException ex) { log.error "[K8s] ${dataFilePath} invalid data: ${ex.message}" } line = reader.readLine() } reader.close() } catch (IOException ex) { log.error "[K8s] Failed to load ${dataFilePath}: ${ex.message}" } return data } }