2023-12-03 13:09:16 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
2023-09-17 22:13:42 +03:00
|
|
|
#include "File.h"
|
|
|
|
|
#include "Utils.h"
|
|
|
|
|
#include "Global.h"
|
2023-12-03 13:09:16 +03:00
|
|
|
|
|
|
|
|
enum TaskState {
|
2023-09-17 22:13:42 +03:00
|
|
|
Inactive, //0
|
|
|
|
|
Waiting, //1
|
|
|
|
|
WorkspaceCreated, //2
|
|
|
|
|
WorkspaceReady, //3
|
|
|
|
|
Running, //4
|
|
|
|
|
Canceled, //5
|
|
|
|
|
Finished, //6
|
|
|
|
|
FinishedAbortedByTimeout, //7
|
|
|
|
|
FinishedAbortedByUser, //8
|
|
|
|
|
Done, //9
|
|
|
|
|
DoneWithErrors, //10
|
|
|
|
|
AbortedByTimeout, //11
|
|
|
|
|
AbortedByUser, //12
|
|
|
|
|
Crushed, //13
|
|
|
|
|
WrongTestFormat, //14
|
|
|
|
|
InternalError, //15
|
|
|
|
|
Queued, //16
|
|
|
|
|
NoSuchTask, //17
|
|
|
|
|
FailedToQueue, //18
|
|
|
|
|
AbortingByUser //19
|
2023-12-03 13:09:16 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum TestType {
|
2023-09-17 22:13:42 +03:00
|
|
|
Default, //0
|
|
|
|
|
Correctness, //1
|
|
|
|
|
Performance, //2
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class Task {
|
|
|
|
|
protected:
|
2023-12-03 13:09:16 +03:00
|
|
|
long id;
|
2023-12-03 17:44:32 +03:00
|
|
|
|
2023-09-17 22:13:42 +03:00
|
|
|
int maxtime;
|
|
|
|
|
int kernels; //получение зависит от типа задачи.
|
|
|
|
|
String workspace;
|
|
|
|
|
TaskState state;
|
2023-12-03 13:09:16 +03:00
|
|
|
public:
|
2023-12-03 17:44:32 +03:00
|
|
|
long start_time;
|
2023-09-17 22:13:42 +03:00
|
|
|
String printState(){
|
|
|
|
|
switch(state){
|
|
|
|
|
case Inactive:
|
|
|
|
|
return String("Inactive");
|
|
|
|
|
case Waiting:
|
|
|
|
|
return String("Waiting");
|
|
|
|
|
case WorkspaceCreated:
|
|
|
|
|
return String("WorkspaceCreated");
|
|
|
|
|
case WorkspaceReady:
|
|
|
|
|
return String("WorkspaceReady");
|
|
|
|
|
case Running:
|
|
|
|
|
return String("Running");
|
|
|
|
|
case Canceled:
|
|
|
|
|
return String("Canceled");
|
|
|
|
|
case Finished:
|
|
|
|
|
return String("Finished");
|
|
|
|
|
case FinishedAbortedByTimeout:
|
|
|
|
|
return String("FinishedAbortedByTimeout");
|
|
|
|
|
case FinishedAbortedByUser:
|
|
|
|
|
return String("FinishedAbortedByUser");
|
|
|
|
|
case Done:
|
|
|
|
|
return String("Done");
|
|
|
|
|
case DoneWithErrors:
|
|
|
|
|
return String("DoneWithErrors");
|
|
|
|
|
case AbortedByTimeout:
|
|
|
|
|
return String("AbortedByTimeout");
|
|
|
|
|
case AbortedByUser:
|
|
|
|
|
return String("AbortedByUser");
|
|
|
|
|
case Crushed:
|
|
|
|
|
return String("Crushed");
|
|
|
|
|
case WrongTestFormat:
|
|
|
|
|
return String("WrongTestFormat");
|
|
|
|
|
case InternalError:
|
|
|
|
|
return String("InternalError");
|
|
|
|
|
case Queued:
|
|
|
|
|
return String("Queued");
|
|
|
|
|
case NoSuchTask:
|
|
|
|
|
return String("NoSuchTask");
|
|
|
|
|
case FailedToQueue:
|
|
|
|
|
return String("FailedToQueue");
|
|
|
|
|
case AbortingByUser:
|
|
|
|
|
return String("AbortingByUser");
|
|
|
|
|
default:
|
|
|
|
|
return "?";
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-03 18:02:15 +03:00
|
|
|
|
2023-09-17 22:13:42 +03:00
|
|
|
//-------------->>
|
2023-12-03 13:09:16 +03:00
|
|
|
long getId() { return id; }
|
|
|
|
|
long setId(String* id_s) {
|
|
|
|
|
return id = strtol(id_s->getCharArray(), NULL, 10);
|
|
|
|
|
}
|
|
|
|
|
int getMaxtime() { return maxtime; }
|
|
|
|
|
int setMaxtime(String* maxtime_s) {
|
|
|
|
|
return maxtime = atoi(maxtime_s->getCharArray());
|
|
|
|
|
}
|
|
|
|
|
const String& getWorkspace() { return workspace; }
|
|
|
|
|
TaskState getState() { return state; }
|
|
|
|
|
TaskState setState(TaskState state_in) { return state = state_in; }
|
|
|
|
|
Task(Text* lines, int offset) {
|
|
|
|
|
setId(lines->get(offset));
|
|
|
|
|
setMaxtime(lines->get(offset + 1));
|
|
|
|
|
workspace = packageWorkspace + "/" + String(id);
|
|
|
|
|
}
|
2023-12-03 13:41:29 +03:00
|
|
|
virtual void print() const = 0;
|
2023-09-17 22:13:42 +03:00
|
|
|
//-
|
2023-12-03 13:09:16 +03:00
|
|
|
virtual void prepareWorkspace() {}
|
|
|
|
|
virtual String getLaunchScriptText() = 0;
|
|
|
|
|
virtual String getStartCommand() {
|
|
|
|
|
return workspace + "/run";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void createWorkspace() {
|
|
|
|
|
Utils::Mkdir(workspace);
|
|
|
|
|
}
|
|
|
|
|
void createLaunchScript() {
|
|
|
|
|
String launchScriptPath = workspace + "/run";
|
|
|
|
|
String launchScriptText =
|
|
|
|
|
String("cd ") + String::DQuotes(workspace) + "\n" +
|
|
|
|
|
getLaunchScriptText();
|
|
|
|
|
File launchScriptFile = File(launchScriptPath, launchScriptText);
|
|
|
|
|
Utils::Chmod(launchScriptPath);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-03 15:31:50 +03:00
|
|
|
int getKernels() const { return kernels; }
|
|
|
|
|
|
|
|
|
|
virtual void Start(bool dontCheck = false) {
|
|
|
|
|
|
|
|
|
|
if (kernels <= freeKernels || dontCheck) {
|
2023-12-03 13:09:16 +03:00
|
|
|
system(getStartCommand().getCharArray());
|
|
|
|
|
state = Running;
|
2023-09-17 22:13:42 +03:00
|
|
|
//-
|
2023-12-03 13:09:16 +03:00
|
|
|
busyKernels = Utils::min(busyKernels + kernels, maxKernels);
|
|
|
|
|
freeKernels = Utils::max(0, maxKernels - busyKernels);
|
2023-09-17 22:13:42 +03:00
|
|
|
//-
|
2023-12-03 13:09:16 +03:00
|
|
|
}
|
|
|
|
|
}
|
2023-12-03 15:31:50 +03:00
|
|
|
|
2023-12-03 16:25:42 +03:00
|
|
|
//return 'true' if done, 'false' - if running
|
|
|
|
|
virtual bool Check() {
|
2023-12-03 15:31:50 +03:00
|
|
|
if (Utils::Exists(workspace + "/DONE"))
|
2023-09-17 22:13:42 +03:00
|
|
|
analyseResults();
|
2023-12-03 13:09:16 +03:00
|
|
|
else {
|
|
|
|
|
if (Utils::Exists(workspace + "/TIMEOUT")) {
|
|
|
|
|
state = AbortedByTimeout;
|
2023-09-17 22:13:42 +03:00
|
|
|
//todo определить по интервалу времени на всякий случай.
|
|
|
|
|
}else if (Utils::Exists(workspace+"/INTERRUPT")){
|
|
|
|
|
state=AbortedByUser;
|
2023-12-03 17:44:32 +03:00
|
|
|
} else {
|
|
|
|
|
long now = Utils::getAbsoluteTime();
|
|
|
|
|
long delta = now-start_time;
|
|
|
|
|
if (maxtime<delta){
|
|
|
|
|
state=AbortedByTimeout;
|
|
|
|
|
}
|
2023-12-03 13:09:16 +03:00
|
|
|
}
|
2023-09-17 22:13:42 +03:00
|
|
|
}
|
2023-12-03 18:02:15 +03:00
|
|
|
if (state!=Running){
|
2023-09-17 22:13:42 +03:00
|
|
|
//-
|
2023-12-03 13:09:16 +03:00
|
|
|
busyKernels = Utils::min(busyKernels - kernels, maxKernels);
|
|
|
|
|
freeKernels = Utils::max(0, maxKernels - busyKernels);
|
2023-09-17 22:13:42 +03:00
|
|
|
//-
|
2023-12-03 16:25:42 +03:00
|
|
|
//saveState(); //не нужно. только для отладки. анализ будет делаться архивом.
|
2023-12-03 13:09:16 +03:00
|
|
|
}
|
2023-12-03 16:25:42 +03:00
|
|
|
|
|
|
|
|
return (state != Running);
|
2023-12-03 13:09:16 +03:00
|
|
|
}
|
2023-12-03 15:31:50 +03:00
|
|
|
|
|
|
|
|
virtual void analyseResults() {
|
|
|
|
|
state = Finished;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-03 13:09:16 +03:00
|
|
|
virtual void saveState() {
|
|
|
|
|
String stateFile = workspace + "/TaskState";
|
2023-12-03 15:31:50 +03:00
|
|
|
File tmp(stateFile, printState());
|
2023-12-03 13:09:16 +03:00
|
|
|
}
|
|
|
|
|
};
|