1

クリーンでグレースフルなシャットダウンを取得しようとしていますが、何らかの理由で実行されません。私はもう試した:

sys addShutdownHook{
    logger.warn("SHUTTING DOWN...")
    // irrelevant logic here...
}

また:

Runtime.getRuntime.addShutdownHook(ThreadOperations.delayOnThread{
        logger.warn("SHUTTING DOWN...")
        // irrelevant logic here...
    }
)

ThreadOperations.delayOnThread定義は次のとおりです。

object ThreadOperations {

    def startOnThread(body: =>Unit) : Thread = {
        onThread(true, body)
    }

    def delayOnThread(body: =>Unit) : Thread = {
        onThread(false, body)
    }

    private def onThread(runNow : Boolean, body: =>Unit) : Thread = {
        val t=new Thread {
            override def run=body
        }
        if(runNow){t.start}
        t
    }

    // more irrelevant operations...
}

しかし、プログラム (実行可能 jar、二重アクティベーション) を実行すると、フックが開始されません。それで、私は何を間違っていますか?scalaにシャットダウンフックを追加する正しい方法は何ですか? それは、私が二重アクティベーションを使用しているという事実に何らかの形で関連していますか?

二重アクティベーションは次のように行われます。

object Gate extends App {
    val givenArgs = if(args.isEmpty){
                        Array("run")
                    }else{
                        args
                    }

    val jar = Main.getClass.getProtectionDomain().getCodeSource().getLocation().getFile;
    val dir = jar.dropRight(jar.split(System.getProperty("file.separator")).last.length + 1)
    val arguments = Seq("java", "-cp", jar, "boot.Main") ++ givenArgs.toSeq
    Process(arguments, new java.io.File(dir)).run();
}

(scala バージョン: 2.9.2) ありがとうございます。

4

2 に答える 2

0

2 回目の試行では、シャットダウン フックは、スレッドを作成するだけで開始しないように見えます (したがって、ガベージ コレクションが行われ、何もしません)。私は何か見落としてますか?(編集:はい、コメントを参照してください。私の悪い)。

最初の試行では、基になるログにいくらかのキャッシュがあり、ログがフラッシュされる前にアプリケーションが終了することが問題である可能性があります。

于 2012-09-10T10:48:33.767 に答える
0

解決しました。

どういうわけか、プロセスを切り離すのではrunなく、と思いました。から返さ!れるオープンストリームが に残っているため、実際にはハングアップします(または、別の理由でハングするだけかもしれません。. このため、元のプロセスがまだ生きていて、誤ってシグナルを送ってしまいました。もちろん、ハンドラーやシャットダウン フックは含まれていないため、何も起こりませんでした。ProcessrunexecProcessrun

Runtime.getRuntime.exec(arguments.toArray)解決策は、代わりにを使用Process(arguments, new java.io.File(dir)).run();し、オブジェクト内のストリームを閉じてGate、^C シグナルを適切なプロセスに送信することでした。

于 2012-09-10T11:58:56.287 に答える