From 4585d079f69c9e029e07f8b0d200ca595d249ec0 Mon Sep 17 00:00:00 2001 From: IDONTSUDO Date: Fri, 3 May 2024 21:30:18 +0300 Subject: [PATCH] progress --- server/src/core/controllers/app.ts | 1 + ...e_pipeline_to_realtime_service_scenario.ts | 4 +- .../usecases/search_database_model_usecase.ts | 2 +- .../search_many_database_model_usecase.ts | 18 ++++++++ .../domain/create_dataset_scenario.ts | 4 +- .../get_dataset_active_project_scenario.ts | 4 +- .../domain/get_active_project_scenario.ts | 6 +-- .../domain/exec_weights_process_scenario.ts | 2 +- ...et_all_weights_active_project_scenarios.ts | 11 +++++ .../models/weights_validation_model.ts | 1 + .../features/weights/weights_presentation.ts | 2 + server/src/main.ts | 1 - ui/src/features/skils/skill_card.tsx | 10 +++-- ui/src/features/skils/skill_model.ts | 20 +++++++-- .../features/skils/skill_socket_repository.ts | 31 +++++++++++++ ...ository.tsx => skills_http_repository.tsx} | 0 ui/src/features/skils/skills_screen.tsx | 15 +++++-- ui/src/features/skils/skills_store.tsx | 44 +++++++++++++++---- .../features/socket_lister/socket_lister.tsx | 3 ++ 19 files changed, 149 insertions(+), 30 deletions(-) create mode 100644 server/src/core/usecases/search_many_database_model_usecase.ts create mode 100644 server/src/features/weights/domain/get_all_weights_active_project_scenarios.ts create mode 100644 ui/src/features/skils/skill_socket_repository.ts rename ui/src/features/skils/{skills_repository.tsx => skills_http_repository.tsx} (100%) diff --git a/server/src/core/controllers/app.ts b/server/src/core/controllers/app.ts index a65ba2f..8908e2e 100644 --- a/server/src/core/controllers/app.ts +++ b/server/src/core/controllers/app.ts @@ -124,3 +124,4 @@ export class App extends TypedEvent { return rootDir + "public/"; }; } + diff --git a/server/src/core/scenarios/set_active_pipeline_to_realtime_service_scenario.ts b/server/src/core/scenarios/set_active_pipeline_to_realtime_service_scenario.ts index fa4bf7d..38d9ad5 100644 --- a/server/src/core/scenarios/set_active_pipeline_to_realtime_service_scenario.ts +++ b/server/src/core/scenarios/set_active_pipeline_to_realtime_service_scenario.ts @@ -5,12 +5,12 @@ import { import { pipelineRealTimeService } from "../../features/_realtime/realtime_presentation"; import { App } from "../controllers/app"; import { CreateFolderUseCase } from "../usecases/create_folder_usecase"; -import { SearchDataBaseModelUseCase } from "../usecases/search_database_model_usecase"; +import { SearchOneDataBaseModelUseCase } from "../usecases/search_database_model_usecase"; export class SetLastActivePipelineToRealTimeServiceScenario { call = async (): Promise => { return ( - await new SearchDataBaseModelUseCase(ProjectInstanceDbModel).call({ + await new SearchOneDataBaseModelUseCase(ProjectInstanceDbModel).call({ isActive: true, }) ).fold( diff --git a/server/src/core/usecases/search_database_model_usecase.ts b/server/src/core/usecases/search_database_model_usecase.ts index c8e6fd4..3f8e4d0 100644 --- a/server/src/core/usecases/search_database_model_usecase.ts +++ b/server/src/core/usecases/search_database_model_usecase.ts @@ -1,6 +1,6 @@ import { Result } from "../helpers/result"; -export class SearchDataBaseModelUseCase { +export class SearchOneDataBaseModelUseCase { model: any; constructor(model: any) { diff --git a/server/src/core/usecases/search_many_database_model_usecase.ts b/server/src/core/usecases/search_many_database_model_usecase.ts new file mode 100644 index 0000000..ea7db85 --- /dev/null +++ b/server/src/core/usecases/search_many_database_model_usecase.ts @@ -0,0 +1,18 @@ +import { Result } from "../helpers/result"; + +export class SearchManyDataBaseModelUseCase { + model: any; + + constructor(model: any) { + this.model = model; + } + + call = async (findFilter: Partial, error: string = "not found database"): Promise> => { + const result = await this.model.find(findFilter); + if (result === null) { + return Result.error(error); + } else { + return Result.ok(result); + } + }; +} diff --git a/server/src/features/datasets/domain/create_dataset_scenario.ts b/server/src/features/datasets/domain/create_dataset_scenario.ts index 22fe73a..330fda4 100644 --- a/server/src/features/datasets/domain/create_dataset_scenario.ts +++ b/server/src/features/datasets/domain/create_dataset_scenario.ts @@ -4,7 +4,7 @@ import { Result } from "../../../core/helpers/result"; import { TypedEvent } from "../../../core/helpers/typed_event"; import { EXEC_EVENT, ExecError, SpawnError } from "../../../core/models/exec_error_model"; import { ExecutorResult } from "../../../core/models/executor_result"; -import { SearchDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase"; +import { SearchOneDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase"; import { IProjectModel, ProjectDBModel } from "../../_projects/models/project_database_model"; import { DatasetDBModel } from "../models/dataset_database_model"; import { DatasetValidationModel, ProcessStatus } from "../models/dataset_validation_model"; @@ -53,7 +53,7 @@ export class CreateDataSetScenario extends CallbackStrategyWithValidationModel { return ( - await new SearchDataBaseModelUseCase(ProjectDBModel).call({ isActive: true }, "no active projects") + await new SearchOneDataBaseModelUseCase(ProjectDBModel).call({ isActive: true }, "no active projects") ).map(async (project) => { model.processStatus = ProcessStatus.NEW; model.local_path = project.rootDir; diff --git a/server/src/features/datasets/domain/get_dataset_active_project_scenario.ts b/server/src/features/datasets/domain/get_dataset_active_project_scenario.ts index d5cd6c7..f99adb2 100644 --- a/server/src/features/datasets/domain/get_dataset_active_project_scenario.ts +++ b/server/src/features/datasets/domain/get_dataset_active_project_scenario.ts @@ -1,13 +1,13 @@ import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controllers/http_controller"; import { Result } from "../../../core/helpers/result"; -import { SearchDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase"; +import { SearchOneDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase"; import { IProjectModel, ProjectDBModel } from "../../_projects/models/project_database_model"; import { DatasetDBModel } from "../models/dataset_database_model"; export class GetDatasetActiveProjectScenario extends CallbackStrategyWithEmpty { call = async (): ResponseBase => { return ( - await new SearchDataBaseModelUseCase(ProjectDBModel).call({ isActive: true }, "no active projects") + await new SearchOneDataBaseModelUseCase(ProjectDBModel).call({ isActive: true }, "no active projects") ).map(async (project) => { return Result.ok(await DatasetDBModel.find({ project: project._id })); }); diff --git a/server/src/features/projects/domain/get_active_project_scenario.ts b/server/src/features/projects/domain/get_active_project_scenario.ts index ecf4b6b..cd6aea0 100644 --- a/server/src/features/projects/domain/get_active_project_scenario.ts +++ b/server/src/features/projects/domain/get_active_project_scenario.ts @@ -1,12 +1,12 @@ import { CallbackStrategyWithEmpty, ResponseBase } from "../../../core/controllers/http_controller"; import { Result } from "../../../core/helpers/result"; -import { SearchDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase"; +import { SearchOneDataBaseModelUseCase } from "../../../core/usecases/search_database_model_usecase"; import { IProjectModel, ProjectDBModel } from "../../_projects/models/project_database_model"; export class GetActiveProjectScenario extends CallbackStrategyWithEmpty { - async call(): ResponseBase { + async call(): Promise> { return ( - await new SearchDataBaseModelUseCase(ProjectDBModel).call({ isActive: true }, "no active projects") + await new SearchOneDataBaseModelUseCase(ProjectDBModel).call({ isActive: true }, "no active projects") ).map((model) => Result.ok({ id: model._id })); } } diff --git a/server/src/features/weights/domain/exec_weights_process_scenario.ts b/server/src/features/weights/domain/exec_weights_process_scenario.ts index 5e6e0f8..92fe0df 100644 --- a/server/src/features/weights/domain/exec_weights_process_scenario.ts +++ b/server/src/features/weights/domain/exec_weights_process_scenario.ts @@ -17,7 +17,7 @@ export class ExecWeightProcessScenario extends CallbackStrategyWithIdQuery { await WeightDBModel.findById(id).updateOne({ processStatus: "RUN" }); return match(model.processStatus) .with("exec", "RUN", "none", () => this.exec(id, model)) - .with("exec", "RUN", () => this.exec(id, model, true)) + .with('before_training' , () => this.exec(id, model, true)) .otherwise(() => Result.error(`model status is ${model.processStatus}`)); }); }); diff --git a/server/src/features/weights/domain/get_all_weights_active_project_scenarios.ts b/server/src/features/weights/domain/get_all_weights_active_project_scenarios.ts new file mode 100644 index 0000000..ec401ab --- /dev/null +++ b/server/src/features/weights/domain/get_all_weights_active_project_scenarios.ts @@ -0,0 +1,11 @@ +import { ResponseBase } from "../../../core/controllers/http_controller"; +import { SearchManyDataBaseModelUseCase } from "../../../core/usecases/search_many_database_model_usecase"; +import { GetActiveProjectScenario } from "../../projects/domain/get_active_project_scenario"; +import { IWeightModel, WeightDBModel } from "../models/weights_validation_model"; + +export class GetAllWeightsActiveProjectScenarios { + call = async (): ResponseBase => + (await new GetActiveProjectScenario().call()).map( + async (model) => await new SearchManyDataBaseModelUseCase(WeightDBModel).call({ project: model.id }) + ); +} diff --git a/server/src/features/weights/models/weights_validation_model.ts b/server/src/features/weights/models/weights_validation_model.ts index ca8b203..d400687 100644 --- a/server/src/features/weights/models/weights_validation_model.ts +++ b/server/src/features/weights/models/weights_validation_model.ts @@ -20,6 +20,7 @@ export const WeightSchema = new Schema({ }, numberOfTrainedEpochs: { type: Number, + default:0, }, neuralNetworkName: { type: String, diff --git a/server/src/features/weights/weights_presentation.ts b/server/src/features/weights/weights_presentation.ts index 8ee308c..b2e89f8 100644 --- a/server/src/features/weights/weights_presentation.ts +++ b/server/src/features/weights/weights_presentation.ts @@ -1,5 +1,6 @@ import { CrudController } from "../../core/controllers/crud_controller"; import { ExecWeightProcessScenario } from "./domain/exec_weights_process_scenario"; +import { GetAllWeightsActiveProjectScenarios } from "./domain/get_all_weights_active_project_scenarios"; import { WeightValidationModel } from "./models/weights_database_model"; import { WeightDBModel } from "./models/weights_validation_model"; @@ -10,6 +11,7 @@ export class WeightsPresentation extends CrudController void; datasetName?: string; + epochNextTraining?: number; } export const SkillCard = (props: ISkillCardProps) => { @@ -52,7 +53,7 @@ export const SkillCard = (props: ISkillCardProps) => { backgroundColor: "#f7f2fa", borderRadius: 10, padding: 10, - width: 150, + width: 200, height: "max-content", alignContent: "center", display: "flex", @@ -86,7 +87,9 @@ export const SkillCard = (props: ISkillCardProps) => {
- + + +
@@ -120,9 +123,10 @@ export const SkillCard = (props: ISkillCardProps) => { { - if (props.startOnClick && props.id) props.startOnClick(props.id); + if (props.continueOnClick && props.id) props.continueOnClick(props.id); }} /> +
{ diff --git a/ui/src/features/skils/skill_model.ts b/ui/src/features/skils/skill_model.ts index 1cd6b80..fb3d39e 100644 --- a/ui/src/features/skils/skill_model.ts +++ b/ui/src/features/skils/skill_model.ts @@ -1,25 +1,39 @@ import makeAutoObservable from "mobx-store-inheritance"; import { Result } from "../../core/helper/result"; -import { ISkils } from "./skills_repository"; +import { ISkils } from "./skills_http_repository"; export class SkillModel { numberOfTrainedEpochs?: number; + id?: string; + constructor( public name: string, public datasetId: string, public project: string, public epoch: number, - numberOfTrainedEpochs?: number + numberOfTrainedEpochs?: number, + id?: string ) { this.numberOfTrainedEpochs = numberOfTrainedEpochs; + this.id = id; makeAutoObservable(this); } + static fromISkill(model: ISkils) { - return new SkillModel(model.name, model.datasetId._id, model.project._id, model.epoch, model.numberOfTrainedEpochs); + return new SkillModel( + model.name, + model.datasetId._id, + model.project._id, + model.epoch, + model.numberOfTrainedEpochs, + model._id + ); } + static empty() { return new SkillModel("", "", "", 0); } + valid(): Result { if (this.name.isEmpty()) { return Result.error("введите имя скила"); diff --git a/ui/src/features/skils/skill_socket_repository.ts b/ui/src/features/skils/skill_socket_repository.ts new file mode 100644 index 0000000..9b2634d --- /dev/null +++ b/ui/src/features/skils/skill_socket_repository.ts @@ -0,0 +1,31 @@ +import { TypedEvent } from "../../core/helper/typed_event"; +import { SocketRepository, socketRepository } from "../../core/repository/socket_repository"; +import { ProcessStatus } from "../dataset/dataset_model"; + +export interface ProcessUpdate { + id: string; + status: ProcessStatus; +} + +export class SkillSocketRepository extends TypedEvent { + socketRepository: SocketRepository = socketRepository; + constructor() { + super(); + this.socketRepository.on((e) => { + if (e.event === "realtime") { + if (e.payload !== undefined && e.payload.value !== undefined && e.payload.value.id !== undefined) { + this.emit({ + id: String(e.payload.value.id), + status: ProcessStatus.END, + }); + } + if (e.payload !== undefined && e.payload.error !== undefined && e.payload.error.id !== undefined) { + this.emit({ + id: String(e.payload.error.id), + status: ProcessStatus.ERROR, + }); + } + } + }); + } +} diff --git a/ui/src/features/skils/skills_repository.tsx b/ui/src/features/skils/skills_http_repository.tsx similarity index 100% rename from ui/src/features/skils/skills_repository.tsx rename to ui/src/features/skils/skills_http_repository.tsx diff --git a/ui/src/features/skils/skills_screen.tsx b/ui/src/features/skils/skills_screen.tsx index 1505431..65195ba 100644 --- a/ui/src/features/skils/skills_screen.tsx +++ b/ui/src/features/skils/skills_screen.tsx @@ -39,7 +39,7 @@ export const SkillScreen = observer(() => {
{ processStatus={el.processStatus} empty={false} epoch={el.numberOfTrainedEpochs} + epochNextTraining={el.epoch} startOnClick={(id) => store.execSkill(id)} continueOnClick={(id) => store.continueSkill(id)} - onEdit={(id) => store.editSkill(id)} + onEdit={(id) => store.fromEditSkill(id)} + onDelete={(id) => store.deleteSkill(id)} /> ))} store.edtDrawer(DrawersSkill.NEW_SKILL, true)} /> @@ -71,7 +73,14 @@ export const SkillScreen = observer(() => { onClose={() => store.edtDrawer(DrawersSkill.EDIT_SKILL, false)} open={store.drawers.find((el) => el.name === DrawersSkill.EDIT_SKILL)?.status} > - +
+ +
+ store.saveEdiSkill()} /> +
+ store.edtDrawer(DrawersSkill.NEW_SKILL, false)} /> +
+
{ - editSkill(id: string): void { - this.skill = SkillModel.fromISkill(this.getSkillById(id) as ISkils); - - this.edtDrawer(DrawersSkill.EDIT_SKILL, true); - } drawers: Drawer[]; skillsHttpRepository: SkillsHttpRepository; skils?: ISkils[]; @@ -27,6 +24,7 @@ export class SkillStore extends UiErrorState { activeProjectId?: UUID; skill: SkillModel; titleDrawer: string = DrawersSkill.NEW_SKILL; + skillSocketRepository: SkillSocketRepository = new SkillSocketRepository(); constructor() { super(); @@ -38,14 +36,25 @@ export class SkillStore extends UiErrorState { }); this.skill = SkillModel.empty(); this.skillsHttpRepository = new SkillsHttpRepository(); + this.skillSocketRepository.on(this.socketUpdate); makeAutoObservable(this); } + socketUpdate = (data: ProcessUpdate) => { + this.skils?.map((el) => { + if (el._id.isEqual(data.id)) { + el.processStatus = data.status; + } + return el; + }); + }; getSkillById = (id: string) => this.skils?.find((el) => el._id === id); continueSkill = async (id: string) => { const skill = this.getSkillById(id) as ISkils; - skill.processStatus = "new"; + skill.processStatus = "before_training"; + skill.numberOfTrainedEpochs += skill.epoch; await this.skillsHttpRepository.editSkill(skill); - this.messageHttp(this.skillsHttpRepository.execSkill(id), { + + await this.messageHttp(this.skillsHttpRepository.execSkill(id), { errorMessage: "Ошибка", successMessage: "Обучение продолжено", }); @@ -54,6 +63,7 @@ export class SkillStore extends UiErrorState { execSkill = async (id: string) => { const skill = this.getSkillById(id) as ISkils; skill.processStatus = "exec"; + skill.numberOfTrainedEpochs = skill.epoch; await this.skillsHttpRepository.editSkill(skill); this.messageHttp(this.skillsHttpRepository.execSkill(id), { errorMessage: "Ошибка", @@ -72,7 +82,6 @@ export class SkillStore extends UiErrorState { } changeEpoch(epoch: number) { this.skill.epoch = epoch; - } saveSkill() { this.skill.project = this.activeProjectId?.id ?? ""; @@ -94,6 +103,7 @@ export class SkillStore extends UiErrorState { this.skill.datasetId = id; } edtDrawer(drawerName: DrawersSkill, status: boolean): void { + this.titleDrawer = drawerName; this.drawers = this.drawers.map((el) => { if (el.name === drawerName) { el.status = status; @@ -101,4 +111,20 @@ export class SkillStore extends UiErrorState { return el; }); } + deleteSkill = async (id: string): Promise => { + await this.skillsHttpRepository.deleteSkill(id); + await this.init(); + }; + fromEditSkill(id: string): void { + this.skill = SkillModel.fromISkill(this.getSkillById(id) as ISkils); + + this.edtDrawer(DrawersSkill.EDIT_SKILL, true); + } + saveEdiSkill = async () => { + const skillOrigin = this.getSkillById(this.skill.id as string) as ISkils; + skillOrigin.numberOfTrainedEpochs = this.skill.epoch; + + await this.skillsHttpRepository.editSkill(skillOrigin); + this.edtDrawer(DrawersSkill.EDIT_SKILL, false); + }; } diff --git a/ui/src/features/socket_lister/socket_lister.tsx b/ui/src/features/socket_lister/socket_lister.tsx index 04ea360..483dae4 100644 --- a/ui/src/features/socket_lister/socket_lister.tsx +++ b/ui/src/features/socket_lister/socket_lister.tsx @@ -8,6 +8,9 @@ export interface ISocketListerProps { } export const SocketLister = observer((props: ISocketListerProps) => { + React.useEffect(() => { + socketListerStore.init(); + }, []); return (
{/* {socketListerStore.socketHasDisconnect ? (