progress
This commit is contained in:
parent
bad5c4d8a0
commit
8696d99194
8 changed files with 97 additions and 13 deletions
58
server/src/core/scenarios/exec_process_scenario_v2.ts
Normal file
58
server/src/core/scenarios/exec_process_scenario_v2.ts
Normal 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)));
|
||||||
|
}
|
||||||
|
}
|
5
server/src/core/usecases/get_root_dir_usecase.ts
Normal file
5
server/src/core/usecases/get_root_dir_usecase.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import * as os from 'os';
|
||||||
|
|
||||||
|
export class GetRootDirUseCase {
|
||||||
|
call = (): string => os.homedir()
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import { CalculationInstanceDBModel } from "./models/calculations_instance_datab
|
||||||
import { CreateCalculationInstanceScenario } from "./domain/create_calculation_instance_scenario";
|
import { CreateCalculationInstanceScenario } from "./domain/create_calculation_instance_scenario";
|
||||||
import { DeleteCalculationsInstanceScenario } from "./domain/delete_calculations_instance_scenario";
|
import { DeleteCalculationsInstanceScenario } from "./domain/delete_calculations_instance_scenario";
|
||||||
|
|
||||||
|
|
||||||
export class CalculationsInstancesPresentation extends CrudController<
|
export class CalculationsInstancesPresentation extends CrudController<
|
||||||
CalculationInstanceValidationModel,
|
CalculationInstanceValidationModel,
|
||||||
typeof CalculationInstanceDBModel
|
typeof CalculationInstanceDBModel
|
||||||
|
@ -26,3 +27,4 @@ export class CalculationsInstancesPresentation extends CrudController<
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,21 @@ import { ProcessWatcherAndDatabaseUpdateService } from "../../datasets/domain/cr
|
||||||
import { CalculationInstanceDBModel, ICalculationInstance } from "../models/calculations_instance_database_model";
|
import { CalculationInstanceDBModel, ICalculationInstance } from "../models/calculations_instance_database_model";
|
||||||
import { Result } from "../../../core/helpers/result";
|
import { Result } from "../../../core/helpers/result";
|
||||||
import { CreateFileUseCase } from "../../../core/usecases/create_file_usecase";
|
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 {
|
export class ExecCalculationInstanceProcessScenario extends CallbackStrategyWithIdQuery {
|
||||||
idValidationExpression = new MongoIdValidation();
|
idValidationExpression = new MongoIdValidation();
|
||||||
call = async (id: string): ResponseBase =>
|
call = async (id: string): ResponseBase =>
|
||||||
|
@ -23,13 +37,9 @@ export class ExecCalculationInstanceProcessScenario extends CallbackStrategyWith
|
||||||
processStatus: "RUN",
|
processStatus: "RUN",
|
||||||
lastProcessExecCommand: execCommand,
|
lastProcessExecCommand: execCommand,
|
||||||
});
|
});
|
||||||
new ExecProcessUseCase().call(
|
|
||||||
// @ts-expect-error
|
new ExecProcessScenarioV2().call(execCommand, new ExecProcess(model._id))
|
||||||
`${model.project.rootDir}/`,
|
|
||||||
execCommand,
|
|
||||||
id,
|
|
||||||
new ProcessWatcherAndDatabaseUpdateService(id as unknown as ObjectId, CalculationInstanceDBModel)
|
|
||||||
);
|
|
||||||
return Result.ok("OK");
|
return Result.ok("OK");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { FormBuilderValidationModel } from "../../datasets/models/dataset_valida
|
||||||
import { IProjectModel, projectSchema } from "../../projects/models/project_model_database_model";
|
import { IProjectModel, projectSchema } from "../../projects/models/project_model_database_model";
|
||||||
|
|
||||||
export interface ICalculationInstance {
|
export interface ICalculationInstance {
|
||||||
|
_id: string;
|
||||||
script: string;
|
script: string;
|
||||||
instancePath: string;
|
instancePath: string;
|
||||||
formBuilder: FormBuilderValidationModel;
|
formBuilder: FormBuilderValidationModel;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { FormBuilderValidationModel } from "../../datasets/models/dataset_valida
|
||||||
import { IProjectModel } from "../../projects/models/project_model_database_model";
|
import { IProjectModel } from "../../projects/models/project_model_database_model";
|
||||||
|
|
||||||
export class CalculationInstanceValidationModel implements ICalculationInstance {
|
export class CalculationInstanceValidationModel implements ICalculationInstance {
|
||||||
|
_id: string;
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsString()
|
@IsString()
|
||||||
instanceName: string;
|
instanceName: string;
|
||||||
|
|
|
@ -3,8 +3,7 @@ import { App } from "./core/controllers/app";
|
||||||
import { SocketSubscriber } from "./core/controllers/socket_controller";
|
import { SocketSubscriber } from "./core/controllers/socket_controller";
|
||||||
import { extensions } from "./core/extensions/extensions";
|
import { extensions } from "./core/extensions/extensions";
|
||||||
import { httpRoutes } from "./core/controllers/routes";
|
import { httpRoutes } from "./core/controllers/routes";
|
||||||
import { SpawnProcessUseCase, executorProgramService } from "./core/usecases/exec_process_usecase";
|
import { executorProgramService } from "./core/usecases/exec_process_usecase";
|
||||||
import { ProcessWatcher } from "./features/runtime/service/process_watcher";
|
|
||||||
|
|
||||||
extensions();
|
extensions();
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const CalculationInstanceScreenPath = "/calculation";
|
||||||
|
|
||||||
export const CalculationInstanceScreen = observer(() => {
|
export const CalculationInstanceScreen = observer(() => {
|
||||||
const store = useStore(CalculationInstanceStore);
|
const store = useStore(CalculationInstanceStore);
|
||||||
|
// console.log(200);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MainPage
|
<MainPage
|
||||||
|
@ -143,8 +143,16 @@ export const CalculationInstanceScreen = observer(() => {
|
||||||
label={"Тип карточки"}
|
label={"Тип карточки"}
|
||||||
onChange={(text: string) => store.updateForm({ card: text })}
|
onChange={(text: string) => store.updateForm({ card: text })}
|
||||||
/>
|
/>
|
||||||
<CoreInput label="Имя" onChange={(text) => store.updateForm({ name: text })} />
|
<CoreInput
|
||||||
<CoreInput label="Команда для запуска" onChange={(text) => store.updateForm({ script: text })} />
|
trim={true}
|
||||||
|
label="Имя"
|
||||||
|
onChange={(text) => store.updateForm({ name: text.replaceAll("\n", "") })}
|
||||||
|
/>
|
||||||
|
<CoreInput
|
||||||
|
trim={true}
|
||||||
|
label="Команда для запуска"
|
||||||
|
onChange={(text) => store.updateForm({ script: text.replaceAll("\n", "") })}
|
||||||
|
/>
|
||||||
<InputV2
|
<InputV2
|
||||||
label="FormBuilder Result"
|
label="FormBuilder Result"
|
||||||
onChange={(text) => (store.viewModel.formBuilder.result = text)}
|
onChange={(text) => (store.viewModel.formBuilder.result = text)}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue