Перенос.

This commit is contained in:
2023-09-17 22:13:42 +03:00
parent dd2e0ca7e0
commit 629d8b8477
1239 changed files with 61161 additions and 1 deletions

View File

@@ -0,0 +1,110 @@
package GlobalData.Tasks.CompilationTask;
import Common.Current;
import Common.Global;
import Common.Utils.Utils;
import GlobalData.Makefile.Makefile;
import GlobalData.Module.Module;
import GlobalData.Tasks.RunTask.RunTask;
import GlobalData.Tasks.Task;
import ProjectData.Files.DBProjectFile;
import ProjectData.LanguageName;
import ProjectData.Project.db_project_info;
import com.sun.org.glassfish.gmbal.Description;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.LinkedHashMap;
public class CompilationTask extends Task {
public int makefile_id = Utils.Nan;
public String binary_name = ""; //исполняемый файл.
//---------------------------------------------------
@Description("DEFAULT ''")
public String linkerDescription = "";
@Description("DEFAULT ''")
public String linkFlags = "";
//для отображения.
//-------------------
@Description("DEFAULT ''")
public String fortranCompilerDescription = "";
@Description("DEFAULT ''")
public String fortranFlags = "";
//-------------------
@Description("DEFAULT ''")
public String cCompilerDescription = "";
@Description("DEFAULT ''")
public String cFlags = "";
//------------------
@Description("DEFAULT ''")
public String cppCompilerDescription = "";
@Description("DEFAULT ''")
public String cppFlags = "";
//---------------------------------------------------
public void CompleteSummary(int maxtime_in) throws Exception {
maxtime = maxtime_in;
Makefile makefile = getMakefile();
LinkedHashMap<LanguageName, Module> modules = makefile.getModules();
linkerDescription = makefile.getCompilerDescription();
linkFlags = makefile.flags;
for (Module module : modules.values()) {
switch (module.language) {
case fortran:
fortranCompilerDescription = module.getCompilerDescription();
fortranFlags = module.flags;
break;
case c:
cCompilerDescription = module.getCompilerDescription();
cFlags = module.flags;
break;
case cpp:
cppCompilerDescription = module.getCompilerDescription();
cppFlags = module.flags;
break;
}
}
Global.db.Update(this);
}
//---------------------------------------------------
@Override
public File getHome() {
return Global.CompilationTasksDirectory;
}
@Override
public boolean isVisible() {
return
Current.CheckID(Current.Machine, machine_id) &&
Current.CheckID(Current.User, user_id) &&
Current.HasProject() &&
belongsToProject(Current.getProject());
}
public Makefile getMakefile() {
return Global.db.getById(Makefile.class, makefile_id);
}
@Override
public String getFullCommand() {
return "make -j -f Makefile";
}
public LinkedHashMap<Integer, RunTask> getRunTasks() {
LinkedHashMap<Integer, RunTask> res = new LinkedHashMap<>();
//так не получится. не правильно назвал ключевое поле. F...
// return Global.db.getMapByFKi(this, RunTask.class);
for (RunTask runTask : Global.db.runTasks.Data.values()) {
if (runTask.compilation_task_id == id)
res.put(runTask.id, runTask);
}
return res;
}
@Override
public void AnalyzeResultsTexts(db_project_info project) throws Exception {
String output = getOutput();
String errors = getErrors();
for (DBProjectFile file : project.db.files.Data.values()) {
if (!file.last_assembly_name.isEmpty()) {
String replacement = file.last_assembly_name + " " + Utils.RBrackets(file.name);
output = output.replace(file.last_assembly_name, replacement);
errors = errors.replace(file.last_assembly_name, replacement);
}
}
FileUtils.writeStringToFile(getOutputFile(), output);
FileUtils.writeStringToFile(getErrorsFile(), errors);
}
}

View File

@@ -0,0 +1,120 @@
package GlobalData.Tasks.CompilationTask;
import Common.Current;
import Common.Database.*;
import Common.UI.DataSetControlForm;
import Common.UI.Menus.TableMenu;
import Common.UI.UI;
import GlobalData.Tasks.RunTask.RunTask;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import java.util.LinkedHashMap;
import static Common.UI.Tables.TableRenderers.RendererDate;
import static Common.UI.Tables.TableRenderers.RendererStatusEnum;
public class CompilationTasksDBTable extends iDBTable<CompilationTask> {
public CompilationTasksDBTable() {
super(CompilationTask.class);
}
@Override
public String getSingleDescription() {
return "задача на компиляцию";
}
@Override
public String getPluralDescription() {
return "задачи на компиляцию";
}
@Override
public LinkedHashMap<Class<? extends DBObject>, FKBehaviour> getFKDependencies() {
LinkedHashMap<Class<? extends DBObject>, FKBehaviour> res = new LinkedHashMap<>();
res.put(RunTask.class, new FKBehaviour(FKDataBehaviour.DELETE, FKCurrentObjectBehaviuor.ACTIVE));
return res;
}
@Override
protected DataSetControlForm createUI() {
return new DataSetControlForm(this) {
@Override
public boolean hasCheckBox() {
return true;
}
@Override
protected void AdditionalInitColumns() {
columns.get(12).setRenderer(RendererDate);
columns.get(13).setRenderer(RendererStatusEnum);
}
@Override
public void ShowCurrentObject() throws Exception {
super.ShowCurrentObject();
UI.getMainWindow().getTestingWindow().DropRunTasksComparison();
}
@Override
public void ShowNoCurrentObject() throws Exception {
super.ShowNoCurrentObject();
UI.getMainWindow().getTestingWindow().DropRunTasksComparison();
}
@Override
public void CreateControl() {
super.CreateControl();
TableMenu dataTableMenu = new TableMenu(control);
dataTableMenu.add(Pass_2021.passes.get(PassCode_2021.DeleteSelectedCompilationTasks).createMenuItem());
control.setComponentPopupMenu(dataTableMenu);
}
};
}
@Override
public String[] getUIColumnNames() {
return new String[]{
"сборка",
"",
//
"Fortran",
"",
//
"С",
"",
//
"С++",
"",
"Лимит(c)",
"Время(c)",
"Дата",
"Статус"
};
}
@Override
public Object getFieldAt(CompilationTask object, int columnIndex) {
switch (columnIndex) {
case 2:
return object.linkerDescription;
case 3:
return object.linkFlags;
case 4:
return object.fortranCompilerDescription;
case 5:
return object.fortranFlags;
case 6:
return object.cCompilerDescription;
case 7:
return object.cFlags;
case 8:
return object.cppCompilerDescription;
case 9:
return object.cppFlags;
case 10:
return object.maxtime;
case 11:
return object.Time;
case 12:
return object.getEndDate();
case 13:
return object.state;
default:
return null;
}
}
@Override
public Current CurrentName() {
return Current.CompilationTask;
}
}

View File

@@ -0,0 +1,31 @@
package GlobalData.Tasks.Passes;
import Common.Current;
import Common.Global;
import GlobalData.Tasks.Supervisor.TaskSupervisor;
import Visual_DVM_2021.Passes.ProcessPass;
public abstract class TaskLocalPass<S extends TaskSupervisor> extends ProcessPass {
public S supervisor; //инициализация идет в конструкторе потомка.
public TaskLocalPass(Class<S> s_class) {
try {
supervisor = s_class.newInstance();
} catch (Exception e) {
Global.Log.PrintException(e);
}
}
@Override
protected boolean needsAnimation() {
return true;
}
@Override
protected void body() throws Exception {
supervisor.PerformTask();
}
@Override
protected void performFinish() throws Exception {
supervisor.UpdateTask();
}
@Override
public void Interrupt() throws Exception {
Current.getProject().CreateInterruptFile();
}
}

View File

@@ -0,0 +1,16 @@
package GlobalData.Tasks.QueueSystem;
import GlobalData.Tasks.TaskState;
public class MVS extends QueueSystem {
public MVS() {
cancel_command = "mcancel";
check_command = "mqtest";
refuse = "runmvsd: Error on queue task:Sorry, you achieved max task number. Try once more later.";
commands = new QueueCommand[]{
new QueueCommand(TaskState.Queued, "task", "queued successfully"),
new QueueCommand(TaskState.Running, "task", "is in the run"),
new QueueCommand(TaskState.Running, "task", "started successfully"),
new QueueCommand(TaskState.Finished, "task", "complete"),
new QueueCommand(TaskState.NoSuchTask, "", "no such task")
};
}
}

View File

@@ -0,0 +1,10 @@
package GlobalData.Tasks.QueueSystem;
import Common.Utils.StringTemplate;
import GlobalData.Tasks.TaskState;
public class QueueCommand extends StringTemplate {
public TaskState state; //состояние задачи в случае успешного разбора этой команды.
public QueueCommand(TaskState state_in, String p, String s) {
super(p, s);
state = state_in;
}
}

View File

@@ -0,0 +1,36 @@
package GlobalData.Tasks.QueueSystem;
import Common.Utils.Utils;
import GlobalData.Tasks.Task;
import GlobalData.Tasks.TaskState;
public class QueueSystem {
public String check_command;
public String cancel_command;
public String refuse;
QueueCommand[] commands;
public void checkTask(String Output, Task task) {
for (QueueCommand command : commands)
if (command.check(Output)) {
task.state = command.state;
return;
}
}
public void enqueueTask(String Output, Task task) {
if (Output.equalsIgnoreCase(refuse))
task.state = TaskState.FailedToQueue;
else
for (QueueCommand command : commands) {
String c_res = command.check_and_get_param(Output);
if (c_res != null) {
task.PID = c_res.replace("\"", "").replace("'", "");
task.state = command.state;
return;
}
}
}
public String getCheckTaskCommand(Task task) {
return check_command + " " + Utils.DQuotes(task.PID);
}
public String getCancelTaskCommand(Task task) {
return cancel_command + " " + Utils.DQuotes(task.PID);
}
}

View File

