Skip to content

Instantly share code, notes, and snippets.

@kurin
Created May 31, 2018 18:40
Show Gist options
  • Save kurin/f591f02632ba0661839a265ac551f452 to your computer and use it in GitHub Desktop.
Save kurin/f591f02632ba0661839a265ac551f452 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"io"
)
func main() {
}
type reader struct {
ctx context.Context
r io.Reader
}
func (r reader) Read(b []byte) (i int, err error) {
ch := make(chan struct{})
go func() {
i, err = r.r.Read(b)
close(ch)
}()
select {
case <-ch:
return
case <-r.ctx.Done():
return 0, r.ctx.Err()
}
}
func contextReader(ctx context.Context, r io.Reader) *reader {
return &reader{
ctx: ctx,
r: r,
}
}
type writer struct {
ctx context.Context
w io.Writer
}
func (w writer) Write(b []byte) (i int, err error) {
ch := make(chan struct{})
go func() {
i, err = w.w.Write(b)
close(ch)
}()
select {
case <-ch:
return
case <-w.ctx.Done():
return 0, w.ctx.Err()
}
}
func contextWriter(ctx context.Context, w io.Writer) *writer {
return &writer{
ctx: ctx,
w: w,
}
}
func CopyContext(ctx context.Context, w io.Writer, r io.Reader) (int64, error) {
rc := contextReader(ctx, r)
wc := contextWriter(ctx, w)
return io.Copy(wc, rc)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment