Exemple #1
0
        /// <summary>
        /// 学習履歴コンテナを削除し、ステータスを変更する。
        /// </summary>
        /// <param name="trainingHistory">対象学習履歴</param>
        /// <param name="status">変更後のステータス</param>
        /// <param name="force">他テナントに対する変更を許可するか</param>
        public async Task ExitAsync(TrainingHistory trainingHistory, ContainerStatus status, bool force)
        {
            //コンテナの生存確認
            if (trainingHistory.GetStatus().Exist())
            {
                var info = await clusterManagementLogic.GetContainerDetailsInfoAsync(trainingHistory.Key, CurrentUserInfo.SelectedTenant.Name, force);

                if (info.Status.Exist())
                {
                    //再確認してもまだ存在していたら、コンテナ削除

                    await clusterManagementLogic.DeleteContainerAsync(
                        ContainerType.Training, trainingHistory.Key, CurrentUserInfo.SelectedTenant.Name, force);
                }

                await trainingHistoryRepository.UpdateStatusAsync(trainingHistory.Id, status, info.CreatedAt, DateTime.Now, force);
            }
            else
            {
                await trainingHistoryRepository.UpdateStatusAsync(trainingHistory.Id, status, force);
            }

            //実コンテナ削除の結果は確認せず、DBの更新を確定する(コンテナがいないなら、そのまま消しても問題ない想定)
            unitOfWork.Commit();
        }
        /// <summary>
        /// 前処理実行を終了させる。
        /// </summary>
        /// <param name="id">前処理ID</param>
        /// <param name="dataId">入力データID</param>
        /// <param name="newStatus">変更後のステータス</param>
        private async Task <IActionResult> ExitAsync(long id, long dataId, ContainerStatus newStatus)
        {
            // データの存在チェック
            var preprocessHistory = await preprocessHistoryRepository.GetPreprocessIncludeDataAndPreprocessAsync(id, dataId);

            if (preprocessHistory == null)
            {
                return(JsonNotFound($"Preprocessing History about Preprocess {id} to Data {dataId} is not found."));
            }
            var status = ContainerStatus.Convert(preprocessHistory.Status);

            if (status.IsOpened() == false)
            {
                // 終了できるのは開放中のコンテナだけ(ローカルの結果を追加することがあるので、Runningとは限らない)
                return(JsonBadRequest($"Preprocessing History {preprocessHistory.Id} is not opened."));
            }
            if (status.Exist())
            {
                // コンテナが動いていれば、停止する
                await clusterManagementLogic.DeleteContainerAsync(
                    ContainerType.Preprocessing, preprocessHistory.Name, CurrentUserInfo.SelectedTenant.Name, false);
            }

            preprocessHistory.CompletedAt = DateTime.Now;
            preprocessHistory.Status      = newStatus.Key;
            unitOfWork.Commit();

            return(JsonOK(new HistoriesOutputModel(preprocessHistory)));
        }
        /// <summary>
        /// 前処理コンテナを削除し、ステータスを変更する。
        /// 削除可否の判断が必要なら、呼び出しもとで判定すること。
        /// </summary>
        /// <param name="preprocessHistory">対象前処理履歴</param>
        /// <param name="force">他テナントに対する変更を許可するか</param>
        public async Task <bool> DeleteAsync(PreprocessHistory preprocessHistory, bool force)
        {
            // 前処理結果を削除
            bool result = true;

            foreach (var outputDataId in preprocessHistoryRepository.GetPreprocessOutputs(preprocessHistory.Id))
            {
                //1件でも失敗したら結果はfalse。ただし、エラーが出ても最後まで消し切る。
                result &= await dataLogic.DeleteDataAsync(outputDataId);
            }

            // 前処理履歴の削除
            preprocessHistoryRepository.Delete(preprocessHistory, force);

            // 結果に関わらずコミット
            unitOfWork.Commit();

            var status = ContainerStatus.Convert(preprocessHistory.Status);

            if (status.Exist())
            {
                //コンテナが動いていれば、停止する
                await clusterManagementLogic.DeleteContainerAsync(
                    ContainerType.Preprocessing, preprocessHistory.Name, CurrentUserInfo.SelectedTenant.Name, force);
            }

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// 指定コンテナを削除する
        /// </summary>
        /// <param name="tenant">対象テナント</param>
        /// <param name="name">コンテナ名</param>
        /// <param name="force">Admin権限で実行するか</param>
        private async Task <IActionResult> DeleteContainerAsync(Models.Tenant tenant, string name, bool force)
        {
            //入力チェック
            if (string.IsNullOrWhiteSpace(name))
            {
                return(JsonBadRequest("Name is required."));
            }

            var container = CheckContainerType(name, force);

            switch (container.Item1)
            {
            case ContainerType.TensorBoard:
                //C#は各caseがスコープ共通のため、同一変数名を使えない。止む無く変数名を分ける。
                var trainingLogicForTensorBoard = commonDiLogic.DynamicDi <ITrainingLogic>();
                //TensorBoardコンテナを削除する
                await trainingLogicForTensorBoard.DeleteTensorBoardAsync(container.Item2 as TensorBoardContainer, force);

                break;

            case ContainerType.Training:
                //学習コンテナを強制終了させる
                var trainingLogicForTraining = commonDiLogic.DynamicDi <ITrainingLogic>();
                await trainingLogicForTraining.ExitAsync(container.Item2 as TrainingHistory, ContainerStatus.Killed, force);

                break;

            case ContainerType.Inferencing:
                //推論コンテナを強制終了させる
                var inferenceLogic = commonDiLogic.DynamicDi <IInferenceLogic>();
                await inferenceLogic.ExitAsync(container.Item2 as InferenceHistory, ContainerStatus.Killed, force);

                break;

            case ContainerType.Preprocessing:
                //前処理コンテナを強制終了させる

                //コンテナがいる=前処理中なので、前処理済みデータは無条件で削除できると判断する
                var preprocessLogic = commonDiLogic.DynamicDi <IPreprocessLogic>();
                await preprocessLogic.DeleteAsync(container.Item2 as PreprocessHistory, force);

                break;

            default:
                //正体不明コンテナを削除する
                var result = await clusterManagementLogic.DeleteContainerAsync(ContainerType.Unknown, name, tenant.Name, force);

                if (result == false)
                {
                    return(JsonNotFound($"Container named {name} is not found."));
                }
                break;
            }

            return(JsonNoContent());
        }
        public async Task <IActionResult> Delete(long?id)
        {
            //データの入力チェック
            if (id == null)
            {
                return(JsonBadRequest("Invalid inputs."));
            }
            //データの存在チェック
            var inferenceHistory = await inferenceHistoryRepository.GetByIdAsync(id.Value);

            if (inferenceHistory == null)
            {
                return(JsonNotFound($"Inference ID {id} is not found."));
            }

            //ステータスを確認

            var status = inferenceHistory.GetStatus();

            if (status.Exist())
            {
                //推論がまだ進行中の場合、情報を更新する
                status = await clusterManagementLogic.GetContainerStatusAsync(inferenceHistory.Key, CurrentUserInfo.SelectedTenant.Name, false);
            }

            if (status.Exist())
            {
                //実行中であれば、コンテナを削除
                await clusterManagementLogic.DeleteContainerAsync(
                    ContainerType.Training, inferenceHistory.Key, CurrentUserInfo.SelectedTenant.Name, false);
            }

            //添付ファイルがあったらまとめて消す
            var files = await inferenceHistoryRepository.GetAllAttachedFilesAsync(inferenceHistory.Id);

            foreach (var file in files)
            {
                inferenceHistoryRepository.DeleteAttachedFile(file);
                await storageLogic.DeleteFileAsync(ResourceType.InferenceHistoryAttachedFiles, file.StoredPath);
            }

            await dataSetLogic.ReleaseLockAsync(inferenceHistory.DataSetId);

            inferenceHistoryRepository.Delete(inferenceHistory);
            unitOfWork.Commit();

            // ストレージ内の推論データを削除する
            await storageLogic.DeleteResultsAsync(ResourceType.InferenceContainerAttachedFiles, inferenceHistory.Id);

            await storageLogic.DeleteResultsAsync(ResourceType.InferenceContainerOutputFiles, inferenceHistory.Id);

            return(JsonNoContent());
        }
        public async Task <IActionResult> Delete(long?id)
        {
            //データの入力チェック
            if (id == null)
            {
                return(JsonBadRequest("Invalid inputs."));
            }

            //データの存在チェック
            var notebookHistory = await notebookHistoryRepository.GetByIdAsync(id.Value);

            if (notebookHistory == null)
            {
                return(JsonNotFound($"Notebook ID {id} is not found."));
            }

            //ステータスを確認
            var status = notebookHistory.GetStatus();

            if (status.Exist())
            {
                //Notebookコンテナが起動中の場合、情報を更新する
                status = await clusterManagementLogic.GetContainerStatusAsync(notebookHistory.Key, CurrentUserInfo.SelectedTenant.Name, false);
            }

            if (status.Exist())
            {
                //実行中であれば、コンテナを削除
                await clusterManagementLogic.DeleteContainerAsync(
                    ContainerType.Notebook, notebookHistory.Key, CurrentUserInfo.SelectedTenant.Name, false);
            }

            notebookHistoryRepository.Delete(notebookHistory);
            unitOfWork.Commit();

            // ストレージ内のノートブックデータを削除する
            await storageLogic.DeleteResultsAsync(ResourceType.NotebookContainerAttachedFiles, notebookHistory.Id);

            await storageLogic.DeleteResultsAsync(ResourceType.NotebookContainerOutputFiles, notebookHistory.Id);

            return(JsonNoContent());
        }
        public async Task <IActionResult> DeleteAll()
        {
            var containers = await tensorBoardContainerRepository.GetAllIncludePortAndTenantAsync();

            int  count   = 0;     //削除したコンテナの数
            bool failure = false; //1件でも失敗したか

            LogInformation("コンテナのDBレコード削除、コンテナ強制終了を開始。");

            foreach (TensorBoardContainer container in containers)
            {
                var destroyResult = await clusterManagementLogic.DeleteContainerAsync(ContainerType.TensorBoard, container.Name, container.Tenant.Name, true);

                //コンテナ削除に成功した場合
                if (destroyResult)
                {
                    count++;
                }
                else
                {
                    LogError($"テナント:{container.Tenant.Name}のコンテナ:{container.Name}のコンテナ強制終了時に予期しないエラーが発生しました。");

                    //TensorBoard削除に限り、ミスって削除しても問題が大きくないため、途中でエラーが発生しても最後まで処理し続ける

                    failure = true;
                }

                //DB側も削除する
                //コンテナの削除に失敗したとしても、ログは出しているし、DBに残していてもできる事がないので、無視して削除する
                tensorBoardContainerRepository.Delete(container, true);
            }
            unitOfWork.Commit();
            if (failure)
            {
                //1件以上失敗しているので、エラー扱い
                return(JsonError(HttpStatusCode.ServiceUnavailable, $"failed to delete some tensorboard containers. deleted: {count}"));
            }
            else
            {
                return(JsonOK(count));
            }
        }
        public async Task <IActionResult> Delete(long?id)
        {
            //データの入力チェック
            if (id == null)
            {
                return(JsonBadRequest("Invalid inputs."));
            }
            //データの存在チェック
            var trainingHistory = await trainingHistoryRepository.GetByIdAsync(id.Value);

            if (trainingHistory == null)
            {
                return(JsonNotFound($"Training ID {id} is not found."));
            }

            //ステータスを確認

            var status = trainingHistory.GetStatus();

            if (status.Exist())
            {
                //学習がまだ進行中の場合、情報を更新する
                status = await clusterManagementLogic.GetContainerStatusAsync(trainingHistory.Key, CurrentUserInfo.SelectedTenant.Name, false);
            }

            //派生した学習履歴があったら消せない
            var child = trainingHistoryRepository.Find(t => t.ParentId == trainingHistory.Id);

            if (child != null)
            {
                return(JsonConflict($"There is another training which is derived from training {trainingHistory.Id}."));
            }

            //学習結果を利用した推論ジョブがあったら消せない
            var inference = inferenceHistoryRepository.Find(t => t.ParentId == trainingHistory.Id);

            if (inference != null)
            {
                return(JsonConflict($"Training training {trainingHistory.Id} has been used by inference."));
            }

            if (status.Exist())
            {
                //実行中であれば、コンテナを削除
                await clusterManagementLogic.DeleteContainerAsync(
                    ContainerType.Training, trainingHistory.Key, CurrentUserInfo.SelectedTenant.Name, false);
            }

            //TensorBoardを起動中だった場合は、そっちも消す
            TensorBoardContainer container = tensorBoardContainerRepository.GetAvailableContainer(trainingHistory.Id);

            if (container != null)
            {
                await clusterManagementLogic.DeleteContainerAsync(
                    ContainerType.TensorBoard, container.Name, CurrentUserInfo.SelectedTenant.Name, false);

                tensorBoardContainerRepository.Delete(container, true);
            }

            //添付ファイルがあったらまとめて消す
            var files = await trainingHistoryRepository.GetAllAttachedFilesAsync(trainingHistory.Id);

            foreach (var file in files)
            {
                trainingHistoryRepository.DeleteAttachedFile(file);
                await storageLogic.DeleteFileAsync(ResourceType.TrainingHistoryAttachedFiles, file.StoredPath);
            }

            trainingHistoryRepository.Delete(trainingHistory);
            unitOfWork.Commit();

            return(JsonNoContent());
        }