いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-132 (Go 1.16で追加された signal.NotifyContext())

概要

Go 1.16 のリリース自体については以下の記事を参照ください。

devlights.hatenablog.com

devlights.hatenablog.com

Go 1.16 で signal パッケージに NotifyContext という関数が追加されました。

context.Context を受け取れるようになっているので、少し便利になりましたね。

サンプル作るほどでも無いと思いますが、一応自分用にメモメモ。

サンプル

signal.Notify

以前から存在している signal.Notify 関数を使ったサンプル

package signals

import (
    "context"
    "os"
    "os/signal"
    "time"

    "github.com/devlights/gomy/output"
)

// Notify は、 signal.Notify のサンプルです.
//
// REFERENCES:
//   - https://golang.org/pkg/os/signal/#example_Notify
func Notify() error {
    var (
        rootCtx          = context.Background()
        mainCtx, mainCxl = context.WithCancel(rootCtx)
        procCtx, procCxl = context.WithTimeout(mainCtx, 5*time.Second)
    )

    defer mainCxl()
    defer procCxl()

    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, os.Interrupt)
    defer close(sigCh)

    select {
    case <-procCtx.Done():
        output.Stdoutl("[Timeout]", "procCtx.Done()")
    case <-sigCh:
        output.Stdoutl("[Interrupt]", "Ctrl-C")
    }

    return nil
}

実行すると以下のようになります。

何もせずに5秒経過した場合
gitpod /workspace/try-golang $ make run

GO111MODULE=off go get golang.org/dl/go1.16
go1.16 download
go1.16: already downloaded in /home/gitpod/sdk/go1.16
go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example ""

ENTER EXAMPLE NAME: signal_notify
[Name] "signal_notify"
[Timeout]            procCtx.Done()


[Elapsed] 5.023452884s
5秒以内にCtrl-Cで割り込み入れた場合
gitpod /workspace/try-golang $ make run

GO111MODULE=off go get golang.org/dl/go1.16
go1.16 download
go1.16: already downloaded in /home/gitpod/sdk/go1.16
go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example ""

ENTER EXAMPLE NAME: signal_notify
[Name] "signal_notify"
^C[Interrupt]          Ctrl-C


[Elapsed] 2.790585428s

signal.NotifyContext

こちらが Go 1.16 で新たに追加された関数です。

package signals

import (
    "context"
    "os"
    "os/signal"
    "time"

    "github.com/devlights/gomy/output"
)

// NotifyContext は、 Go 1.16 から追加された signal.NotifyContext のサンプルです.
//
// REFERENCES:
//   - https://golang.org/pkg/os/signal/#NotifyContext
func NotifyContext() error {
    var (
        rootCtx          = context.Background()
        mainCtx, mainCxl = context.WithCancel(rootCtx)
        procCtx, procCxl = context.WithTimeout(mainCtx, 5*time.Second)
        sigCtx, sigCxl   = signal.NotifyContext(procCtx, os.Interrupt)
    )

    defer mainCxl()
    defer procCxl()
    defer sigCxl()

    <-sigCtx.Done()
    sigCxl()

    switch sigCtx.Err() {
    case context.Canceled:
        output.Stdoutl("[Interrupt]", "Ctrl-C")
    case context.DeadlineExceeded:
        output.Stdoutl("[Timeout]", "procCtx.Done()")
    }

    return nil
}

実行すると以下のようになります。

何もせずに5秒経過した場合
gitpod /workspace/try-golang $ make run

GO111MODULE=off go get golang.org/dl/go1.16
go1.16 download
go1.16: already downloaded in /home/gitpod/sdk/go1.16
go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example ""

ENTER EXAMPLE NAME: signal_notify_context
[Name] "signal_notify_context"
[Timeout]            procCtx.Done()


[Elapsed] 5.021714981s
5秒以内にCtrl-Cで割り込み入れた場合
gitpod /workspace/try-golang $ make run

GO111MODULE=off go get golang.org/dl/go1.16
go1.16 download
go1.16: already downloaded in /home/gitpod/sdk/go1.16
go1.16 run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example ""

ENTER EXAMPLE NAME: signal_notify_context
[Name] "signal_notify_context"
^C[Interrupt]          Ctrl-C


[Elapsed] 3.135518739s

参考情報


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com