@@ -0,0 +1,160 @@
package GlobalData.Tasks.RunTask;
import Common.Current;
import Common.Global;
import Common.Utils.StringTemplate;
import Common.Utils.Utils;
import GlobalData.Compiler.CompilerType;
import GlobalData.RunConfiguration.RunConfiguration;
import GlobalData.Tasks.CompilationTask.CompilationTask;
import GlobalData.Tasks.Task;
import GlobalData.Tasks.TaskState;
import ProjectData.Project.db_project_info;
import TestingSystem.Tasks.TestRunTaskInterface;
import com.sun.org.glassfish.gmbal.Description;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.file.Paths;
import java.util.List;
public class RunTask extends Task {
public int compilation_task_id = Utils.Nan; //нужна для бинарника
public int run_configuration_id = Utils.Nan;
@Description("DEFAULT ''")
public String last_sts_name = "";
@Description("DEFAULT 0")
public double CleanTime;
@Description("IGNORE")
public boolean hasDvmSts = false;
@Description("IGNORE")
public boolean hasGCOV = false;
//-------------------------------------
@Description("DEFAULT ''")
public String matrix = "";
//-------------------------------------
@Override
public void DropResults() throws Exception {
super.DropResults();
Utils.forceDeleteWithCheck(getLocalStsFile());
CleanTime = 0;
Global.db.Update(this);
}
@Override
public File getHome() {
return Global.RunTasksDirectory;
}
@Override
public String getFullCommand() {
return getRunConfiguration().getLaunchScriptText(getCompilationTask().binary_name, matrix);
}
//---------------------------------------
@Override
public boolean isVisible() {
return
Current.CheckID(Current.Machine, machine_id) &&
Current.CheckID(Current.User, user_id) &&
Current.CheckID(Current.RunConfiguration, run_configuration_id) &&
Current.HasProject() &&
belongsToProject(Current.getProject()) &&
Current.HasCompilationTask() &&
compilation_task_id == Current.getCompilationTask().id;
}
public RunConfiguration getRunConfiguration() {
return Global.db.runConfigurations.Data.get(run_configuration_id);
}
public CompilationTask getCompilationTask() {
return Global.db.compilationTasks.Data.get(compilation_task_id);
}
public void UpdateLastStsName(String file_name) {
if (!last_sts_name.equals(file_name)) {
last_sts_name = file_name;
try {
Global.db.Update(this);
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
}
public File getLocalStsFile() {
return Paths.get(getLocalWorkspace().getAbsolutePath(), last_sts_name).toFile();
}
public File getLocalStsTextFile() {
return Paths.get(getLocalWorkspace().getAbsolutePath(), "statistic.txt").toFile();
}
public String getLocalStsText() {
return getTextResult(getLocalStsTextFile());
}
public void parseCleanTime() {
StringTemplate template = new StringTemplate("Time in seconds =", "");
String p = template.check_and_get_param(Utils.ReadAllText(getOutputFile()));
try {
if (p != null) CleanTime = Double.parseDouble(p);
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
@Override
public void AnalyzeOutFile(db_project_info project) throws Exception {
List<String> lines = FileUtils.readLines(getOutputFile());
if (lines.stream().anyMatch(TestRunTaskInterface::isCrushedLine)
) {
state = TaskState.Crushed;
return;
}
//->>
//тест на корректность.
if (!lines.isEmpty() && lines.get(0).toUpperCase().contains("START OF ")) {
int complete = 0;
int errors = 0;
for (int i = 1; i < lines.size(); ++i) {
String line_ = lines.get(i).toUpperCase();
if (line_.endsWith("COMPLETE")) {
complete++;
} else if (line_.endsWith("ERROR")) {
errors++;
} else if (line_.contains("END OF")) {
if (errors > 0) state = TaskState.DoneWithErrors;
else if (complete > 0) state = TaskState.Done;
return;
}
}
}
//тест на производительность.
StringTemplate stringTemplate = new StringTemplate("Verification =", "");
for (String line : lines) {
String param = stringTemplate.check_and_get_param(line);
if (param != null) {
switch (param) {
case "SUCCESSFUL":
state = TaskState.Done;
return;
case "UNSUCCESSFUL":
state = TaskState.DoneWithErrors;
return;
default:
break;
}
}
}
}
@Override
public void AnalyzeErrorsFile(db_project_info project) throws Exception {
List<String> lines = FileUtils.readLines(getErrorsFile());
if (lines.stream().anyMatch(TestRunTaskInterface::isCrushedLine))
state = TaskState.Crushed;
}
@Override
public void Reset() {
super.Reset();
CleanTime = 0.0;
hasDvmSts = false;
hasGCOV = false;
}
public boolean hasDVMPar() {
RunConfiguration config = getRunConfiguration();
return
config.compiler_id != Utils.Nan &&
config.getCompiler().type.equals(CompilerType.dvm) &&
!config.getParList().isEmpty()
;
}
}

View File

@@ -0,0 +1,88 @@
package GlobalData.Tasks.RunTask;
import Common.Current;
import Common.Database.iDBTable;
import Common.UI.DataSetControlForm;
import Common.UI.Menus.TableMenu;
import Common.UI.UI;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import static Common.UI.Tables.TableRenderers.RendererDate;
import static Common.UI.Tables.TableRenderers.RendererStatusEnum;
public class RunTasksDBTable extends iDBTable<RunTask> {
public RunTasksDBTable() {
super(RunTask.class);
}
@Override
public String getSingleDescription() {
return "задача на запуск";
}
@Override
public String getPluralDescription() {
return "задачи на запуск";
}
@Override
protected DataSetControlForm createUI() {
return new DataSetControlForm(this) {
@Override
public boolean hasCheckBox() {
return true;
}
@Override
protected void AdditionalInitColumns() {
columns.get(6).setRenderer(RendererDate);
columns.get(7).setRenderer(RendererStatusEnum);
}
@Override
public void ShowCurrentObject() throws Exception {
super.ShowCurrentObject();
UI.getMainWindow().getTestingWindow().ShowCurrentRunTask();
}
@Override
public void ShowNoCurrentObject() throws Exception {
super.ShowNoCurrentObject();
UI.getMainWindow().getTestingWindow().ShowNoCurrentRunTask();
}
@Override
public void CreateControl() {
super.CreateControl();
TableMenu dataTableMenu = new TableMenu(control);
dataTableMenu.add(Pass_2021.passes.get(PassCode_2021.DeleteSelectedRunTasks).createMenuItem());
control.setComponentPopupMenu(dataTableMenu);
}
};
}
@Override
public String[] getUIColumnNames() {
return new String[]{
"Матрица",
"Лимит(с)",
"Время(с)",
"Чистое время",
"Дата",
"Статус"};
}
@Override
public Object getFieldAt(RunTask object, int columnIndex) {
switch (columnIndex) {
case 2:
return object.matrix;
case 3:
return object.maxtime;
case 4:
return object.Time;
case 5:
return object.CleanTime;
case 6:
return object.getEndDate();
case 7:
return object.state;
default:
return null;
}
}
@Override
public Current CurrentName() {
return Current.RunTask;
}
}

View File

@@ -0,0 +1,42 @@
package GlobalData.Tasks.Supervisor.Local.Linux;
import Common.Utils.Utils;
import GlobalData.Makefile.Makefile;
import GlobalData.Tasks.CompilationTask.CompilationTask;
import GlobalData.Tasks.TaskState;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class LinuxLocalCompilationSupervisor extends LinuxLocalTaskSupervisor<CompilationTask> {
@Override
protected void PrepareWorkspace() throws Exception {
//возможно тут сделать отличие. не удалять все, а тоже сверять по дате и именам..
super.PrepareWorkspace();
Utils.CheckAndCleanDirectory(getProjectCopy());
//скопировать проект в папку. без бд.
project.Clone(getProjectCopy(), false);
//-удалить старый бинарник если есть? бессмысленно если папка и так полностью пересоздается при каждой компиляции.
//по идее надо исправить на синхронизацию.
//if (!task.binary_name.isEmpty()) {
// File old_binary = Paths.get(getProjectCopy().getAbsolutePath(), task.binary_name).toFile();
// FileUtils.forceDelete(old_binary);
// }
//создать мейкфайл.
Makefile makefile = task.getMakefile();
File makefile_text = Paths.get(getProjectCopy().getAbsolutePath(), "Makefile").toFile();
FileUtils.write(makefile_text, makefile.Generate(project));
}
@Override
protected void ValidateTaskResults() throws Exception {
if (getBinary().exists()) {
File renamed_binary = Paths.get(getProjectCopy().getAbsolutePath(),
Utils.getDateName("spf")).toFile();
task.binary_name = renamed_binary.getName();
Files.move(getBinary().toPath(), renamed_binary.toPath(), StandardCopyOption.REPLACE_EXISTING);
task.state = TaskState.Done;
} else task.state = TaskState.DoneWithErrors;
task.AnalyzeResultsTexts(project);
}
}

View File

@@ -0,0 +1,32 @@
package GlobalData.Tasks.Supervisor.Local.Linux;
import Common.Current;
import GlobalData.Tasks.RunTask.RunTask;
import java.util.Map;
public class LinuxLocalRunSupervisor extends LinuxLocalTaskSupervisor<RunTask> {
@Override
protected void PrepareWorkspace() throws Exception {
super.PrepareWorkspace();
PrepareRunTaskWorkspace(task);
}
@Override
protected void AchieveResults() throws Exception {
super.AchieveResults();
AchieveRunTaskResults(task);
}
@Override
protected Map<String, String> getEnvs() {
return Current.getRunConfiguration().getEnvMap();
}
@Override
protected String getScriptText() {
return "ulimit -s unlimited\n" + super.getScriptText();
}
@Override
protected void ValidateTaskResults() throws Exception {
task.AnalyzeResultsTexts(project);
}
protected String getCoupDeGrace() {
return "killall -SIGKILL " + task.getCompilationTask().binary_name;
}
}

View File

@@ -0,0 +1,82 @@
package GlobalData.Tasks.Supervisor.Local.Linux;
import Common.Utils.Utils;
import GlobalData.Tasks.Supervisor.Local.LocalTaskSupervisor;
import GlobalData.Tasks.Task;
import GlobalData.Tasks.TaskState;
import GlobalData.User.User;
import ProjectData.Project.db_project_info;
import Visual_DVM_2021.Passes.PassException;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Date;
public abstract class LinuxLocalTaskSupervisor<T extends Task> extends LocalTaskSupervisor<T> {
@Override
protected void StartTask() throws Exception {
super.StartTask();
task.PID = Utils.readLine(taskProcess);
}
@Override
protected String getScriptText() {
User user = task.getUser();
return
String.join(" ",
Utils.DQuotes(user.getStarterFile()),
Utils.DQuotes(user.getLauncherFile()),
String.valueOf(task.maxtime),
Utils.DQuotes(getCoupDeGrace()),
task.getFullCommand()
);
}
@Override
protected void CheckTask() throws Exception {
if (getDONE_file().exists())
task.state = TaskState.Finished;
else if (getTIMEOUT_file().exists())
task.state = TaskState.AbortedByTimeout;
}
@Override
protected String getKillCommand() {
return "kill -2 " + task.PID;
}
@Override
public void WaitForTask() throws Exception {
if (isTaskActive()) {
if (task.PID.isEmpty())
throw new PassException("Ошибка при старте : идентификатор задачи не определен.");
task.StartDate = (new Date()).getTime();
pass.ShowMessage1("Задача активна, идентификатор " + Utils.Brackets(task.PID));
RefreshProgress();
do {
Thread.sleep(getTaskCheckPeriod() * 1000L);
performanceTime += getTaskCheckPeriod();
CheckTask();
if (isTaskActive()) CheckIfNeedAbort();
RefreshProgress();
} while (isTaskActive());
}
}
protected File getProjectTime() {
return Paths.get(getProjectCopy().getAbsolutePath(), db_project_info.time_file).toFile();
}
protected File getDONE_file() {
return Paths.get(getProjectCopy().getAbsolutePath(), db_project_info.DONE).toFile();
}
protected File getTIMEOUT_file() {
return Paths.get(getProjectCopy().getAbsolutePath(), db_project_info.TIMEOUT).toFile();
}
@Override
protected void PrepareWorkspace() throws Exception {
super.PrepareWorkspace();
Utils.forceDeleteWithCheck(getDONE_file());
Utils.forceDeleteWithCheck(getTIMEOUT_file());
Utils.forceDeleteWithCheck(getProjectTime());
}
@Override
protected void CalculatePerformanceTime() throws Exception {
Files.move(getProjectTime().toPath(), task.getTimeFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
task.RefreshTime();
}
}

View File

@@ -0,0 +1,105 @@
package GlobalData.Tasks.Supervisor.Local;
import Common.Global;
import Common.Utils.Utils;
import GlobalData.Tasks.RunTask.RunTask;
import GlobalData.Tasks.Supervisor.TaskSupervisor;
import GlobalData.Tasks.Task;
import GlobalData.Tasks.TaskState;
import ProjectData.Project.db_project_info;
import Visual_DVM_2021.Passes.Pass_2021;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Map;
import java.util.Vector;
//про mpi mpich2
//https://stackoverflow.com/questions/12983635/how-to-include-library-mpich2-in-mingw
public abstract class LocalTaskSupervisor<T extends Task> extends TaskSupervisor<T, Pass_2021> {
protected Process taskProcess;
protected int exitCode;
@Override
protected void StartTask() throws Exception {
exitCode = Utils.Nan;
taskProcess = Utils.startScript(task.getLocalWorkspace(), getProjectCopy(), "start_task_script", getScriptText(), getEnvs());
task.state = TaskState.Running;
}
@Override
protected void AbortTask() throws Exception {
Process killer = Runtime.getRuntime().exec(getKillCommand());
killer.waitFor();
}
//---->
protected abstract String getScriptText();
protected abstract String getKillCommand();
//----->
protected Map<String, String> getEnvs() {
return null;
}
//---->
protected File getProjectCopy() {
return Paths.get(task.getUser().getLocalProjectsDir().getAbsolutePath(), project.getUniqKey()).toFile();
}
protected File getBinary() {
return Paths.get(getProjectCopy().getAbsolutePath(), "0" + (Global.isWindows ? ".exe" : "")).toFile();
}
protected File getProjectOutput() {
return Paths.get(getProjectCopy().getAbsolutePath(), db_project_info.out_file).toFile();
}
protected File getProjectErrors() {
return Paths.get(getProjectCopy().getAbsolutePath(), db_project_info.err_file).toFile();
}
@Override
protected void PrepareWorkspace() throws Exception {
super.PrepareWorkspace(); //локальная подготовка
Utils.forceDeleteWithCheck(getProjectOutput());
Utils.forceDeleteWithCheck(getProjectErrors());
}
@Override
protected void AchieveResults() throws Exception {
Files.copy(getProjectOutput().toPath(), task.getOutputFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
Files.copy(getProjectErrors().toPath(), task.getErrorsFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
}
protected void AchieveRunTaskResults(RunTask rTask) throws Exception {
rTask.parseCleanTime();
//-статистика
Vector<File> stsFiles = new Vector<>();
Utils.getFilesByExtensions_r(getProjectCopy(), stsFiles, "gz+");
if (stsFiles.size() > 0) {
File file = stsFiles.get(0);
rTask.UpdateLastStsName(file.getName());
Files.copy(file.toPath(), rTask.getLocalStsFile().toPath(), StandardCopyOption.REPLACE_EXISTING);
rTask.hasDvmSts = true;
}
/*
//-gcov
if (rTask.getRunConfiguration().needsGCOV()) {
//-
Process gcovProcess = Utils.startScript(rTask.getLocalWorkspace(), getProjectCopy(), "gcov_script", "gcov *.gcda -p");
gcovProcess.waitFor();
//-
project.CreateGCOVDirs();
Vector<File> gcovs = new Vector<>();
Utils.getFilesByExtensions_r(getProjectCopy(), gcovs, "gcov");
for (File src : gcovs) {
File dst = Paths.get(project.getGCOVDirectory().getAbsolutePath(),
src.getName().replace("#",
Global.isWindows ? "\\" : "/")).toFile();
Files.move(src.toPath(), dst.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
*/
}
protected void PrepareRunTaskWorkspace(RunTask rTask) throws Exception {
Utils.deleteFilesByExtensions(getProjectCopy(), "gcda", "gcov", "gz+", "par");
rTask.UpdateLastStsName("");
//отправить usr.par.
if (rTask.hasDVMPar()) {
File par_text = Paths.get(getProjectCopy().getAbsolutePath(), "usr.par").toFile();
FileUtils.write(par_text, String.join("\n", rTask.getRunConfiguration().getParList()));
}
}
protected String getCoupDeGrace(){return "";}
}

View File

@@ -0,0 +1,54 @@
package GlobalData.Tasks.Supervisor.Local.Windows;
import Common.Global;
import Common.Utils.Utils;
import GlobalData.Makefile.Makefile;
import GlobalData.Settings.SettingName;
import GlobalData.Tasks.CompilationTask.CompilationTask;
import GlobalData.Tasks.TaskState;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class WindowsLocalCompilationSupervisor extends WindowsLocalTaskSupervisor<CompilationTask> {
@Override
protected String getKillCommand() {
return "taskkill /FI \"IMAGENAME eq make.exe\" /F /T";
}
@Override
protected String getScriptText() {
return Utils.DQuotes(Global.db.settings.get(SettingName.LocalMakePathWindows).Value) + " 1>out.txt 2>err.txt";
}
//скорее всего как то выделить подготовку к компиляции как метод предка.
@Override
protected void PrepareWorkspace() throws Exception {
//возможно тут сделать отличие. не удалять все, а тоже сверять по дате и именам..
super.PrepareWorkspace();
Utils.CheckAndCleanDirectory(getProjectCopy());
//скопировать проект в папку. без бд.
project.Clone(getProjectCopy(), false);
//-удалить старый бинарник если есть? бессмысленно если папка и так полностью пересоздается при каждой компиляции.
//по идее надо исправить на синхронизацию.
//if (!task.binary_name.isEmpty()) {
// File old_binary = Paths.get(getProjectCopy().getAbsolutePath(), task.binary_name).toFile();
// FileUtils.forceDelete(old_binary);
// }
//создать мейкфайл.
Makefile makefile = task.getMakefile();
File makefile_text = Paths.get(getProjectCopy().getAbsolutePath(), "Makefile").toFile();
FileUtils.write(makefile_text, makefile.Generate(project));
}
//как и валидация.
@Override
protected void ValidateTaskResults() throws Exception {
if (getBinary().exists()) {
File renamed_binary = Paths.get(getProjectCopy().getAbsolutePath(),
Utils.getDateName("spf") + ".exe").toFile();
task.binary_name = renamed_binary.getName();
Files.move(getBinary().toPath(), renamed_binary.toPath(), StandardCopyOption.REPLACE_EXISTING);
task.state = TaskState.Done;
} else task.state = TaskState.DoneWithErrors;
task.AnalyzeResultsTexts(project);
}
}

View File

@@ -0,0 +1,48 @@
package GlobalData.Tasks.Supervisor.Local.Windows;
import Common.Current;
import GlobalData.Tasks.RunTask.RunTask;
import java.util.Map;
public class WindowsLocalRunSupervisor extends WindowsLocalTaskSupervisor<RunTask> {
@Override
protected void ValidateTaskResults() throws Exception {
task.AnalyzeResultsTexts(project);
}
@Override
protected String getScriptText() {
return task.getFullCommand() + " 1>out.txt 2>err.txt";
}
//общая часть для запуска.
@Override
protected void PrepareWorkspace() throws Exception {
super.PrepareWorkspace();
PrepareRunTaskWorkspace(task);
}
@Override
protected void AchieveResults() throws Exception {
super.AchieveResults();
AchieveRunTaskResults(task);
}
@Override
protected Map<String, String> getEnvs() {
return Current.getRunConfiguration().getEnvMap();
}
void kill_mpi() throws Exception {
System.out.println("KILLING MPI");
}
@Override
protected void AbortTask() throws Exception {
super.AbortTask(); //убить группу.
kill_mpi();
}
@Override
protected String getKillCommand() {
return "taskkill /FI \"IMAGENAME eq " + task.getCompilationTask().binary_name + "\" /F /T";
}
/*
@Override
protected void CoupDeGraceTask() throws Exception {
kill_mpi();
}
*/
}

View File

@@ -0,0 +1,51 @@
package GlobalData.Tasks.Supervisor.Local.Windows;
import Common.Global;
import GlobalData.Tasks.Supervisor.Local.LocalTaskSupervisor;
import GlobalData.Tasks.Task;
import GlobalData.Tasks.TaskState;
import java.util.Date;
import java.util.concurrent.TimeUnit;
//https://ab57.ru/cmdlist/taskkill.html
public abstract class WindowsLocalTaskSupervisor<T extends Task> extends LocalTaskSupervisor<T> {
@Override
protected void StartTask() throws Exception {
super.StartTask();
task.PID = "start_task_script.bat"; // возможно делать уникальное имя скрипта, чтобы было чем убивать под виндой.
}
//--------------------------------------------------->>>
protected void CheckIfNeedAbort() {
if (project.getInterruptFile().exists())
task.state = TaskState.AbortingByUser;
if (performanceTime > task.maxtime) {
try {
AbortTask();
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
task.state = TaskState.AbortedByTimeout;
}
}
@Override
protected void CheckTask() throws Exception {
if (taskProcess.waitFor(getTaskCheckPeriod(), TimeUnit.SECONDS)) {
exitCode = taskProcess.waitFor();
task.state = TaskState.Finished;
} else {
performanceTime += getTaskCheckPeriod();
}
}
@Override
public void WaitForTask() throws Exception {
if (isTaskActive()) {
task.StartDate = (new Date()).getTime();
pass.ShowMessage1("Задача активна");
RefreshProgress();
do {
CheckTask();
if (isTaskActive()) CheckIfNeedAbort();
RefreshProgress();
} while (isTaskActive());
}
}
}

View File

@@ -0,0 +1,58 @@
package GlobalData.Tasks.Supervisor.Remote;
import Common.Current;
import Common.Utils.Utils;
import GlobalData.RemoteFile.RemoteFile;
import GlobalData.Tasks.QueueSystem.MVS;
import GlobalData.Tasks.TaskState;
public class MVSRunSupervisor extends ServerRunSupervisor {
MVS mvs = new MVS();
int mvs_time;
@Override
protected RemoteFile getRemoteOutput() {
return new RemoteFile(getRemoteProject().full_name + "/" + task.PID, "output");
}
@Override
protected RemoteFile getRemoteErrors() {
return new RemoteFile(getRemoteProject().full_name + "/" + task.PID, "errors");
}
@Override
protected String getLaunchScriptText() {
return task.getFullCommand();
}
@Override
protected int getTaskCheckPeriod() {
return 5;
}
@Override
public int getMaxtime() {
return mvs_time * 60;
}
@Override
protected void StartTask() throws Exception {
String env = String.join(" ", Current.getRunConfiguration().getEnvList());
mvs_time = (task.maxtime / 60); //в минутах
if (task.maxtime % 60 > 0) mvs_time += 1;
String res = "maxtime=" + Utils.DQuotes(mvs_time) + " ./run";
if (!env.isEmpty())
res = env + " " + res;
mvs.enqueueTask(pass.ShellCommand(
"cd " + Utils.DQuotes(getRemoteProject().full_name),
res), task);
}
@Override
protected boolean isTaskActive() {
return super.isTaskActive() || task.state.equals(TaskState.Queued);
}
@Override
protected void CheckTask() throws Exception {
mvs.checkTask(pass.ShellCommand(mvs.getCheckTaskCommand(task)), task);
}
@Override
protected void AbortTask() throws Exception {
pass.ShellCommand(mvs.getCancelTaskCommand(task));
}
@Override
protected void CalculatePerformanceTime() throws Exception {
task.Time = performanceTime;
}
}

View File

@@ -0,0 +1,48 @@
package GlobalData.Tasks.Supervisor.Remote;
import Common.Utils.Utils;
import GlobalData.Makefile.Makefile;
import GlobalData.RemoteFile.RemoteFile;
import GlobalData.Tasks.CompilationTask.CompilationTask;
import GlobalData.Tasks.TaskState;
import java.io.File;
public class RemoteCompilationSupervisor extends RemoteTaskSupervisor<CompilationTask> {
@Override
protected void PrepareWorkspace() throws Exception {
//0. если нет папки с его именем создаем.
pass.tryMKDir(getRemoteProject());
pass.SynchronizeProjectSubDirsR(project, project.Home, getRemoteProject(), false);
pass.tryRM(getBinary());
if (!task.binary_name.isEmpty()) {
RemoteFile old_binary = new RemoteFile(getRemoteProject().full_name, task.binary_name);
pass.tryRM(old_binary);
}
//отправить мейкфайл.
Makefile makefile = task.getMakefile();
File makefile_text = Utils.CreateTempFile("makefile", makefile.Generate(project));
pass.putSingleFile(makefile_text, new RemoteFile(getRemoteProject().full_name, "Makefile"));
//очистить все что связано с gcov
//файлы gcda, gcno, gcov
pass.deleteFilesByExtensions(getRemoteProject(), "gcda", "gcno", "gcov");
//очистить служебные файлы.
super.PrepareWorkspace();
}
@Override
protected void StartTask() throws Exception {
//UI.Info("starting task");
task.PID = pass.ShellCommand(
"cd " + Utils.DQuotes(getRemoteProject().full_name),
getStartCommand());
task.state = TaskState.Running;
}
@Override
protected void ValidateTaskResults() throws Exception {
if (pass.Exists(getRemoteProject().full_name, getBinary().name)) {
RemoteFile renamed_binary = new RemoteFile(getRemoteProject().full_name, Utils.getDateName("spf_" + getBinary().name));
pass.sftpChannel.rename(getBinary().full_name, renamed_binary.full_name);
task.binary_name = renamed_binary.name;
task.state = TaskState.Done;
} else task.state = TaskState.DoneWithErrors;
task.AnalyzeResultsTexts(project);
}
}

View File

@@ -0,0 +1,76 @@
package GlobalData.Tasks.Supervisor.Remote;
import Common.Utils.Utils;
import GlobalData.RemoteFile.RemoteFile;
import GlobalData.Tasks.Supervisor.TaskSupervisor;
import GlobalData.Tasks.Task;
import GlobalData.Tasks.TaskState;
import ProjectData.Project.db_project_info;
import Visual_DVM_2021.Passes.SSH.ConnectionPass;
public abstract class RemoteTaskSupervisor<T extends Task> extends TaskSupervisor<T, ConnectionPass> {
protected RemoteFile getRemoteProjectsPath() {
return new RemoteFile(pass.user.getRemoteProjectsPath(), true);
}
protected RemoteFile getRemoteProject() {
return new RemoteFile(getRemoteProjectsPath().full_name, project.getUniqKey(), true);
}
protected RemoteFile getBinary() {
return new RemoteFile(getRemoteProject().full_name, "0");
}
protected RemoteFile getRemoteTime() {
return new RemoteFile(getRemoteProject().full_name, db_project_info.time_file);
}
protected RemoteFile getRemoteOutput() {
return new RemoteFile(getRemoteProject().full_name, db_project_info.out_file);
}
protected RemoteFile getRemoteErrors() {
return new RemoteFile(getRemoteProject().full_name, db_project_info.err_file);
}
public RemoteFile getDONE_file() {
return new RemoteFile(getRemoteProject().full_name, db_project_info.DONE);
}
public RemoteFile getTIMEOUT_file() {
return new RemoteFile(getRemoteProject().full_name, db_project_info.TIMEOUT);
}
@Override
protected void PrepareWorkspace() throws Exception {
super.PrepareWorkspace(); //локальная подготовка
pass.tryRM(getDONE_file());
pass.tryRM(getTIMEOUT_file());
pass.tryRM(getRemoteOutput());
pass.tryRM(getRemoteErrors());
pass.tryRM(getRemoteTime());
}
@Override
protected void CheckTask() throws Exception {
if (pass.Exists(getRemoteProject().full_name, db_project_info.DONE))
task.state = TaskState.Finished;
else if (pass.Exists(getRemoteProject().full_name, db_project_info.TIMEOUT))
task.state = TaskState.AbortedByTimeout;
}
@Override
protected void AchieveResults() throws Exception {
pass.tryGetSingleFile(getRemoteOutput(), task.getOutputFile(), 10240);
pass.tryGetSingleFile(getRemoteErrors(), task.getErrorsFile(), 10240);
}
@Override
protected void AbortTask() throws Exception {
pass.ShellCommand("kill -2 " + task.PID);
}
@Override
protected void CalculatePerformanceTime() throws Exception {
if (pass.tryGetSingleFile(getRemoteTime(), task.getTimeFile(), 0))
task.RefreshTime();
}
protected String getStartCommand() {
String res =
String.join(" ",
Utils.DQuotes(pass.getStarter()),
Utils.DQuotes(pass.getLauncher()),
String.valueOf(task.maxtime),
Utils.DQuotes(getCoupDeGrace()),
task.getFullCommand()
);
System.out.println(res);
return res;
}
}

View File

@@ -0,0 +1,91 @@
package GlobalData.Tasks.Supervisor.Remote;
import Common.Current;
import Common.Utils.Utils;
import GlobalData.RemoteFile.RemoteFile;
import GlobalData.Tasks.RunTask.RunTask;
import GlobalData.Tasks.TaskState;
import com.jcraft.jsch.ChannelSftp;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Vector;
public class ServerRunSupervisor extends RemoteTaskSupervisor<RunTask> {
@Override
protected void StartTask() throws Exception {
String res = "./run";
String env = String.join(" ", Current.getRunConfiguration().getEnvList());
if (!env.isEmpty()) res = env + " " + res;
task.PID = pass.ShellCommand(
"cd " + Utils.DQuotes(getRemoteProject().full_name),
"ulimit -s unlimited",
res);
task.state = TaskState.Running;
}
@Override
protected void ValidateTaskResults() throws Exception {
task.AnalyzeResultsTexts(project);
}
@Override
protected void PrepareWorkspace() throws Exception {
super.PrepareWorkspace();
//-------------------------
//удалить старую статистику если оная есть.
if (!task.last_sts_name.isEmpty()) {
pass.tryRM(new RemoteFile(getRemoteProject().full_name, task.last_sts_name));
task.UpdateLastStsName("");
}
//-------------------------
String launchScriptText = getLaunchScriptText();
RemoteFile launchScript = new RemoteFile(getRemoteProject().full_name, "run");
pass.sftpChannel.put(
new ByteArrayInputStream(
launchScriptText.getBytes(StandardCharsets.UTF_8)), launchScript.full_name);
pass.sftpChannel.chmod(0777, launchScript.full_name);
//-
//отправить usr.par.
if (task.hasDVMPar()) {
File par_text = Utils.CreateTempFile("usr", String.join("\n", task.getRunConfiguration().getParList()));
pass.putSingleFile(par_text, new RemoteFile(getRemoteProject().full_name, "usr.par"));
}
}
protected String getLaunchScriptText() {
return getStartCommand();
}
@Override
protected String getCoupDeGrace() {
return "killall -SIGKILL " + task.getCompilationTask().binary_name;
}
@Override
protected void AchieveResults() throws Exception {
super.AchieveResults();
task.parseCleanTime();
//теперь ищем статистику.
//статистика
Vector<ChannelSftp.LsEntry> files = pass.sftpChannel.ls(getRemoteProject().full_name);
for (ChannelSftp.LsEntry file : files) {
if (file.getFilename().endsWith("sts.gz+")) {
task.UpdateLastStsName(file.getFilename());
break;
}
}
if (!task.last_sts_name.isEmpty()) {
RemoteFile remote_sts = new RemoteFile(getRemoteProject().full_name, task.last_sts_name);
task.hasDvmSts = pass.tryGetSingleFile(remote_sts, task.getLocalStsFile(), 10240);
}
}
}
/*
//ищем GCOV
if (task.getRunConfiguration().needsGCOV()) {
pass.ShellCommand("cd " + Utils.DQuotes(getRemoteProject().full_name),
"gcov *.gcda -p"
);
project.CreateGCOVDirs();
Vector<RemoteFile> gcov_results = pass.getFilesByExtensions(getRemoteProject(), "gcov");
for (RemoteFile gcov_file : gcov_results) {
File local_gcov = Paths.get(project.getGCOVDirectory().getAbsolutePath(),
gcov_file.name.replace("#", "\\")).toFile();
pass.getSingleFile(gcov_file.full_name, local_gcov.getAbsolutePath());
}
*/

View File

@@ -0,0 +1,138 @@
package GlobalData.Tasks.Supervisor;
import Common.Global;
import Common.Utils.Utils;
import GlobalData.Tasks.Task;
import GlobalData.Tasks.TaskState;
import ProjectData.Project.db_project_info;
import Visual_DVM_2021.Passes.PassException;
import Visual_DVM_2021.Passes.Pass_2021;
import java.util.Date;
public abstract class TaskSupervisor<T extends Task, P extends Pass_2021> {
public T task; //задача
protected db_project_info project; //проект к которому относится задача
protected P pass; //проход отвечающий за задачу
protected int performanceTime; //сколько задача уже выполняется.
public void ShowTaskState(){
Global.db.tables.get(task.getClass()).ShowUI(task.getPK());
}
public void Init(T task_in, P pass_in, db_project_info project_in) {
task = task_in;
pass = pass_in;
project = project_in;
try {
project.CleanInterruptFile();
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
protected void PrepareWorkspace() throws Exception {
Utils.CheckAndCleanDirectory(task.getLocalWorkspace());
}
protected abstract void StartTask() throws Exception;
protected boolean isTaskActive() {
return task.state.equals(TaskState.Running);
}
//периодичность проверки состояния задачи (с)
protected int getTaskCheckPeriod() {
return 1;
}
public int getMaxtime() {
return task.maxtime;
}
protected void RefreshProgress() {
pass.ShowProgress2(getMaxtime(), performanceTime, task.state.getDescription() + ", прошло секунд");
}
//проверка состояния задачи
protected void CheckTask() throws Exception {
}
protected void CheckIfNeedAbort() {
if (project.getInterruptFile().exists()){
task.state = TaskState.AbortingByUser;
ShowTaskState();
}
}
//досрочное прерывание задачи
protected void AbortTask() throws Exception {
}
protected String getCoupDeGrace(){
return "";
}
//добивание задачи после ее завершения по таймауту. не всегда нужно
// protected void CoupDeGraceTask() throws Exception {}
//получить результаты выполнения задачи. в случае локальной машины, очевидно, пустая функция
protected void AchieveResults() throws Exception {
}
protected abstract void ValidateTaskResults() throws Exception;
//получить время выполнения задачи. по умолчанию самый грубый метод.
protected void CalculatePerformanceTime() throws Exception {
task.Time = performanceTime;
}
//рабочий цикл задачи.
public void PerformTask() throws Exception {
if (task.hasProgress())
pass.ShowProgressTextOnly(task.progressAll, task.progressStep, "задача");
//сброс
performanceTime = 0;
System.out.println(performanceTime);
task.Reset();
ShowTaskState();
pass.ShowMessage1("Подготовка рабочего пространства задачи..");
PrepareWorkspace();
ShowTaskState();
pass.ShowMessage1("Старт задачи..");
//запуск задачи
StartTask();
ShowTaskState();
WaitForTask();
//маловероятно, но в теории задача может оказаться выполненной сразу после команды выполнения
//например если запуск шел через систему очередей.
//анализируем состояние.
//если приказано убить задачу. убиваем.
if (task.state == TaskState.AbortingByUser) {
pass.ShowMessage1("Принудительная остановка задачи..");
AbortTask();
task.state = TaskState.AbortedByUser;
ShowTaskState();
}
pass.ShowMessage1("Задача " + Utils.Brackets(task.state.getDescription()));
task.EndDate = (new Date()).getTime();
pass.ShowMessage2("Получение результатов");
AchieveResults();
pass.ShowMessage2("Анализ результатов");
switch (task.state) {
case Finished:
ValidateTaskResults();
CalculatePerformanceTime();
break;
case AbortedByTimeout:
task.MaximizeTime();
pass.ShowMessage2("Добивание задачи..");
break;
default:
break;
}
}
public void WaitForTask() throws Exception {
if (isTaskActive()) {
if (task.PID.isEmpty())
throw new PassException("Ошибка при старте : идентификатор задачи не определен.");
task.StartDate = (new Date()).getTime();
pass.ShowMessage1("Задача активна, идентификатор " + Utils.Brackets(task.PID));
RefreshProgress();
do {
Thread.sleep(getTaskCheckPeriod() * 1000);
performanceTime += getTaskCheckPeriod();
CheckTask();
if (isTaskActive()) CheckIfNeedAbort();
RefreshProgress();
} while (isTaskActive());
ShowTaskState();
}
}
public void UpdateTask() throws Exception {
Global.db.Update(task);
}
}

View File

@@ -0,0 +1,129 @@
package GlobalData.Tasks;
import Common.Database.iDBObject;
import Common.Global;
import Common.Utils.Utils;
import GlobalData.Machine.Machine;
import GlobalData.User.User;
import ProjectData.Project.db_project_info;
import com.sun.org.glassfish.gmbal.Description;
import java.io.File;
import java.nio.file.Paths;
import java.util.Date;
public abstract class Task extends iDBObject {
//<editor-fold desc="файловые константы">
//</editor-fold>
public TaskState state = TaskState.Inactive;
//----------------------------------
public int machine_id = Utils.Nan;
public int user_id = Utils.Nan;
//-----------------------------------
public String PID = "";
public String project_path;// путь к проекту.
public String project_description; // краткое описание(чтобы не лезть в бд целевого проекта). только для таблицы.
public int maxtime = 40;
//результаты-------------------------------
public double Time; //время выполнения.
public long StartDate = 0; //дата начала выполнения
public long EndDate = 0;//дата окончания выполнения
//---------------------------------
@Description("IGNORE")
public int progressStep = Utils.Nan;
@Description("IGNORE")
public int progressAll = Utils.Nan;
public boolean belongsToProject(db_project_info project) {
return this.project_path.equalsIgnoreCase(project.Home.getAbsolutePath());
}
public void DropResults() throws Exception {
Utils.forceDeleteWithCheck(getOutputFile());
Utils.forceDeleteWithCheck(getErrorsFile());
//-
StartDate = 0;
EndDate = 0;
Time = 0;
state = TaskState.Inactive;
Global.db.Update(this);
}
//</editor-fold>
//<editor-fold desc="локальные файлы">
public abstract File getHome();
public File getLocalWorkspace() {
return Paths.get(getHome().getAbsolutePath(), String.valueOf(id)).toFile();
}
public File getOutputFile() {
return Paths.get(getLocalWorkspace().getAbsolutePath(), db_project_info.out_file).toFile();
}
public File getErrorsFile() {
return Paths.get(getLocalWorkspace().getAbsolutePath(), db_project_info.err_file).toFile();
}
public File getTimeFile() {
return Paths.get(getLocalWorkspace().getAbsolutePath(), db_project_info.time_file).toFile();
}
public abstract String getFullCommand();
public Date getEndDate() {
return new Date(EndDate);
}
public Machine getMachine() {
return Global.db.getById(Machine.class, machine_id);
}
public User getUser() {
return Global.db.getById(User.class, user_id);
}
protected String getTextResult(File file) {
return (file.exists()) ? Utils.ReadAllText(file) : "файл не найден. Задача еще не выполнялась или была завершена некорректно";
}
//подразумевается, что выходные потоки задачи видны только при открытом проекте
public String getOutput() {
return getTextResult(getOutputFile());
}
public String getErrors() {
return getTextResult(getErrorsFile());
}
public void RefreshTime() {
Time = Double.parseDouble(Utils.ReadAllText(getTimeFile()));
}
public void MaximizeTime() {
Time = maxtime + 1;
}
public void UpdateState(TaskState state_in) {
if (state != state_in) {
state = state_in;
try {
Global.db.Update(this);
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
}
public void Reset() {
PID = "";
StartDate = 0;
EndDate = 0;
state = TaskState.Inactive;
}
public void setProgress(int progressStep_in, int progressAll_in) {
progressStep = progressStep_in;
progressAll = progressAll_in;
}
public void dropProgress() {
progressStep = Utils.Nan;
progressAll = Utils.Nan;
}
public boolean hasProgress() {
return (progressStep != Utils.Nan) && (progressAll != Utils.Nan);
}
//---------------------------------
public void AnalyzeResultsTexts(db_project_info project) throws Exception {
state = TaskState.Done;
AnalyzeOutFile(project);
AnalyzeErrorsFile(project);
}
public void AnalyzeOutFile(db_project_info project) throws Exception {
}
public void AnalyzeErrorsFile(db_project_info project) throws Exception {
}
public boolean isPassive() {
return (state != TaskState.Queued) && (state != TaskState.Running);
}
}

View File

@@ -0,0 +1,148 @@
package GlobalData.Tasks;
import Common.Current;
import Common.UI.StatusEnum;
import Common.UI.Themes.VisualiserFonts;
import java.awt.*;
public enum TaskState implements StatusEnum {
Inactive,
//--
Waiting,
WorkspaceCreated,
WorkspaceReady,
Running,
Canceled,
//--- определение без скачки результатов!
ResultsDownloaded,
//-----------------------
Finished,
//--- результирующие
Done,
DoneWithErrors,
AbortedByTimeout,
AbortedByUser,
Crushed,
WrongTestFormat,
InternalError,
//--- сугубо кластерные.
Queued,
NoSuchTask,
FailedToQueue,
AbortingByUser; //только для одиночного запуска
public boolean isVisible() {
switch (this) {
case Queued:
case FailedToQueue:
case NoSuchTask:
case AbortingByUser:
return false;
default:
return true;
}
}
public String getDescription() {
switch (this) {
case Waiting:
return "ожидание";
case WorkspaceCreated:
return "папка создана";
case WorkspaceReady:
return "готова к выполнению";
case Running:
return "выполняется";
case Finished:
return "ожидание анализа результатов";
case Inactive:
return "неактивно";
case AbortedByTimeout:
return "таймаут";
case AbortedByUser:
return "прервана";
case Done:
return "успешно";
case DoneWithErrors:
return "с ошибками";
case Crushed:
return "падение";
case Canceled:
return "отменена";
case InternalError:
return "внутренняя ошибка";
case WrongTestFormat:
return "неверный формат";
case FailedToQueue:
return "не удалось поставить в очередь";
case NoSuchTask:
return "не существует";
case Queued:
return "в очереди";
case AbortingByUser:
return "прерывание...";
case ResultsDownloaded:
return "результаты загружены";
//--------------------------------------->>>
default:
return StatusEnum.super.getDescription();
}
}
@Override
public Font getFont() {
switch (this) {
case FailedToQueue:
case NoSuchTask:
case AbortedByUser:
case AbortedByTimeout:
case DoneWithErrors:
case WrongTestFormat:
case InternalError:
case Canceled:
return Current.getTheme().Fonts.get(VisualiserFonts.BadState);
case Queued:
case Running:
return Current.getTheme().Fonts.get(VisualiserFonts.ProgressState);
case Done:
return Current.getTheme().Fonts.get(VisualiserFonts.GoodState);
case Crushed:
return Current.getTheme().Fonts.get(VisualiserFonts.Fatal);
case Finished:
return Current.getTheme().Fonts.get(VisualiserFonts.BlueState);
case WorkspaceReady:
return Current.getTheme().Fonts.get(VisualiserFonts.ReadyState);
default:
return StatusEnum.super.getFont();
}
}
//
public boolean isActive() {
switch (this) {
case Waiting:
case Running:
case Queued:
case Finished:
case AbortingByUser:
case WorkspaceReady:
case WorkspaceCreated:
return true;
default:
return false;
}
}
public boolean isFinished() {
return this == TaskState.Finished;
}
public boolean isComplete() {
switch (this) {
case Done:
case DoneWithErrors:
case AbortedByTimeout:
case AbortedByUser:
case WrongTestFormat:
case Crushed:
case InternalError:
case Canceled:
return true;
default:
return false;
}
}
}