ベンダー製品付属のCLIを利用する時によくあるケースですが、非同期なサービス起動コマンドを実行した後に定期的にステータスを取得し、ステータス=処理完了が真になるまでループを回すことはよくありますが、そのようなサービス起動完了を同期待ちする汎用関数sync_wait()
を実装してみました。
例えば、フェイルオーバー発生後の待機系ホストのサービス起動完了を同期待ちする用途などで使えそうです。
バージョン
$ bash --version
GNU bash, version 4.3.30(1)-release (i586-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
sync_wait 関数の仕様
sync_wait()
の第1引数には、サービス状態を判定するコールバック関数(is_service_online
)を文字列リテラルで指定します。第2引数に指定した値が、コールバック関数の戻り値と一致するまで(=オンライン状態が検知されるまで)、本関数で同期待ちをします。第3引数に指定した秒数を超えてもオンライン状態が検知されない場合、タイムアウト発生とみなします。
libsample.sh
# !/bin/bash
set -u
#
# Wait until callback function returns expected status.
#
sync_wait()
{
local callbackfn="$1"
local status_expected="$2"
local timeout_s="$3"
local elapsed_s=0
for((; ; elapsed_s++)){
${callbackfn}
[[ $? -eq ${status_expected} ]] && return 0
[[ ! ${elapsed_s} -lt ${timeout_s} ]] && break
sleep 1
}
return 1
}
sync_wait 関数の使い方
sample.sh
# !/bin/bash
set -u
. ./libsample.sh
#
# Check if service is online.
#
is_service_online()
{
# TODO : サービスの状態を取得するコマンドを実行し
# TODO : その標準出力結果をawkとかでごりごり解析して
# TODO : オンラインなら1、それ以外は0を返す処理をここに書く。
}
#
# Main
#
sync_wait "is_service_online" 1 10
status=$?
if [[ ${status} -ne 0 ]]; then
echo "Timeout occurred. (${status})"
exit 1
fi
echo "Service is online. (${status})"
#
# TODO : 後続処理
#
exit 0