最終更新: a few seconds agoRemove Netlify-related code from main (grafted, HEAD)

CIRCUS CS Docker 化 打合せ記録など

2018-05-14

Plugin Manager Queue Management System

  • とりあえず single thread を想定して作成して良い。
  • キューっぽくない機能も実装する

export する関数

  • registerJob(jobId: string, request: pluginJobRequest, priority: number = 0): Promise<void>; - 一般的な優先度付きキューだとこうかも。 - 失敗時例外 - request >>> payload - registerJob() から変更?
  • cancelJob(jobId: string): Promise<result: boolean>; - 要求の削除。 ステータスが in_queue 以外で例外。 - 取り急ぎキューらしからぬMongoDB の検索によって実装する。
  • listQueue();
  • start(): Promise<void> - 自動で一定時間おきに dequeue() を行うプロセス(Deque Daemon)を起動する。
  • stop(): Promise<void> - Deque Daemon を停止する。
  • status() :Promise<"running"|"stopped">; - Deque Daemon の実行状況を確認する。

export しない

  • dequeue(): Promise<boolean> - 現在のキューリストから1つ取り出して、適宜処理を行う。

Plugin Manager Deque Daemon

  • 内部実装上は Deque Daemon と Queue Management System は分離
  • Deque Daemon が Queue Management System を使用するイメージ。

jobId はどこが発行するのか

processing 更新時の問題が存在するため UI 側が発行 する。

DB について

次の 2 種類が存在する。

  1. UI 側が管理するジョブのリスト
    • pluginJobs
  2. PM が使用するキュー管理システムのためのデータ
    • pluginJobQueue
    • JobSeries

疎結合性は諦めた構成になっている。

  • UI が共通で使用する主キーを発行(jobId) - PM 側は、主キーの重複がない前提で作成してよい。 - UI 側(リクエスト側)で、enqueue 失敗のログもとれる。
  • PM はこのキーを用いて、UI 側管理のジョブリストのステータスを更新する。
  • EventEmitter を使用する方法やコールバックを使用する方法などの検討が行われたが、取り急ぎ前述の通りで進める。
  • 理想的な構成ではないので、後々検討?

enqueue 処理

  • priority: 高いものほど先に。同じ優先度は FIFO。 優先度が低いものは常に後回しになる。
interface pluginJobRequest {
	pluginId: string;
	series: jobSeries[];
	priority: number;
	environment: string; // = arguments , deprecated // 3つぐらいの病院で機械学習した結果、パラメータ ... 残す
}
  • export のときに stopped の場合にエラーにするかは検討。
  • 追加実装が容易なので後回し。

dequeue 処理

  1. 前処理
    1. ジョブリスト(UI) へステータス更新を通知
      • UI.mongo 直接書込: processing
    2. 作業用ディレクトリを作成。 jobId をディレクトリ名に使用する。
      • mkdir -p .../${jobId}/{dicom,in,out} 相当
    3. DICOM パーサを使用して、個人情報を排除したファイル群を作成し .../${jobId}/in に設置
      • docker 化したものをいただける。
      • cp .../[seriesUID]/ .../${jobId}/dicom 相当 - circus-rs/src/server/dicom-file-repository/DicomFileRepository.ts - circus-rs-dicom-server - getSeriesLoader(seriesUid: string): Promise<{SeriesLoaderFunction, images}>; - SeriesLoaderFunction = (imgNum: number) => Promise;
      • docker run DICOMPARSE -v .../${jobId}/dicom:/hoge /hoge - OR docker run DICOMPARSE -v .../${jobId}/dicom:/hoge dicom_utility /hoge - ENTRYPOINT を使用?
  2. プラグイン処理
    1. プラグインの Docker image から、 Docker container を作成する (先程の作業用ディレクトリをマウントする)
      • docker container create --name ${jobIdAsContainerName} ${pluginImage} 相当
    2. 作成したコンテナを開始する。
      • docker start ${jobIdAsContainerName} 相当
    3. 作成したコンテナのステータスを監視する。
      • docker ps -f "name=${jobIdAsContainerName}"
      • docker inspect ${jobIdAsContainerName}0.State あたりを定期確認する。
    4. コンテナの正常終了
      • 良かったね。
    5. コンテナのタイムアウト
      • docker rm -f ${jobIdAsContainerName} 相当で、強制的にコンテナを削除
      • この場合でも後処理へは進める
  3. 後処理
    1. プラグインの正常終了判定
      • 出力データ .../${jobId}/out の確認
    2. 出力の転送
      • ファイル転送??????
    3. ジョブリスト(UI) へステータス更新を通知
      • UI.mongo 直接書込: finished+ results.txt の パース後データ
      • UI.mongo 直接書込: failed + FAILED 内容 message,
    4. 作業用ディレクトリの削除
      • 失敗 > エラーログ
    5. 十分に古いキューデータを削除
      • 失敗 > エラーログ
      • production: 5 分
      • develop 1 日

1.3. ファイルの分離例(1 series につき 3 ファイルが作成される)

const request: pluginJobRequest = {
	pluginId: string = ......,
	series: jobSeries[] = [ s1: JobSeries, s2:JobSeries, s3: JobSeries ],
	priority: number = ....,
	environment: string = .....
}
000.raw, 000.mhd, 000.txt // s1 のファイル群
001.raw, 001.mhd, 001.txt // s2 のファイル群
002.raw, 002.mhd, 002.txt // s3 のファイル群

その他

  • 三木先生の感覚で 10 日位の作業。

課題

  • dequeue 1.3 DICOM Parser の実装について - RS の DICOMParser を使用できるのでは? - Dicom タグを txt に変換する部分がないので実装が必要。 - dicom_voxel_dump Linux 版がある ? - circus_cs_plugin_job_manager_win/source/CreateVolumeData.cpp - circus-dicom-utility/source/CreateVolumeData.cpp - もし Linux 版があれば、当座の使用では問題ない。 - 将来的にブラウザ側で個人情報の抜き取りを実装する上では、Javascript 版の強化をしておきたいが...

2018-05-15

疑問点

  • dequeue 1.3 DICOM Parser の実装について - circus_cs_plugin_job_manager_win\source\CreateVolumeData.h - Linux 版がある
  • dequeue 3.2 出力データはどうやって UI 側へ渡すのか。
  • dequeue 3.5 後処理順序の調整とキュー削除に関する動作の調整

出力には 2 種類あって、 - mongo 行きデータ - csv など - mongo にカカないデータ - 特殊なファイルを作成した、など

結果ディレクトリ: 固定。 BASE_DIR: 三木先生から固定で頂く /..../plugin_results/{$jobId}/{results.txt, ...rest}

MongoDB の pluginJobs の該当するジョブの status, finishedAt, updatedAt をそれぞれ適切に更新する。作業ディレクトリの /out 配下の内容をジョブ結果ディレクトリにコピーする。作業ディレクトリの /out/results.txt を読み込んで JSON として解釈する。 /out/results.txt の内容について JSON Schema によるバリデーションをかける。 >> raise exception or - エラーの内容の行き先は ... UIの DB 作業ディレクトリを適切に削除する。 (キューからジョブを削除する)

JSON Schema

Ajv

  • async 使用可能 \192.168.0.81\kano\work\circus\circus-api\src\createValidator.js