Ohataさん、こんにちは。
監視機能の中でMirroringの起動時に実行されるメソッドはないかと思います。
ただ、GetSensors()メソッドはデフォルトで30秒ごとに呼ばれますので、$SYSTEM.Mirror.IsPrimary()メソッドの戻り値が0から1になった時点でメソッドを実行することは可能です。
メソッドが呼ばれるタイミングは切り替わった時点よりも遅くなりますが。。。
/// 起動処理サンプル Class MonTest.Test Extends %SYS.Monitor.AbstractSensor { Property Primary As %Boolean; Method Start() As %Status { // todo: ここに処理内容を記述します do ##class(%SYS.System).WriteToConsoleLog("startup test sensor in "_$namespace) // ミラーの状態を保存 set ..Primary=$SYSTEM.Mirror.IsPrimary() Q $$$OK } Method GetSensors() As %Status { set ret=$$$OK set status=$SYSTEM.Mirror.IsPrimary() // 状態が変更されたとき if ..Primary'=status { set ..Primary=status if status {// Primaryに変更されたとき set ret=..BecomePrimary() } } Quit ret } Method BecomePrimary() As %Status { Quit $$$OK } }
Ohataさん
あけましておめでとうございます。本年もよろしくお願いします。
インスタンス起動時に実行されるメソッドですが、モニタークラスを作成し、Startメソッドに必要な処理を記載するのはいかがでしょうか?
1.プロダクションを設定されているネームスペースにて、以下のような%SYS.Monitor.AbstractSensorを継承したクラスを作成し、Start()メソッドに起動時の処理を記述します。
Class MonTest.Test Extends %SYS.Monitor.AbstractSensor
{
Method Start() As %Status
{
// todo: ここに処理内容を記述します
do ##class(%SYS.System).WriteToConsoleLog("startup test sensor in "_$namespace)
Q $$$OK
}
Method GetSensors() As %Status
{
Quit $$$OK
}
}
2.ターミナルを起動し、プロダクションを設定しているネームスペースに移動、システムモニター管理(^%SYSMONMGR)を起動します。
USER> zn "PROD" PROD> do ^%SYSMONMGR
メニューにて 3 (Configure System Monitor Classes) を選択します。
さらに、1 (Configure System Monitor Components) を選択します。
2 (Add Class)を選択し、「Class?」に対してモニタークラス(この例ではMonTest.Test)を入力します。
Enterキーを何度か押し、システムモニター管理を終了します。
3.ターミナルにて%SYSネームスペースに移動し、システムモニター管理を再度起動します。
PROD> zn "%SYS" %SYS> do ^%SYSMONMGR
メニューにて 3 (Configure System Monitor Classes) を選択します。
さらに、2 (Configure Startup Namespaces) を選択します。
2 (Add Namespace)を選択し、「Namespace?」に対してプロダクションを設定しているネームスペースを入力します。
Namespace? PROD
何度かEnterキーを押して、システムモニター管理を終了します。
4.IRISを再起動します。
以上で、起動時にMonTest.TestクラスのStart()メソッドが実行されるかと思います。
注意点としましてはプロダクションを起動するプロセスとは別のプロセスで実行されますので、プロダクションの自動起動は設定せずに、Startメソッドからプロダクションを起動(Ens.DirectorクラスのStartProductionメソッド)したほうが良いかと思います。







Ohataさん、おはようございます。
ちなみに、私はモジュール単位で独立して起動時や終了時の処理を実行できるようにしたかったので、%ZSTARTや%ZSTOPルーチンは管理クラスから生成するようにしています。
プログラムはこんな感じです。
/// ZSTARTルーチンの生成 /// 起動時やログイン時、プロセス起動時に実行するプログラムを登録し、 /// %ZSTARTルーチンを生成させる /// systemcode ... システム起動時に実行するコード /// logincode ... ログイン時に実行するコード /// jobcode ... プロセス起動時に実行するコード /// /// ※複数行にわたるときはCRLFを挿入する /// モジュール名は%ZLOADERでファイル名から生成されたモジュール名%moduleの値を使用する ClassMethod GenerateZSTART(systemcode As %String = "", logincode As %String = "", jobcode As %String = "") As %Status { if $get(%module)="" { quit $$$ERROR(5001,"モジュール名%moduleが定義されていません") } kill ^%ZModule.Code("ZSTART","SYSTEM",%module) kill ^%ZModule.Code("ZSTART","LOGIN",%module) kill ^%ZModule.Code("ZSTART","JOB",%module) set:systemcode'="" ^%ZModule.Code("ZSTART","SYSTEM",%module)=systemcode set:logincode'="" ^%ZModule.Code("ZSTART","LOGIN",%module)=logincode set:jobcode'="" ^%ZModule.Code("ZSTART","JOB",%module)=jobcode set rtn=##class(%Routine).%New() set rtn.RoutineName="%ZSTART.MAC" set sec="" for { set sec=$order(^%ZModule.Code("ZSTART",sec)) quit:sec="" do rtn.WriteLine(sec_"() public {") set mod="" for { set mod=$order(^%ZModule.Code("ZSTART",sec,mod),1,code) quit:mod="" do:code'="" rtn.WriteLine(code) } do rtn.WriteLine("}") } quit rtn.Compile() }
便宜上、モジュール名は%付き変数で渡していたり、グローバルを使っていたりしますが、
モジュール名と起動、停止コマンドを入れるテーブルを作成し、トリガーで項目が更新される度にルーチンを生成するメソッドを実行しても良いかと思います。
ご参考まで。