Last active
February 12, 2020 12:18
-
-
Save Integralist/f0ab51316127c7d118e87bc62f5008af to your computer and use it in GitHub Desktop.
[Golang io.Pipe and io.TeeReader combined] #go #golang #io #pipe #tee #reader #writer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"io/ioutil" | |
"sync" | |
) | |
func readFrom(pr *io.PipeReader, wg *sync.WaitGroup) { | |
defer wg.Done() | |
b, _ := ioutil.ReadAll(pr) | |
fmt.Println(string(b), ".") | |
} | |
func main() { | |
wg := sync.WaitGroup{} | |
wg.Add(2) | |
pr, pw := io.Pipe() | |
go readFrom(pr, &wg) // this will consume all three writes in one single read. | |
go readFrom(pr, &wg) // this secondary read needs pw.Close() to unblock it! | |
// specifically, the pipe reader will keep going util the | |
// writer has signified an EOF, which wont happen without | |
// the call to Close(). | |
// | |
// this problem wouldn't exist if we had used a different | |
// read method, but as we used ioutil.ReadAll it is designed | |
// around the expectation of an EOF. | |
pw.Write([]byte("foo")) | |
pw.Write([]byte("-")) | |
pw.Write([]byte("bar")) | |
pw.Close() // do before Wait() otherwise deadlock (see comment above) | |
wg.Wait() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"io/ioutil" | |
"strings" | |
"sync" | |
) | |
func main() { | |
wg := sync.WaitGroup{} | |
wg.Add(1) | |
s := strings.NewReader("Test") | |
r, w := io.Pipe() | |
tee := io.TeeReader(s, w) | |
go func() { | |
defer wg.Done() | |
fmt.Println("about to block thread waiting for a write to io.Pipe's reader") | |
content, _ := ioutil.ReadAll(r) | |
fmt.Println("1: ", content) | |
}() | |
fmt.Println("about to block main thread until write to io.TeeReader's configured writer is complete") | |
content, _ := ioutil.ReadAll(tee) // this will force a write to io.TeeReader's writer | |
fmt.Println("2: ", content) | |
w.Close() // close the io.Pipe first before waiting for thread to complete (otherwise get a deadlock) | |
wg.Wait() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment