This commit is contained in:
IDONTSUDO 2024-12-14 20:09:42 +03:00
parent bad5c4d8a0
commit 8696d99194
8 changed files with 97 additions and 13 deletions

View file

@ -0,0 +1,58 @@
import { Disposable, Listener, TypedEvent } from "../helpers/typed_event";
import { GetRootDirUseCase } from "../usecases/get_root_dir_usecase"
import { exec } from 'child_process';
enum ProcessStatus {
run = 'run',
endError = 'endError',
endOk = 'endOk',
}
class ProcessData {
log: string | undefined;
status: ProcessStatus;
constructor(log: string | undefined, status: ProcessStatus) {
// console.log(log)
if (log !== undefined) {
this.log = log;
}
this.status = status;
}
}
abstract class Watcher {
}
export abstract class ExecProcessWatcher extends TypedEvent<ProcessData> implements Watcher {
logs: string[] = [];
status: ProcessStatus;
constructor() {
super();
this.on((event) => {
if (event.log !== undefined) {
console.log(event.log)
this.logs.push(event.log);
}
this.status = event.status;
if (event.status.isEqualMany([ProcessStatus.endError, ProcessStatus.endOk])) {
this.result()
}
})
}
abstract result(): Promise<any>
}
export class ExecProcessScenarioV2 {
call = (command: string, watcher: ExecProcessWatcher): void => {
const process = exec(command, { cwd: new GetRootDirUseCase().call() });
process.stdout.on('data', (data) => watcher.emit(new ProcessData(data, ProcessStatus.run)))
process.stderr.on('data', (data) => watcher.emit(new ProcessData(data, ProcessStatus.run)));
process.on('close', (code) =>{
if(code === 0){
watcher.emit(new ProcessData(undefined, ProcessStatus.endOk))
}else{
watcher.emit(new ProcessData(undefined, ProcessStatus.endError))
}
});
process.on('error', (err) => watcher.emit(new ProcessData(err.message, ProcessStatus.endError)));
}
}

View file

@ -0,0 +1,5 @@
import * as os from 'os';
export class GetRootDirUseCase {
call = (): string => os.homedir()
}

View file

@ -5,6 +5,7 @@ import { CalculationInstanceDBModel } from "./models/calculations_instance_datab
import { CreateCalculationInstanceScenario } from "./domain/create_calculation_instance_scenario";
import { DeleteCalculationsInstanceScenario } from "./domain/delete_calculations_instance_scenario";
export class CalculationsInstancesPresentation extends CrudController<
CalculationInstanceValidationModel,
typeof CalculationInstanceDBModel
@ -26,3 +27,4 @@ export class CalculationsInstancesPresentation extends CrudController<
});
}
}

View file

@ -7,7 +7,21 @@ import { ProcessWatcherAndDatabaseUpdateService } from "../../datasets/domain/cr
import { CalculationInstanceDBModel, ICalculationInstance } from "../models/calculations_instance_database_model";
import { Result } from "../../../core/helpers/result";
import { CreateFileUseCase } from "../../../core/usecases/create_file_usecase";
import { ExecProcessScenarioV2, ExecProcessWatcher } from "../../../core/scenarios/exec_process_scenario_v2";
class ExecProcess extends ExecProcessWatcher {
id: string;
constructor(id: string) {
super()
this.id = id;
}
result = async (): Promise<any> => (await new ReadByIdDataBaseModelUseCase<ICalculationInstance>(CalculationInstanceDBModel).call(this.id)).map(async (model) => {
model.lastProcessLogs = this.logs.join('\n')
model.processStatus = this.status;
// @ts-ignore
await model.save()
});
}
export class ExecCalculationInstanceProcessScenario extends CallbackStrategyWithIdQuery {
idValidationExpression = new MongoIdValidation();
call = async (id: string): ResponseBase =>
@ -23,13 +37,9 @@ export class ExecCalculationInstanceProcessScenario extends CallbackStrategyWith
processStatus: "RUN",
lastProcessExecCommand: execCommand,
});
new ExecProcessUseCase().call(
// @ts-expect-error
`${model.project.rootDir}/`,
execCommand,
id,
new ProcessWatcherAndDatabaseUpdateService(id as unknown as ObjectId, CalculationInstanceDBModel)
);
new ExecProcessScenarioV2().call(execCommand, new ExecProcess(model._id))
return Result.ok("OK");
});
}

View file

@ -3,6 +3,7 @@ import { FormBuilderValidationModel } from "../../datasets/models/dataset_valida
import { IProjectModel, projectSchema } from "../../projects/models/project_model_database_model";
export interface ICalculationInstance {
_id: string;
script: string;
instancePath: string;
formBuilder: FormBuilderValidationModel;

View file

@ -4,6 +4,7 @@ import { FormBuilderValidationModel } from "../../datasets/models/dataset_valida
import { IProjectModel } from "../../projects/models/project_model_database_model";
export class CalculationInstanceValidationModel implements ICalculationInstance {
_id: string;
@IsNotEmpty()
@IsString()
instanceName: string;

View file

@ -3,8 +3,7 @@ import { App } from "./core/controllers/app";
import { SocketSubscriber } from "./core/controllers/socket_controller";
import { extensions } from "./core/extensions/extensions";
import { httpRoutes } from "./core/controllers/routes";
import { SpawnProcessUseCase, executorProgramService } from "./core/usecases/exec_process_usecase";
import { ProcessWatcher } from "./features/runtime/service/process_watcher";
import { executorProgramService } from "./core/usecases/exec_process_usecase";
extensions();

View file

@ -28,7 +28,7 @@ export const CalculationInstanceScreenPath = "/calculation";
export const CalculationInstanceScreen = observer(() => {
const store = useStore(CalculationInstanceStore);
// console.log(200);
return (
<>
<MainPage
@ -143,8 +143,16 @@ export const CalculationInstanceScreen = observer(() => {
label={"Тип карточки"}
onChange={(text: string) => store.updateForm({ card: text })}
/>
<CoreInput label="Имя" onChange={(text) => store.updateForm({ name: text })} />
<CoreInput label="Команда для запуска" onChange={(text) => store.updateForm({ script: text })} />
<CoreInput
trim={true}
label="Имя"
onChange={(text) => store.updateForm({ name: text.replaceAll("\n", "") })}
/>
<CoreInput
trim={true}
label="Команда для запуска"
onChange={(text) => store.updateForm({ script: text.replaceAll("\n", "") })}
/>
<InputV2
label="FormBuilder Result"
onChange={(text) => (store.viewModel.formBuilder.result = text)}