prompt-defer.bash (5784B)
1 # blesh/contrib/prompt-defer.bash (C) 2021, akinomyoga 2 3 function ble/contrib/prompt-defer/.worker { 4 local prefix=$1 5 local tmpfile=$_ble_base_run/$$.prompt.defer.$prefix 6 ble/contrib/prompt-defer:"$prefix"/worker 7 ble/util/put "$?" >| "$tmpfile" 8 } 9 10 function ble/contrib/prompt-defer/.finalize { 11 local prefix=$1 12 local tmpfile=$_ble_base_run/$$.prompt.defer.$prefix 13 ble/util/set "${prefix}_DEFER_bgpid" '' 14 15 local ext 16 ble/util/readfile ext "$tmpfile" 17 ble/util/setexit "$ext" 18 ble/contrib/prompt-defer:"$prefix"/callback 19 20 local ret; ble/util/clock 21 ble/util/set "${prefix}_DEFER_clock" "$ret" 22 } 23 24 function ble/contrib/prompt-defer/clear { 25 local prefix=$1 script=' 26 [[ $PREFIX_DEFER_bgpid ]] && 27 builtin kill -9 "$PREFIX_DEFER_bgpid" &>/dev/null 28 PREFIX_DEFER_index= 29 PREFIX_DEFER_hash1= 30 PREFIX_DEFER_hash2= 31 PREFIX_DEFER_clock= 32 PREFIX_DEFER_bgpid=' 33 builtin eval -- "${script//PREFIX/$prefix}" 34 } 35 36 ## @fn ble/contrib/prompt-defer/submit prefix [hash1] [hash2] [opts] 37 ## @param[in] prefix 38 ## 関連変数の接頭辞を指定します。 39 ## 40 ## @fn ble/comtrib/prompt-defer:$prefix/clear 41 ## これまでに取得した情報を初期化します。後述の hash1 が前回の呼 42 ## び出しと異なる際に親シェルで呼び出されます。 43 ## 44 ## @fn ble/comtrib/prompt-defer:$prefix/worker 45 ## バックグラウンドの別プロセスで実行する処理を記述します。bash 46 ## 4.0 以降ではサブシェルで呼び出されます。bash 4.0 未満では非同 47 ## 期に処理できない為、親シェルで実行されます。 48 ## 49 ## @fn ble/comtrib/prompt-defer:$prefix/callback 50 ## バックグラウンドの処理が完了した時に親シェルで呼び出される関 51 ## 数です。$? に worker の終了ステータスが設定された状態で呼び出 52 ## されます。 53 ## 54 ## @var[internal] ${prefix}_DEFER_index 55 ## @var[internal] ${prefix}_DEFER_hash1 56 ## @var[internal] ${prefix}_DEFER_hash2 57 ## @var[internal] ${prefix}_DEFER_clock 58 ## @var[internal] ${prefix}_DEFER_bgpid 59 ## 内部で使用する変数です。 60 ## 61 ## @param[in] hash1 62 ## この値が前回の呼び出しと異なる時に強制的に情報の更新を行います。 63 ## 64 ## @param[in] hash2 65 ## この値が前回の呼び出しと異なりかつ前回の呼び出しから十分時間が 66 ## 経っている時に情報の更新を行います。 67 ## 68 ## @param[in,opt] opts 69 ## コロン区切りのオプションです。 70 ## 71 ## cooling=NUM 72 ## ミリ秒(整数)で情報のタイムアウトを指定します。プロンプト番号 73 ## または hash2 が前回と異なりかつ此処で指定した時間経過している 74 ## 場合に再度情報更新を行います。 75 ## 76 ## cooling-lines=NUM 77 ## プロンプト更新回数を指定します。プロンプト番号が此処で指定し 78 ## た回数以上変化している場合に再度情報更新を行います。 79 ## 80 ## expires[=NUM] 81 ## ミリ秒(整数)で情報のタイムアウトを指定します。プロンプト更新 82 ## の際に指定した時間経過している場合、強制的に情報更新を行いま 83 ## す。既定値は 60000 (1分) です。 84 ## 85 ## sync=NUM 86 ## ミリ秒(整数)で同期的な情報取得のタイムアウトを指定します。 87 ## 88 function ble/contrib/prompt-defer/submit { 89 local prefix=$1 opts=$4 90 local tmpfile=$_ble_base_run/$$.prompt.defer.$prefix 91 local rbgpid=${prefix}_DEFER_bgpid 92 93 local opt_cooling=1000 opt_expires=none opt_nprompt=10 opt_sync=5 ret 94 ble/opts#extract-last-optarg "$opts" cooling && opt_cooling=$ret 95 ble/opts#extract-last-optarg "$opts" cooling-lines && opt_nprompt=$ret 96 ble/opts#extract-last-optarg "$opts" expires 60000 && opt_expires=$ret 97 ble/opts#extract-last-optarg "$opts" sync 60000 && opt_sync=$ret 98 99 local oindex=${prefix}_DEFER_index; oindex=${!oindex-} 100 local ohash1=${prefix}_DEFER_hash1; ohash1=${!ohash1-} 101 local ohash2=${prefix}_DEFER_hash2; ohash2=${!ohash2-} 102 local oclock=${prefix}_DEFER_clock; oclock=${!oclock-} 103 104 local nindex=$_ble_prompt_version 105 local nhash1=${2-done} # 強制 update を誘起する hashref 106 local nhash2=${3-done} # 107 108 local update= 109 if [[ $nhash1 != "$ohash1" ]]; then 110 update=1 111 ble/contrib/prompt-defer:"$prefix"/clear 112 elif [[ ! ${!rbgpid} ]]; then 113 if [[ $nindex:$nhash2 != "$oindex:$ohash2" ]]; then 114 if ((nindex<=oindex-opt_nprompt||oindex+opt_nprompt<=nindex)) || { local ret; ble/util/clock; ((ret>=oclock+opt_cooling)); }; then 115 update=1 116 fi 117 elif [[ $opt_expires && $opt_expires != none ]]; then 118 if local ret; ble/util/clock; ((ret>=oclock+opt_expires)); then 119 update=1 120 fi 121 fi 122 fi 123 124 if [[ $update ]]; then 125 ble/util/set "${prefix}_DEFER_index" "$nindex" 126 ble/util/set "${prefix}_DEFER_hash1" "$nhash1" 127 ble/util/set "${prefix}_DEFER_hash2" "$nhash2" 128 129 if ble/is-function ble/util/idle.push; then 130 if [[ ${!rbgpid} ]]; then 131 builtin kill -9 "${!rbgpid}" &>/dev/null 132 ble/util/idle.cancel "ble/contrib/prompt-defer/.finalize $prefix" 133 ble/util/set "$rbgpid" '' 134 fi 135 136 : >| "$tmpfile" 137 ble/util/set "$rbgpid" "$(ble/util/nohup 'ble/contrib/prompt-defer/.worker $prefix' print-bgpid)" 138 ((opt_sync>0)) && ble/util/msleep "$opt_sync" 139 if [[ -s $tmpfile ]]; then 140 ble/contrib/prompt-defer/.finalize "$prefix" 141 else 142 ble/util/idle.push -F "$tmpfile" "ble/contrib/prompt-defer/.finalize $prefix" 143 fi 144 145 else 146 ble/contrib/prompt-defer:"$prefix"/worker 147 ble/contrib/prompt-defer:"$prefix"/callback 148 fi 149 fi 150 }