SlideShare une entreprise Scribd logo
1  sur  40
Télécharger pour lire hors ligne
Advanced Patterns
with io.ReadWriter
18 Aug 2016
Paul Bellamy
Software Engineer, Weaveworks
Basics - What’s Available in io, bufio, & ioutil?
Basics - What’s Available in io, bufio, & ioutil?
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
Basics - What’s Available in io, bufio, & ioutil?
Tools for working with ReadWriters:
• io.Copy
• io.LimitReader
• io.TeeReader
• bufio.Scanner
• ioutil.Discard
Loads more!
Basics - Composition
Basics - Composition
var r io.Reader
r = strings.NewReader("1234567890")
r = io.LimitReader(r, 5)
io.Copy(os.Stdout, r)
Setup:
Output:
Basics - Composition
var r io.Reader
r = strings.NewReader("1234567890")
r = io.LimitReader(r, 5)
io.Copy(gzip.NewWriter(os.Stdout), r)
Setup:
Output:
Example 1 - HTTP Chunking
Example 1 - HTTP Chunking
Let's transparently proxy a chunked HTTP in a
stream.
Example 1 - HTTP Chunking
Let's transparently proxy a chunked HTTP in a
stream.
Proxy
Client
Example 1 - HTTP Chunking
4rn
Wikirn
5rn
pediarn
Ern
inrn
rn
chunks.rn
0rn
Date: Sun, 06 Nov 1994 08:49:37 GMTrn
Content-MD5: 1B2M2Y8AsgTpgAmY7PhCfg==rn
rn
Example 1 - HTTP Chunking
Wikipedia in
chunks.
io.Copy
Solution 1
io.Copy(clientWriter, responseBody)
Obvious solution with io.Copy
responseBody clientWriter
io.Copy
Solution 1
io.Copy(clientWriter, responseBody)
Obvious solution with io.Copy
responseBody clientWriter
Problems:
• Won’t let us process the Trailers separately
• We need to stop after the body
io.Copy
Solution 2
io.Copy(
clientWriter,
httputil.NewChunkedReader(responseBody),
)
parseTrailers(responseBody)
Better solution with httputil.ChunkedReader
responseBody clientWriterChunkedReader
io.Copy
Solution 2
Problems:
• Strips out the chunking data
• Can’t validate the MD5
Better solution with httputil.ChunkedReader
responseBody clientWriterChunkedReader
io.Copy
Solution 3
digest := md5.New()
io.Copy(digest,
httputil.NewChunkedReader(
io.TeeReader(
responseBody,
clientWriter,
),
),
)
parseTrailers(responseBody)
responseBody
clientWriter
ChunkedReader
TeeReader
digest
io.Copy
Solution 3
io.Copy(ioutil.Discard,
httputil.NewChunkedReader(
io.TeeReader(
responseBody,
clientWriter,
),
),
)
parseTrailers(responseBody)
responseBody
clientWriter
ChunkedReader
TeeReader
ioutil.Discard
Example 2 - Multiplexing
Example 2 - Multiplexing
Run subcommands, multiplex the output, give each a
unique prefix.
echo “HellonWorld!”
make all
git status
[echo] Hello,
[make] make: *** No rule to make target.
[echo] World!
[git] On branch master
[git] Your branch is up-to-date
[git] nothing to commit
Example 2 - Multiplexing
Example 2 - Multiplexing
Starting up the commands
commands := [][]string{
{"echo", "Hello,nWorld!"},
{"make", "all"},
{"git", "status"},
}
for _, cmd := range commands {
c := exec.Command(cmd[0], cmd[1])
// Wire up our prefix writer
prefixedOutput := prefixingWriter(cmd[0], os.Stdout)
c.Stdout = prefixedOutput
c.Stderr = prefixedOutput
// Start each in a goroutine
go func() { done <- c.Run() }()
}
Example 2 - Multiplexing
prefixingWriter
func prefixingWriter(prefix string, output io.Writer) io.Writer
Example 2 - Multiplexing
Splitting streams into sections with bufio.Scanner
input := ...
// Iterate over each line
scanner := bufio.NewScanner(input)
scanner.SplitFunc(bufio.ScanLines)
for scanner.Scan() {
// Write the prefix into the output
fmt.Fprintf(output, "[%s] ", prefix)
// Copy the line
output.Write(scanner.Bytes())
// Re-add a newline (scanner removes it)
fmt.Fprint(output, "n")
}
Example 2 - Multiplexing
Splitting streams into sections with bufio.Scanner
input := ...
// Iterate over each line
scanner := bufio.NewScanner(input)
scanner.SplitFunc(bufio.ScanLines)
for scanner.Scan() {
// Write the prefix into the output
fmt.Fprintf(output, "[%s] ", prefix)
// Copy the line
output.Write(scanner.Bytes())
// Re-add a newline (scanner removes it)
fmt.Fprint(output, "n")
}
Example 2 - Multiplexing
Splitting streams into sections with bufio.Scanner
input := ...
// Iterate over each line
scanner := bufio.NewScanner(input)
scanner.SplitFunc(bufio.ScanLines)
for scanner.Scan() {
// Write the prefix into the output
fmt.Fprintf(output, "[%s] ", prefix)
// Copy the line
output.Write(scanner.Bytes())
// Re-add a newline (scanner removes it)
fmt.Fprint(output, "n")
}
Example 2 - Multiplexing
Splitting streams into sections with bufio.Scanner
input := ...
// Iterate over each line
scanner := bufio.NewScanner(input)
scanner.SplitFunc(bufio.ScanLines)
for scanner.Scan() {
// Write the prefix into the output
fmt.Fprintf(output, "[%s] ", prefix)
// Copy the line
output.Write(scanner.Bytes())
// Re-add a newline (scanner removes it)
fmt.Fprint(output, "n")
}
Example 2 - Multiplexing
Splitting streams into sections with bufio.Scanner
input := ...
// Iterate over each line
scanner := bufio.NewScanner(input)
scanner.SplitFunc(bufio.ScanLines)
for scanner.Scan() {
// Write the prefix into the output
fmt.Fprintf(output, "[%s] ", prefix)
// Copy the line
output.Write(scanner.Bytes())
// Re-add a newline (scanner removes it)
fmt.Fprint(output, "n")
}
Example 2 - Multiplexing
Splitting streams into sections with bufio.Scanner
input := ...
// Iterate over each line
scanner := bufio.NewScanner(input)
scanner.SplitFunc(bufio.ScanLines)
for scanner.Scan() {
// Write the prefix into the output
fmt.Fprintf(output, "[%s] ", prefix)
// Copy the line
output.Write(scanner.Bytes())
// Re-add a newline (scanner removes it)
fmt.Fprint(output, "n")
}
Example 2 - Multiplexing
Splitting streams into sections with bufio.Scanner
input := ...
// Iterate over each line
scanner := bufio.NewScanner(input)
scanner.SplitFunc(bufio.ScanLines)
for scanner.Scan() {
// Write the prefix into the output
fmt.Fprintf(output, "[%s] ", prefix)
// Copy the line
output.Write(scanner.Bytes())
// Re-add a newline (scanner removes it)
fmt.Fprint(output, "n")
}
Example 2 - Multiplexing
What is input?
• bufio.Scanner expects a io.Reader
• exec.Cmd expects a io.Writer
goroutine
Example 2 - Multiplexing
pipeWriter bufio.Scannerio.Pipe output
io.Pipe to the rescue
Example 2 - Multiplexing
func prefixingWriter(prefix string, output io.Writer) io.Writer {
pipeReader, pipeWriter := io.Pipe()
scanner := bufio.NewScanner(pipeReader)
scanner.SplitFunc(bufio.ScanLines)
go func() {
for scanner.Scan() {
fmt.Fprintf(output, "[%s] ", prefix)
output.Write(scanner.Bytes())
fmt.Fprint(output, "n")
}
}()
return pipeWriter
}
Example 2 - Multiplexing
func prefixingWriter(prefix string, output io.Writer) io.Writer {
pipeReader, pipeWriter := io.Pipe()
scanner := bufio.NewScanner(pipeReader)
scanner.SplitFunc(bufio.ScanLines)
go func() {
for scanner.Scan() {
fmt.Fprintf(output, "[%s] ", prefix)
output.Write(scanner.Bytes())
fmt.Fprint(output, "n")
}
}()
return pipeWriter
}
Example 2 - Multiplexing
func prefixingWriter(prefix string, output io.Writer) io.Writer {
pipeReader, pipeWriter := io.Pipe()
scanner := bufio.NewScanner(pipeReader)
scanner.SplitFunc(bufio.ScanLines)
go func() {
for scanner.Scan() {
fmt.Fprintf(output, "[%s] ", prefix)
output.Write(scanner.Bytes())
fmt.Fprint(output, "n")
}
}()
return pipeWriter
}
Example 2 - Multiplexing
func prefixingWriter(prefix string, output io.Writer) io.Writer {
pipeReader, pipeWriter := io.Pipe()
scanner := bufio.NewScanner(pipeReader)
scanner.SplitFunc(bufio.ScanLines)
go func() {
for scanner.Scan() {
fmt.Fprintf(output, "[%s] ", prefix)
output.Write(scanner.Bytes())
fmt.Fprint(output, "n")
}
}()
return pipeWriter
}
Example 2 - Multiplexing
func prefixingWriter(prefix string, output io.Writer) io.Writer {
pipeReader, pipeWriter := io.Pipe()
scanner := bufio.NewScanner(pipeReader)
scanner.SplitFunc(bufio.ScanLines)
go func() {
for scanner.Scan() {
fmt.Fprintf(output, "[%s] ", prefix)
output.Write(scanner.Bytes())
fmt.Fprint(output, "n")
}
}()
return pipeWriter
}
Thank you
18 Aug 2016
Paul Bellamy
Software Engineer, Weaveworks
paul@weave.works
github.com/paulbellamy/golanguk2016
@pyrhho

