LoginSignup
1
0

More than 3 years have passed since last update.

golangでnet.ConnのRead・Writeをcontextでcancel可能にする方法

Last updated at Posted at 2020-11-17

モチベーション

ソケットから読もうとするとブロックする可能性があるので、
それをcontextでキャンセルできる様にしたい。

可能なら以下の様なコードが書きたいが、それはできないので、代替案をメモ

select {
case size, err := conn.Read():
// 略
case <-ctx.Done():
//略
}

解決策

こんな感じでSetDeadlineを使うと良い。
なお、デッドラインの設定時間により、ctx.Done() への応答時間が伸びたりするが、
Readへの応答時間要求に比べてctx.Done()への応答時間要求はかなりゆるい場合が多いと思うので問題になることは少ないはず。


continue_read := true
for continue_read {
    err := conn.SetReadDeadline(time.Now().Add(time.Millisecond * 500))
    if err != nil {
        return err
    }

    size, err := conn.Read(buf)
    switch {
    case err == nil || os.IsTimeout(err):
        continue_read = true  // Do nothing
    case errors.Is(err, io.EOF):
        continue_read = false
    default:
        return err
    }

    // bufの操作等を書く


    select {
    case <-ctx.Done():
        return ctx.Err()
    default:
    }
}

うーん、一応問題は解決したものの、あんまり綺麗じゃないので何とかしたい。

1
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0