Cancelable Reads in Go

原文地址

https://benjamincongdon.me/blog/2020/04/23/Cancelable-Reads-in-Go

本文主要分析了当前Go中reader的现状和使用范围大概,其实Go相比Java,IO操作要简单很多,但是同时也要求使用者有一定的理解和认识,否则也会出现很多问题,比如文中提到的reader堵塞等导致的goroutine leak,其实这个在软件层面只能尽量避免,但是没法完全避免。

package main

import (
    "context"
    "io"
)

type CancelabelReader struct {
    ctx context.Context
    data chan []byte
    err error
    r io.Reader
}

func (c *CancelabelReader) begin() {
    buf := make([]byte, 1024)
    for {
        n, err := c.r.Read(buf)
        if err != nil {
            c.err = err
            close(c.data)
            return
        }
        tmp := make([]byte, n)
        copy(tmp, buf[:n])
        c.data <- tmp
    }
}

func (c *CancelabelReader) Read(p []byte) (int, error) {
    select {
    case <-c.ctx.Done():
        return 0, c.ctx.Err()
    case d, ok := <-c.data:
        if !ok {
            return 0, c.err
        }
        copy(p, d)
        return len(d), nil
    }
}

func New(ctx context.Context, r io.Reader) *CancelabelReader {
    c := &CancelabelReader{
        r:r,
        ctx:ctx,
        data:make(chan []byte),
    }
    go c.begin()
    return c
}

这是一种自定义的结构,我们直接把reader接口插入,再组合ctx,避免流程性重复。

end

一个没有高级趣味的人。 email:hushui502@gmail.com
原文地址:https://www.cnblogs.com/CherryTab/p/12773636.html