Contenu connexe

Tendances

The linux networking architecture
The linux networking architectureThe linux networking architecture
The linux networking architecture
hugo lu
 
Embedded Linux from Scratch to Yocto
Embedded Linux from Scratch to YoctoEmbedded Linux from Scratch to Yocto
Embedded Linux from Scratch to Yocto
Sherif Mousa
 

Tendances (13)

The Theory and Implementation of DVFS on Linux
The Theory and Implementation of DVFS on LinuxThe Theory and Implementation of DVFS on Linux
The Theory and Implementation of DVFS on Linux
 
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
 
Chiffrement affine et césar par Zellagui Amine
Chiffrement affine et césar par Zellagui AmineChiffrement affine et césar par Zellagui Amine
Chiffrement affine et césar par Zellagui Amine
 
CODT2020 OpenStack Version Up and VMHA Masakari in Enterprise Cloud
CODT2020 OpenStack Version Up and VMHA Masakari in Enterprise CloudCODT2020 OpenStack Version Up and VMHA Masakari in Enterprise Cloud
CODT2020 OpenStack Version Up and VMHA Masakari in Enterprise Cloud
 
The linux networking architecture
The linux networking architectureThe linux networking architecture
The linux networking architecture
 
eBPF Basics
eBPF BasicseBPF Basics
eBPF Basics
 
