Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 8335

Goメモ-475 (キャンセル可能なreader)(cancelreader) - いろいろ備忘録日記

$
0
0

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。

標準入力からパイプで流したデータをキャンセル可能にしたいなーって思って、ライブラリ探してたら以下を発見。

github.com

Linuxの場合は、内部で epoll を使って制御してくれているみたいですね。ちょっと試してみました。

以下、サンプルです。

サンプル

package main

import (
    "errors""fmt""log""os""time""github.com/muesli/cancelreader"
)

func main() {
    log.SetFlags(log.Lmicroseconds)
    log.SetOutput(os.Stdout)

    if err := run(); err != nil {
        log.Panic(err)
    }
}

func run() error {
    //// 標準入力をキャンセル可能なReaderにする//// cancelreader.CancelReaderは、Linuxの場合// 内部で epoll を利用して制御を行っている。//// なので、非ブロッキングI/Oが可能なファイルディスクリプタに対してのみ// キャンセル可能となっている。非ブロッキングI/Oが可能なものは例えば以下のもの。//   - ソケット//   - パイプ//   - FIFO//// 通常のファイルは非ブロッキングI/O可能なファイルディスクリプタでは無いことに注意。// 通常のファイルをepollで利用すると epoll_ctl() で EPERM が返ってくる。// 通常のファイルをキャンセル可能にしたい場合は io_uring などを検討する。//var (
        reader cancelreader.CancelReader
        err    error
    )
    reader, err = cancelreader.NewReader(os.Stdin)
    if err != nil {
        return fmt.Errorf("cancelreader.NewReader() failed: %w", err)
    }
    defer reader.Close()

    //// 3秒後にキャンセル//gofunc() {
        time.Sleep(3 * time.Second)
        reader.Cancel()
    }()

    //// 500ms毎に1文字読み込み//var (
        buf [1]byte
    )
    for {
        clear(buf[:])

        if _, err = reader.Read(buf[:]); err != nil {
            if errors.Is(err, cancelreader.ErrCanceled) {
                log.Println("CANCELED")
                break
            }

            return fmt.Errorf("reader.Read() failed: %w", err)
        }

        log.Print(string(buf[:]))
        time.Sleep(500 * time.Millisecond)
    }

    returnnil
}

試してみます。

$ task
task: [default]echo -n helloworld | go run main.go
15:09:24.486356 h
15:09:24.987136 e
15:09:25.487775 l
15:09:25.988534 l
15:09:26.489191 o
15:09:26.989851 w
15:09:27.490367 CANCELED

ちゃんと途中でキャンセルがかかっていますね。

参考情報

ja.manpages.org

itkq.jp

blog.ojisan.io

zenn.dev

Goのおすすめ書籍


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

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


Viewing all articles
Browse latest Browse all 8335

Trending Articles