2012-09-10 6 views
1

깨끗하고 유예 한 종료를 얻으려고하고 있으며 어떤 이유로 든 실행되지 않습니다. iv'e 시도 : 또한종료 후크가^C (scala)에 시작되지 않습니다

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

를 실행 한 다음,하지만 난 내 프로그램 (실행 항아리, 더블 활성화)를 실행, 후크

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... 
} 

: ThreadOperations.delayOnThread 정의는

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

시작되지 않습니다. 그래서 내가 뭘 잘못하고 있니? 스칼라에 시스템 종료 훅을 추가하는 올바른 방법은 무엇입니까? 어떤 식 으로든 이중 활성화를 사용하고 있다는 사실과 관련이 있습니까?

더블 활성화는 그런 식으로 이루어집니다 :

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(); 
} 

(스칼라 버전 : 2.9.2) 감사합니다.

답변

0

해결되었습니다.

어떤 이유로 든 !과 반대로 run이 프로세스를 분리한다고 생각했습니다. 실제로는 run에서 반환되는 열린 스트림이 Process에 남아 있기 때문에 실제로 응답하지 않습니다 (또는 exec은 정지하지 않지만 하위 프로세스와 열린 스트림이있는 Process을 반환하기 때문에 다른 이유로 중지됩니다. , 많이 run처럼). 이런 이유로 원래 프로세스는 여전히 살아 있었고 실수로 신호를 보냈습니다. 물론 핸들러 나 종료 훅 (hook)이 없으므로 아무 일도 일어나지 않았습니다.

Process(arguments, new java.io.File(dir)).run(); 대신 Runtime.getRuntime.exec(arguments.toArray)을 사용하고 Gate 개체의 스트림을 닫은 다음^C 신호를 올바른 프로세스로 보냅니다.

0

두 번째 시도에서 종료 훅은 스레드를 만들고 시작하지 않는 것 같습니다. 따라서 가비지 수집만으로 아무 것도하지 않습니다. 내가 뭐 놓친 거 없니? (편집 : 그렇습니다, 코멘트를 참조하십시오.)

첫 번째 시도에서 기본 로그에 캐싱이 있고 로그가 플러시되기 전에 응용 프로그램이 종료되는 것이 문제 일 수 있습니다.

+0

두 번째 attamept에 대해서는 단지 구문 설탕이므로 다음과 같이 작성할 수 있습니다. 로깅에 관해서는 standart log4j를 사용하고 있습니다. 플러시와 같은 문제가 처리되지 않았다는 것을 믿기 어렵습니다 ... 어쨌든 다른 논리는 실행되지 않았습니다. –

+1

필자는 addShutdownHook이 스칼라를 사용한다는 사실을 간과했다. 나는 더 조심해야했다. 홍조 문제에 관해서는, 나의 경험에서 그것은 아주 진짜 문제이다. log4j 자체가 종료시에 플러시를 수행하기위한 종료 후크를 추가하더라도, 후크는 사용자 자신의 후크 전에 실행될 수 있습니다. Log4j가 기본적으로 * 버퍼링하지 않는다는 것을 이해하지만, 기본 설정을 그대로 사용하면 플러시 문제가 될 수 없습니다. –

관련 문제