Revision 2.2 - kisapapa1227/retrek-ui_V2 GitHub Wiki

主な変更:job管理用システムの導入

exe.py の進捗に関して(現状の不具合)

setInterval+ajax by javascript in blade.php で、exe.py の進捗具合のモニター、及び、不具合(exe.py が落ちた時)の対応をすると ブラウザーのタブがフォーカスされていないと、(ajax がさぼるので)上手くいかない --> setInterval のタイミングで処理が行われず、プロセスがハングアップしていると誤認識する。

タブが最小化されていても、ジョブ管理が適切に出来るように、

  1. 管理用プロセス(python)
  2. 進捗テーブル (mysql) で管理する。blade は、プロセスと作業結果を見に行くのではなく、データベースを読みに行く。

基本的な流れ、方針

現状の枠組みだと、単一ユーザーの複数 login 可能、かつ、中間ファイルに端末情報を入れていないので、単一ユーザで流せる探索は1系統にしないと不具合が起きる。 タイミングとしては、スクリプトを作る段階で判別する必要あり。 並列の探索を制限するためには、実行 job がある場合、multiProc へ飛ばし、multiSearchへの経路をなくす。job制御のプロセスを立ち上げ、GUI側を閉じてしまっても、計算は続ける。計算中でも menu に戻り、データベースは利用できるようにする。<-- 利用中のデータベースの削除は制限する。

pdf 作成の流れ(Rev 2.0 の確認)

  1. 探索(1)では、$uid/report に $substance.txt が作られる。そのファイル内に、指定した数の routes が書き込まれると
  2. exe.py の中から、make_report/routeAnalyzer.py が呼び出され、$uid/report/$substance.pdf が作られる。
  3. 共有データベースだと、$uid/report/$substance.pdf を report/$tableId.pdf に移動する。
    1. (これから)個人用データベースだと、$uid/report/$substance.pdf を $uid/report/$tableId.pdf とリネーム。
  4. 探索(1)だと、ボタン駆動で addDb を呼び出し、RetRekController.php 経由で、make_report/addDb.py を呼び出す。
    1. データベースの置き場所は固定で、RetReKで共有が sList.db で、個人用が sList$uid.db
    2. (重複するが)routeAnalyzer と同じ作業で、$substance.txt を解析、整理した結果をデータベースに登録する。
    3. (これから)探索(2)でも作業は同じだが、別プロセスでのジョブ投入、データベース管理の導入で、並列管理。
  5. データベース管理画面から作成する場合(pdf/pptx/db)共通で、syncPdf on RetRekController.php より
    1. make_report/readDb.py で作成する。出力ディレクトリーは -d で変更可能。ファイル名は、$tableId.pdf

仕様の整理

投げっぱなしで ok 。

  1. Controller でスクリプトを作成して、userId を渡して jobMaster を起動する。
    1. データベースへ情報の受け渡し方法は? <-- $uid_async.sh から読む。
    2. 引数で -start uid max_loop で開始、jobMaster -ask uid で情報を引き出す。
    3. uid_async.sh を有効利用。#abort:false_smiles、false_config、#smiles:$smiles の行を入れて受け渡す。
      1. Controller で、false_smiles (引数の不正)の場合には、script に #false:*** の行を入れる。
  2. jobMaster.db のテーブル
    1. Master(userId,max_job,running_job,exp_time):running_job>max_job で終了。
    2. Slave(userId,#,smiles,available,done,repeated,start_time,end_time,exp_time)
      1. 投入回数を repeated に記録して、たとえば、5回投入して落ちる場合は、なにかおかしい!ので、次のジョブに進む。
      2. 開始時刻、実行時間、終了時刻など、multiProc.php で必要な物はデータベースで保持する。
  3. multiSearch/SingleSearch を呼んだ時、検索中なら、進捗画面へ移動する。
    1. Master where userId で 実行中がないか確認する。-> multiProc へ飛ぶ
  4. (ありえないけど)jobMaster が落ちたら再起動する。
    1. cron で再起動する。*1
  5. multiProc のボタンを
    1. 実行中の Master を落として、戻る。
    2. 実行のまま menu に戻る。1.
  6. multiProc.blade の進捗表示に関して
    1. askProc を利用、images/$uid/$substance.txt を読みに行く。
    2. プロセスの有無、及び、kill するときは、無差別!人のjob も瞬殺。
    3. <-- 別もあるけど、processId を持っている必要がある。 exe.py に $uid を付けてるので、これで選別できる。
    4. singleSearch/multiSearchが並走する場合には? 判断できないので、singleSearch は投入後に Masetr.db に登録する必要あり。
    5. single user, single job: ジョブ実行中には、検索設定画面を開かせない。
    6. データベース任せで、自分では処理をしない。

cron の仕事 (jobMaster.py -start が行う)

  1. 作業

    1. Dockerfile に apt install -y cron を加える。Dockerfile では、複数のフロントプロセスは実行できない。。らしいので
      1. supervisord.conf に実行スクリプトを入れる。
    2. 実行記録 jobMaster.lock を作る。$uid を書き込む。
    3. crontab に、自分 (jobMaster.py) が落ちた時に、jobMaster.py -restart -uid uid を実行する。
    4. jobMaster.py -start/restart は、終了時に、jobMaster.lock を消す。crontab も消す。
      1. 足す場合:(crontab -l ; echo * * * * * command) | crontab -
      2. 消す場合:(crontab -l | grep -v command) | crontab -
  2. cron で、ps aux | grep uid | grep jobMaster.py が無ければ、jobMaster.py -restart -uid uid で再実行。

    1. jobWatcher.py
  3. askMakeScript($n,$l):変更なし

  4. multiProc($request) <-- blade からの繰り返し

    1. script を作り、jobMaster.py を起動する。それ以外の作業は、jobMaster.py へ移植。i.e.)ジョブ管理は Laravel から独立させる。
  5. askProc: データベースから貰う。

    1. singleSearch/Proc 用に残すが、逐次探索では利用しない。

cron を supervisord から起動する。

cat supervisord.conf
[program:cron]
command=cron -f
stdout_logfile=/tmp/cron.log
redirect_stderr=true

container 内で、

$service cron status
* cron is running

で確認。

作業手順

  1. 何はともあれ、jobMaster.py を動かす。(済)
  2. Controllerの変更
    1. multiProc で、script の作成、async_jobMaster.sh (jobMaster.py) の実行(済)
  3. multiProc.blade の変更
    1. 必要な物はすべて、askProc から貰う。持ち物は $uid/$db_type のみ。
    2. kRet は、sail, python, $uid を含むすべて止める。
    3. mRet でジョブを残したまま、menu の戻る。
    4. デーベースへの追加 ? jobMaster の仕事

jobMaster.py の詳細(仕様)

  1. -start -uid uid -max_loop 10 -db_type com データベースへ投入、動かす。
    1. テーブルを作る。
      1. master(user_id,max_loop,running_job,db_type,exp_time,abort)
      2. slave(user_id,script_id,smiles,substance_name,found_route,max_route,done,start_time,end_time)
        1. abort: 再投入=ジョブが終了したが、found_route と max_route が一致しなかった場合に再計算
    2. 両テーブル(master/slave)から、前のレコード where uid=$uid を delete する。
      1. master/slave にレコードを update する
    3. ジョブ(script)を非同期で逐次実行する。<-- &つきなので、仮に同期でもすぐに戻って来る!
      1. done in slave が "ready" でない場合は何もしない。
      2. master/slave の running_job/done,start_time を update する。
      3. 投入で、time.sleep でループ、終了待ち
        1. プロセスの有無をチェックする。<-- ps aux |grep exp.py | grep $uid
        2. どこまで進んでいるかは $substance.txtを読みに行く。
        3. 進捗があれば、master/salve (exp_time/found_route) を update
        4. プロセスが無ければ、終了処理。
          1. found != route の場合、abort をカウントアップして、再実行。
          2. slave の done="Complete"で終了。
    4. ジョブ終了
      1. addDb.py を呼んで、sList.db/sList$uid/db に追加する。
      2. readDb.py を呼んで、pdf を作る。
  2. -restart -uid uid : jobMaster.py が落ちていた場合に再開する。
    1. 実行中は ~/jobMaster.lock を作成、user_id を書き込む。終了したら消す。
    2. crone で見張って、jobMaster.lock が存在した場合、user_id を読み出して、restart する。
    3. 小さなことだが、実行中の exe.py があると無駄なので、
      1. kill するか、継続するか?こだわらずに放置か、時間があったら kill かな。
  3. -ask -uid uid -pid pid: 進捗情報を取得する。実行中のジョブ番号+"###"に続いて
    1. 実行中のジョブ番号と指定した pid が一致する場合は、検索済みルート数、、、、経過時間、終了時刻などを返す。
    2. 一致しない場合は、ジョブリストを返す。

multiSearch.php の詳細(仕様)

  1. スクリプトの作成、jobMaster.php の呼び出し
  2. jobMaster.py getPid で $uid で exe.py の起動確認
    1. なければ、通常通り multiSearch.blade の呼び出し
    2. あれば、multiProc.bladeへ

mutliProc.blade の詳細(仕様)

  1. 「処理継続で戻る」を追加

singleSearch.php の詳細(仕様)

  1. multiSearch.php と同様

dbManage.blade

  1. jobMaster.py の起動中は db の削除、復元(=上書き)は禁止する。
    1. controller から dbMange を呼ぶときにチェックする。

動作確認中に起きた、cron/jobMaster.py の二重起動が起きた条件の検討

  1. jobWatcher.py が、jobMaster.py -uid $uid の有無を確認して再実行する。
    1. CUIで、同時に、二つ jobMaster.py -restart を投げれば、起きるかもしれないが、cron 管理なので起こらない。
  2. jobMaster.py では、-start オプション時に、batch table 作成、jobMaster.lock 作成、正常終了時に削除する。

不具合:ルートが見つからなかった場合

  1. addDb.py が落ちる。
    1. exe.py が見つからなかった場合に、要求数 smiles; と言う列を送ってくる。
    2. 同じルートを削除でまとめると、反応なしのルートが一つ見つかる。<-- 反応ありのルートが一つと区別がつかない。
    3. とりあえず、中途まで処理をすると、繋がりなし(len(connect)<1) になったら exit() <-- 検索条件は table に書き込み済み。
  2. readDb.py 側の処理。
    1. 対応するテーブル (searchTable$pid)が無い場合のしょり、

関連ファイル

  1. resouce/views/db.blade.php, dbManager.blade.php, menu.blade.php, multiProc.blade.php
  2. resources/js/Pages/Auth/Login.vue
  3. routes/web.php
  4. ReTReKpy/addDb.py, jobMaster.py, jobWatcher.py, readDb.py
  5. (installer)UninstallImages.sh
  6. docker/8.3/Dockerfile