Advanced Namespaces and cgroups
Advanced Namespaces and cgroupsAdvanced Namespaces and cgroups
Advanced Namespaces and cgroups
 
DMA Survival Guide
DMA Survival GuideDMA Survival Guide
DMA Survival Guide
 
看似比較簡單的Linux推坑教學 linux mint cinnamon 18.1 操作設定教學
看似比較簡單的Linux推坑教學 linux mint cinnamon 18.1 操作設定教學看似比較簡單的Linux推坑教學 linux mint cinnamon 18.1 操作設定教學
看似比較簡單的Linux推坑教學 linux mint cinnamon 18.1 操作設定教學
 
Sfida CTF: Protostar Format Zero
Sfida CTF: Protostar Format Zero  Sfida CTF: Protostar Format Zero
Sfida CTF: Protostar Format Zero
 
Linux Kernel Init Process
Linux Kernel Init ProcessLinux Kernel Init Process
Linux Kernel Init Process
 
Pengertian Firewall, NAT, dan Proxy Server
Pengertian Firewall, NAT, dan  Proxy ServerPengertian Firewall, NAT, dan  Proxy Server
Pengertian Firewall, NAT, dan Proxy Server
 
Embedded Linux from Scratch to Yocto
Embedded Linux from Scratch to YoctoEmbedded Linux from Scratch to Yocto
Embedded Linux from Scratch to Yocto
 

