Как вызвать метод внутри блока `signal`? - PullRequest
7 голосов
/ 19 апреля 2020

Можно ли вызвать пользовательский метод в блоке сигнала?

method my-method ( ... ) {
    signal(SIGTERM,SIGINT,SIGQUIT,SIGHUP).tap( -> $sig {
        say "Received signal: $sig";
        self!restore-term();
        exit;
    } );
    ...
    ...
}

1 Ответ

8 голосов
/ 19 апреля 2020

Да, но есть предостережения.

signal предоставляет Supply событий, которые вы можете tap (если хотите), но, вероятно, следует использовать внутри структуры react whenever .

В вашем примере tap принимает Block (лямбда). Каждый раз, когда вы вызываете метод, он устанавливает другой Supply (что, вероятно, не то, что вам нужно).

Этот блок вызывается всякий раз, когда приходит событие. Это означает, что он полностью асинхронный и не имеет контекста, кроме лексического контекста, в котором был создан блок.

Поэтому, когда сигнал поступает в Supply, он запускает блок с self на данный момент метод вызван. Что может быть не тем, что вы ожидаете?

Так что мне кажется, что вы задаете неправильный вопрос. По-видимому, у вас есть объект (возможно, часовой), который вы будете вызывать sh restore-term методом, который вызывается всякий раз, когда кто-то указывает, что он хочет покинуть программу. Таким образом, вам, вероятно, лучше реструктурировать вашу программу примерно так:

my $sentinel = class.new(...);
react {
    whenever signal(SIGTERM,SIGINT,SIGQUIT,SIGHUP) -> $sig {
        say "Received signal: $sig";
        $sentinel.restore-term();
        exit;
    }
    # .... other stuff
}
...