go - 惯用的方式来中断NopCloser上的读取?

标签 go

在消费者可以随时取消的情况下,我正在通过读取器流式传输数据。通常,我只需要使用消费者调用reader.Close(),但是在这种情况下,阅读器需要为ReadCloser。 NopCloser是我目前知道的将Reader变成ReadCloser的唯一方法,但是关闭并不会做任何事情,因此,如果消费者离开了,我将无法通知生产者。是否有类似NopCloser的东西发出某种我可以在生产者端监听的信号?

最佳答案

据我了解,这可能是解决方案:https://play.golang.org/p/-d8eGFvwuYb

但是我认为这不是惯用语言,在我看来也像是一个XY问题...刚刚了解了这个词,顺便说一句,分享@Flimzy

package main

import (
    "bytes"
    "context"
    "fmt"
    "io"
    "time"
)

func main() {
    cs := goWrite()
    read(cs)
    time.Sleep(1)
}

func goWrite() CloseSignaler {
    buf := &bytes.Buffer{}
    cs := NewCloseSignaler(buf)
    go func() {
        defer fmt.Println("exit writer")
        for {
            select {
            case <-cs.ctx.Done():
                return
            default:
                buf.Write([]byte("A"))
            }
        }
    }()
    return cs
}

func read(rc io.ReadCloser) {
    p := make([]byte, 1)
    rc.Read(p)
    fmt.Printf("read %s\n", string(p))
    rc.Close()
}

// CloseSignaler

type CloseSignaler struct {
    io.Reader
    ctx    context.Context
    cancel func()
}

func NewCloseSignaler(r io.Reader) CloseSignaler {
    ctx, cancel := context.WithCancel(context.Background())
    return CloseSignaler{
        Reader: r,
        ctx:    ctx,
        cancel: cancel,
    }
}

func (cs CloseSignaler) Close() error {
    cs.cancel()
    return nil
}

关于go - 惯用的方式来中断NopCloser上的读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58918013/

相关文章:

unit-testing - 当连接位于结构中时,我应该如何在 Go 中模拟 Redis 连接?

go - 无法在 GO 中解码 AWS SQS 消息

sql - 将nil值分配给driver.Value会使driver.Value不等于nil

go - 如何使用索引打印?

json - 尝试解码映射[优先级]字符串

http - 使用 http.Client.Get 方法和 Body.Read() 方法处理时导致终止的 EOF 错误

go - 如何知道将安装哪个版本?如果我使用 "go get ./..."来安装依赖项

json - 解析POST请求中发送的json正文数组并打印

go - 使用 compileDaemon 更改源时重新编译 Go Echo 项目

string - 如何将字符串转换为在 Go 中使用给定字符集编译的字节数组?