Similaire à Advanced Patterns with io.ReadWriter

basics of python programming5.pdf
basics of python programming5.pdfbasics of python programming5.pdf
basics of python programming5.pdf
Pushkaran3
 
An Overview Of Python With Functional Programming
An Overview Of Python With Functional ProgrammingAn Overview Of Python With Functional Programming
An Overview Of Python With Functional Programming
Adam Getchell
 
Lec 47.48 - stream-files
Lec 47.48 - stream-filesLec 47.48 - stream-files
Lec 47.48 - stream-files
Princess Sam
 
Stream Based Input Output
Stream Based Input OutputStream Based Input Output
Stream Based Input Output
Bharat17485
 

Similaire à Advanced Patterns with io.ReadWriter (20)

UNIT-II CP DOC.docx
UNIT-II CP DOC.docxUNIT-II CP DOC.docx
UNIT-II CP DOC.docx
 
Rust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command LineRust LDN 24 7 19 Oxidising the Command Line
Rust LDN 24 7 19 Oxidising the Command Line
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
Input and output basic of c++ programming and escape sequences
Input and output basic of c++ programming and escape sequencesInput and output basic of c++ programming and escape sequences
Input and output basic of c++ programming and escape sequences
 
programming language in c&c++
programming language in c&c++programming language in c&c++
programming language in c&c++
 
Cse115 lecture04introtoc programming
Cse115 lecture04introtoc programmingCse115 lecture04introtoc programming
Cse115 lecture04introtoc programming
 
basics of python programming5.pdf
basics of python programming5.pdfbasics of python programming5.pdf
basics of python programming5.pdf
 
Python Training in Bangalore | Python Introduction Session | Learnbay
Python Training in Bangalore |  Python Introduction Session | LearnbayPython Training in Bangalore |  Python Introduction Session | Learnbay
Python Training in Bangalore | Python Introduction Session | Learnbay
 
Functions
FunctionsFunctions
Functions
 
CorePy High-Productivity CellB.E. Programming
CorePy High-Productivity CellB.E. ProgrammingCorePy High-Productivity CellB.E. Programming
CorePy High-Productivity CellB.E. Programming
 
Functions of stdio conio
Functions of stdio   conio Functions of stdio   conio
Functions of stdio conio
 
III MCS python lab (1).pdf
III MCS python lab (1).pdfIII MCS python lab (1).pdf
III MCS python lab (1).pdf
 
An Overview Of Python With Functional Programming
An Overview Of Python With Functional ProgrammingAn Overview Of Python With Functional Programming
An Overview Of Python With Functional Programming
 
3.Lesson Plan - Input.pdf.pdf
3.Lesson Plan - Input.pdf.pdf3.Lesson Plan - Input.pdf.pdf
3.Lesson Plan - Input.pdf.pdf
 
Lec 47.48 - stream-files
Lec 47.48 - stream-filesLec 47.48 - stream-files
Lec 47.48 - stream-files
 
Stream Based Input Output
Stream Based Input OutputStream Based Input Output
Stream Based Input Output
 
MODULE. .pptx
MODULE.                              .pptxMODULE.                              .pptx
MODULE. .pptx
 
07-Basic-Input-Output.ppt
07-Basic-Input-Output.ppt07-Basic-Input-Output.ppt
07-Basic-Input-Output.ppt
 
C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)C cheat sheet for varsity (extreme edition)
C cheat sheet for varsity (extreme edition)
 
Fp201 unit2 1
Fp201 unit2 1Fp201 unit2 1
Fp201 unit2 1
 

Plus de Weaveworks

SRE and GitOps for Building Robust Kubernetes Platforms.pdf
SRE and GitOps for Building Robust Kubernetes Platforms.pdfSRE and GitOps for Building Robust Kubernetes Platforms.pdf
SRE and GitOps for Building Robust Kubernetes Platforms.pdf
Weaveworks
 
How to Avoid Kubernetes Multi-tenancy Catastrophes
How to Avoid Kubernetes Multi-tenancy CatastrophesHow to Avoid Kubernetes Multi-tenancy Catastrophes
How to Avoid Kubernetes Multi-tenancy Catastrophes
Weaveworks
 

Plus de Weaveworks (20)

Weave AI Controllers (Weave GitOps Office Hours)
Weave AI Controllers (Weave GitOps Office Hours)Weave AI Controllers (Weave GitOps Office Hours)
Weave AI Controllers (Weave GitOps Office Hours)
 
Flamingo: Expand ArgoCD with Flux (Office Hours)
Flamingo: Expand ArgoCD with Flux (Office Hours)Flamingo: Expand ArgoCD with Flux (Office Hours)
Flamingo: Expand ArgoCD with Flux (Office Hours)
 
Webinar: Capabilities, Confidence and Community – What Flux GA Means for You
Webinar: Capabilities, Confidence and Community – What Flux GA Means for YouWebinar: Capabilities, Confidence and Community – What Flux GA Means for You
Webinar: Capabilities, Confidence and Community – What Flux GA Means for You
 
Six Signs You Need Platform Engineering
Six Signs You Need Platform EngineeringSix Signs You Need Platform Engineering
Six Signs You Need Platform Engineering
 
SRE and GitOps for Building Robust Kubernetes Platforms.pdf
SRE and GitOps for Building Robust Kubernetes Platforms.pdfSRE and GitOps for Building Robust Kubernetes Platforms.pdf
SRE and GitOps for Building Robust Kubernetes Platforms.pdf
 
Webinar: End to End Security & Operations with Chainguard and Weave GitOps
Webinar: End to End Security & Operations with Chainguard and Weave GitOpsWebinar: End to End Security & Operations with Chainguard and Weave GitOps
Webinar: End to End Security & Operations with Chainguard and Weave GitOps
 
Flux Beyond Git Harnessing the Power of OCI
Flux Beyond Git Harnessing the Power of OCIFlux Beyond Git Harnessing the Power of OCI
Flux Beyond Git Harnessing the Power of OCI
 
Automated Provisioning, Management & Cost Control for Kubernetes Clusters
Automated Provisioning, Management & Cost Control for Kubernetes ClustersAutomated Provisioning, Management & Cost Control for Kubernetes Clusters
Automated Provisioning, Management & Cost Control for Kubernetes Clusters
 
How to Avoid Kubernetes Multi-tenancy Catastrophes
How to Avoid Kubernetes Multi-tenancy CatastrophesHow to Avoid Kubernetes Multi-tenancy Catastrophes
How to Avoid Kubernetes Multi-tenancy Catastrophes
 
Building internal developer platform with EKS and GitOps
Building internal developer platform with EKS and GitOpsBuilding internal developer platform with EKS and GitOps
Building internal developer platform with EKS and GitOps
 
GitOps Testing in Kubernetes with Flux and Testkube.pdf
GitOps Testing in Kubernetes with Flux and Testkube.pdfGitOps Testing in Kubernetes with Flux and Testkube.pdf
GitOps Testing in Kubernetes with Flux and Testkube.pdf
 
Intro to GitOps with Weave GitOps, Flagger and Linkerd
Intro to GitOps with Weave GitOps, Flagger and LinkerdIntro to GitOps with Weave GitOps, Flagger and Linkerd
Intro to GitOps with Weave GitOps, Flagger and Linkerd
 
Implementing Flux for Scale with Soft Multi-tenancy
Implementing Flux for Scale with Soft Multi-tenancyImplementing Flux for Scale with Soft Multi-tenancy
Implementing Flux for Scale with Soft Multi-tenancy
 
Accelerating Hybrid Multistage Delivery with Weave GitOps on EKS
Accelerating Hybrid Multistage Delivery with Weave GitOps on EKSAccelerating Hybrid Multistage Delivery with Weave GitOps on EKS
Accelerating Hybrid Multistage Delivery with Weave GitOps on EKS
 
The Story of Flux Reaching Graduation in the CNCF
The Story of Flux Reaching Graduation in the CNCFThe Story of Flux Reaching Graduation in the CNCF
The Story of Flux Reaching Graduation in the CNCF
 
Shift Deployment Security Left with Weave GitOps & Upbound’s Universal Crossp...
Shift Deployment Security Left with Weave GitOps & Upbound’s Universal Crossp...Shift Deployment Security Left with Weave GitOps & Upbound’s Universal Crossp...
Shift Deployment Security Left with Weave GitOps & Upbound’s Universal Crossp...
 
Securing Your App Deployments with Tunnels, OIDC, RBAC, and Progressive Deliv...
Securing Your App Deployments with Tunnels, OIDC, RBAC, and Progressive Deliv...Securing Your App Deployments with Tunnels, OIDC, RBAC, and Progressive Deliv...
Securing Your App Deployments with Tunnels, OIDC, RBAC, and Progressive Deliv...
 
Flux’s Security & Scalability with OCI & Helm Slides.pdf
Flux’s Security & Scalability with OCI & Helm Slides.pdfFlux’s Security & Scalability with OCI & Helm Slides.pdf
Flux’s Security & Scalability with OCI & Helm Slides.pdf
 
Flux Security & Scalability using VS Code GitOps Extension
Flux Security & Scalability using VS Code GitOps Extension Flux Security & Scalability using VS Code GitOps Extension
Flux Security & Scalability using VS Code GitOps Extension
 
Deploying Stateful Applications Securely & Confidently with Ondat & Weave GitOps
Deploying Stateful Applications Securely & Confidently with Ondat & Weave GitOpsDeploying Stateful Applications Securely & Confidently with Ondat & Weave GitOps
Deploying Stateful Applications Securely & Confidently with Ondat & Weave GitOps
 

Dernier

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Dernier (20)

%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 

Advanced Patterns with io.ReadWriter

  • 1. Advanced Patterns with io.ReadWriter 18 Aug 2016 Paul Bellamy Software Engineer, Weaveworks
  • 2.
  • 3.
  • 4. Basics - What’s Available in io, bufio, & ioutil?
  • 5. Basics - What’s Available in io, bufio, & ioutil? type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) }
  • 6. Basics - What’s Available in io, bufio, & ioutil? Tools for working with ReadWriters: • io.Copy • io.LimitReader • io.TeeReader • bufio.Scanner • ioutil.Discard Loads more!
  • 8. Basics - Composition var r io.Reader r = strings.NewReader("1234567890") r = io.LimitReader(r, 5) io.Copy(os.Stdout, r) Setup: Output:
  • 9. Basics - Composition var r io.Reader r = strings.NewReader("1234567890") r = io.LimitReader(r, 5) io.Copy(gzip.NewWriter(os.Stdout), r) Setup: Output:
  • 10. Example 1 - HTTP Chunking
  • 11. Example 1 - HTTP Chunking Let's transparently proxy a chunked HTTP in a stream.
  • 12. Example 1 - HTTP Chunking Let's transparently proxy a chunked HTTP in a stream. Proxy Client
  • 13. Example 1 - HTTP Chunking 4rn Wikirn 5rn pediarn Ern inrn rn chunks.rn 0rn Date: Sun, 06 Nov 1994 08:49:37 GMTrn Content-MD5: 1B2M2Y8AsgTpgAmY7PhCfg==rn rn
  • 14. Example 1 - HTTP Chunking Wikipedia in chunks.
  • 15. io.Copy Solution 1 io.Copy(clientWriter, responseBody) Obvious solution with io.Copy responseBody clientWriter
  • 16. io.Copy Solution 1 io.Copy(clientWriter, responseBody) Obvious solution with io.Copy responseBody clientWriter Problems: • Won’t let us process the Trailers separately • We need to stop after the body
  • 18. io.Copy Solution 2 Problems: • Strips out the chunking data • Can’t validate the MD5 Better solution with httputil.ChunkedReader responseBody clientWriterChunkedReader
  • 19. io.Copy Solution 3 digest := md5.New() io.Copy(digest, httputil.NewChunkedReader( io.TeeReader( responseBody, clientWriter, ), ), ) parseTrailers(responseBody) responseBody clientWriter ChunkedReader TeeReader digest
  • 21. Example 2 - Multiplexing
  • 22. Example 2 - Multiplexing Run subcommands, multiplex the output, give each a unique prefix. echo “HellonWorld!” make all git status [echo] Hello, [make] make: *** No rule to make target. [echo] World! [git] On branch master [git] Your branch is up-to-date [git] nothing to commit
  • 23. Example 2 - Multiplexing
  • 24. Example 2 - Multiplexing Starting up the commands commands := [][]string{ {"echo", "Hello,nWorld!"}, {"make", "all"}, {"git", "status"}, } for _, cmd := range commands { c := exec.Command(cmd[0], cmd[1]) // Wire up our prefix writer prefixedOutput := prefixingWriter(cmd[0], os.Stdout) c.Stdout = prefixedOutput c.Stderr = prefixedOutput // Start each in a goroutine go func() { done <- c.Run() }() }
  • 25. Example 2 - Multiplexing prefixingWriter func prefixingWriter(prefix string, output io.Writer) io.Writer
  • 26. Example 2 - Multiplexing Splitting streams into sections with bufio.Scanner input := ... // Iterate over each line scanner := bufio.NewScanner(input) scanner.SplitFunc(bufio.ScanLines) for scanner.Scan() { // Write the prefix into the output fmt.Fprintf(output, "[%s] ", prefix) // Copy the line output.Write(scanner.Bytes()) // Re-add a newline (scanner removes it) fmt.Fprint(output, "n") }
  • 27. Example 2 - Multiplexing Splitting streams into sections with bufio.Scanner input := ... // Iterate over each line scanner := bufio.NewScanner(input) scanner.SplitFunc(bufio.ScanLines) for scanner.Scan() { // Write the prefix into the output fmt.Fprintf(output, "[%s] ", prefix) // Copy the line output.Write(scanner.Bytes()) // Re-add a newline (scanner removes it) fmt.Fprint(output, "n") }
  • 28. Example 2 - Multiplexing Splitting streams into sections with bufio.Scanner input := ... // Iterate over each line scanner := bufio.NewScanner(input) scanner.SplitFunc(bufio.ScanLines) for scanner.Scan() { // Write the prefix into the output fmt.Fprintf(output, "[%s] ", prefix) // Copy the line output.Write(scanner.Bytes()) // Re-add a newline (scanner removes it) fmt.Fprint(output, "n") }
  • 29. Example 2 - Multiplexing Splitting streams into sections with bufio.Scanner input := ... // Iterate over each line scanner := bufio.NewScanner(input) scanner.SplitFunc(bufio.ScanLines) for scanner.Scan() { // Write the prefix into the output fmt.Fprintf(output, "[%s] ", prefix) // Copy the line output.Write(scanner.Bytes()) // Re-add a newline (scanner removes it) fmt.Fprint(output, "n") }
  • 30. Example 2 - Multiplexing Splitting streams into sections with bufio.Scanner input := ... // Iterate over each line scanner := bufio.NewScanner(input) scanner.SplitFunc(bufio.ScanLines) for scanner.Scan() { // Write the prefix into the output fmt.Fprintf(output, "[%s] ", prefix) // Copy the line output.Write(scanner.Bytes()) // Re-add a newline (scanner removes it) fmt.Fprint(output, "n") }
  • 31. Example 2 - Multiplexing Splitting streams into sections with bufio.Scanner input := ... // Iterate over each line scanner := bufio.NewScanner(input) scanner.SplitFunc(bufio.ScanLines) for scanner.Scan() { // Write the prefix into the output fmt.Fprintf(output, "[%s] ", prefix) // Copy the line output.Write(scanner.Bytes()) // Re-add a newline (scanner removes it) fmt.Fprint(output, "n") }
  • 32. Example 2 - Multiplexing Splitting streams into sections with bufio.Scanner input := ... // Iterate over each line scanner := bufio.NewScanner(input) scanner.SplitFunc(bufio.ScanLines) for scanner.Scan() { // Write the prefix into the output fmt.Fprintf(output, "[%s] ", prefix) // Copy the line output.Write(scanner.Bytes()) // Re-add a newline (scanner removes it) fmt.Fprint(output, "n") }
  • 33. Example 2 - Multiplexing What is input? • bufio.Scanner expects a io.Reader • exec.Cmd expects a io.Writer
  • 34. goroutine Example 2 - Multiplexing pipeWriter bufio.Scannerio.Pipe output io.Pipe to the rescue
  • 35. Example 2 - Multiplexing func prefixingWriter(prefix string, output io.Writer) io.Writer { pipeReader, pipeWriter := io.Pipe() scanner := bufio.NewScanner(pipeReader) scanner.SplitFunc(bufio.ScanLines) go func() { for scanner.Scan() { fmt.Fprintf(output, "[%s] ", prefix) output.Write(scanner.Bytes()) fmt.Fprint(output, "n") } }() return pipeWriter }
  • 36. Example 2 - Multiplexing func prefixingWriter(prefix string, output io.Writer) io.Writer { pipeReader, pipeWriter := io.Pipe() scanner := bufio.NewScanner(pipeReader) scanner.SplitFunc(bufio.ScanLines) go func() { for scanner.Scan() { fmt.Fprintf(output, "[%s] ", prefix) output.Write(scanner.Bytes()) fmt.Fprint(output, "n") } }() return pipeWriter }
  • 37. Example 2 - Multiplexing func prefixingWriter(prefix string, output io.Writer) io.Writer { pipeReader, pipeWriter := io.Pipe() scanner := bufio.NewScanner(pipeReader) scanner.SplitFunc(bufio.ScanLines) go func() { for scanner.Scan() { fmt.Fprintf(output, "[%s] ", prefix) output.Write(scanner.Bytes()) fmt.Fprint(output, "n") } }() return pipeWriter }
  • 38. Example 2 - Multiplexing func prefixingWriter(prefix string, output io.Writer) io.Writer { pipeReader, pipeWriter := io.Pipe() scanner := bufio.NewScanner(pipeReader) scanner.SplitFunc(bufio.ScanLines) go func() { for scanner.Scan() { fmt.Fprintf(output, "[%s] ", prefix) output.Write(scanner.Bytes()) fmt.Fprint(output, "n") } }() return pipeWriter }
  • 39. Example 2 - Multiplexing func prefixingWriter(prefix string, output io.Writer) io.Writer { pipeReader, pipeWriter := io.Pipe() scanner := bufio.NewScanner(pipeReader) scanner.SplitFunc(bufio.ScanLines) go func() { for scanner.Scan() { fmt.Fprintf(output, "[%s] ", prefix) output.Write(scanner.Bytes()) fmt.Fprint(output, "n") } }() return pipeWriter }
  • 40. Thank you 18 Aug 2016 Paul Bellamy Software Engineer, Weaveworks paul@weave.works github.com/paulbellamy/golanguk2016 @pyrhho