SlideShare a Scribd company logo
Trends in concurrent programming languages
Google’s Go 
April 7, 2013

John Graham-Cumming

www.cloudflare.com!
Go (golang)
•  Created in 2007 internally at Google
•  Announced in 2009
•  Currently on Go 1.0.3 (Go 1.1RC2 released yesterday)


•  Headlines
•  Intended for ‘systems programming’
•  Statically typed
•  Garbage collected
•  Designed for concurrency
•  Very high speed compilation
•  Syntax very familiar to C/C++/Java programmers
•  “A small language”

www.cloudflare.com!
Small number of built in types
•  int, float, string (mutable), boolean
•  pointers
•  map



m := make(map[string]int)!
m[“Hello”] = 10!

•  slice (bounds checked)
a := make([]int, 10)

!
a[0] = 42!
b := a[1,3]!

•  channel
•  structure, function, interface

www.cloudflare.com!
OO using interfaces
•  Interface type
•  Static ‘duck’ typing
type Sequence []int!
!
func (s Sequence) Size() int {!
return len(s)!
}!
!
type Sizer interface {!
Size() int!
}!
!
func Foo (o Sizer) {!
...!
}!

www.cloudflare.com!
Statically typed
•  Familiar type declarations
type currency struct {!
id string!
longName string!
}!
!
type transaction struct {!
cur currency!
amnt int!
}!
!
sterling := currency{“GBP”, “British Pounds Sterling”}!
!
var credit = transaction{cur: sterling, amnt: 100}!
!
lastCredit = &credit!
!
lastCredit.amnt += 100!
www.cloudflare.com!
One type of loop, one iterator
for i := 0; i < 10; i++ {!
...!
}!
!
for {!
...!
}!
!
for some_boolean {!
...!
}!
!
for i, v := range some_slice {!
...!
}!
!
for k, v := range some_map {!
...!
}!
www.cloudflare.com!
Explicit error returns
•  No (actually, very limited) exception mechanism


•  The Go way is multiple returns with errors
conn, err := net.Dial("tcp", "example.com”)!
!
if x, err := do(); err == nil {!
...!
} else {!
...!
}!

•  Can explicitly ignore errors if desired



conn, _ := net.Dial("tcp", "example.com”)!

www.cloudflare.com!
Garbage Collected
•  Parallel mark-and-sweep garbage collector

www.cloudflare.com!
Possible Concurrency Options
•  Processes with IPC
•  Classic ‘Unix’ processes
•  Erlang processes and mailboxes

•  coroutines
•  Lua uses coroutines with explicit yields


•  Threads with shared memory
•  OS vs. user space
•  Go’s goroutines are close to ‘green threads’
•  Event driven
•  node.js, JavaScript
•  Many GUI frameworks
www.cloudflare.com!
Concurrency
•  goroutines
•  Very lightweight processes/threads
•  All scheduling handled internally by the Go runtime
•  Unless you are CPU bound you do not have to think about
scheduling
•  Multiplexed onto system threads, OS polling for I/O
•  Channel-based communication
•  The right way for goroutines to talk to each other

•  Synchronization Library (sync)
•  For when a channel is too heavyweight
•  Rarely used—not going to discuss

www.cloudflare.com!
goroutines
•  “Lightweight”
•  Starting 10,000 goroutines on my MacBook Pro took 22ms
•  Allocated memory increased by 3,014,000 bytes (301 bytes per
goroutine)
•  https://gist.github.com/jgrahamc/5253020
•  Not unusual at CloudFlare to have a single Go program

running 10,000s of goroutines with 1,000,000s of
goroutines created during life program.

•  So, go yourFunc() as much as you like.

www.cloudflare.com!
Channels
•  c := make(chan bool)– Makes an unbuffered

channel of bools

c <- x – Sends a value on the channel
<- c – Waits to receive a value on the channel
x = <- c – Waits to receive a value and stores it in x
x, ok = <- c – Waits to receive a value; ok will be
false if channel is closed and empty.

www.cloudflare.com!
Unbuffered channels are best
•  They provide both communication and synchronization
func from(connection chan int) {!
connection <- rand.Intn(100)!
}!
!
func to(connection chan int) {!
i := <- connection!
fmt.Printf("Someone sent me %dn", i)!
}!
!
func main() {!
cpus := runtime.NumCPU()!
runtime.GOMAXPROCS(cpus)!
!
connection := make(chan int)!
go from(connection)!
go to(connection)!
...!
}!
www.cloudflare.com!
Using channels for signaling
(1)
•  Sometimes just closing a channel is enough
c := make(chan bool)!
!
go func() {!
!// ... do some stuff!
!close(c)!
}()!
!
// ... do some other stuff!
<- c!

www.cloudflare.com!
Using channels for signaling (2) 
•  Close a channel to coordinate multiple goroutines
func worker(start chan bool) {!
<- start!
// ... do stuff!
}!
!
func main() {!
start := make(chan bool)!
!
for i := 0; i < 100; i++ {!
go worker(start)!
}!
!
close(start)!
!
// ... all workers running now!
}!
www.cloudflare.com!
Select
•  Select statement enables sending/receiving on multiple

channels at once
select {!
case x := <- somechan:!
// ... do stuff with x!
!
case y, ok := <- someOtherchan:!
// ... do stuff with y!
// check ok to see if someOtherChan!
// is closed!
!
case outputChan <- z:!
// ... ok z was sent!
!
default:!
// ... no one wants to communicate!
}!
www.cloudflare.com!
Common idiom: for/select!
for {!
select {!
case x := <- somechan:!
// ... do stuff with x!
!
case y, ok := <- someOtherchan:!
// ... do stuff with y!
// check ok to see if someOtherChan!
// is closed!
!
case outputChan <- z:!
// ... ok z was sent!
!
default:!
// ... no one wants to communicate!
}!
}!

www.cloudflare.com!
Using channels for signaling (4)
•  Close a channel to terminate multiple goroutines
func worker(die chan bool) {!
for {!
select {!
// ... do stuff cases!
case <- die: !
return!
}!
}!
}!
!
func main() {!
die := make(chan bool)!
for i := 0; i < 100; i++ {!
go worker(die)!
}!
close(die)!
}!
www.cloudflare.com!
Using channels for signaling (5)
•  Terminate a goroutine and verify termination
func worker(die chan bool) {!
for {!
select {!
// ... do stuff cases!
case <- die:!
// ... do termination tasks !
die <- true!
return!
}!
}!
}!
func main() {!
die := make(chan bool)!
go worker(die)!
die <- true!
<- die!
}!
www.cloudflare.com!
Example: unique ID service
•  Just receive from id to get a unique ID
•  Safe to share id channel across routines
id := make(chan string)!
!
go func() {!
var counter int64 = 0!
for {!
id <- fmt.Sprintf("%x", counter)!
counter += 1!
}!
}()!
!
x := <- id // x will be 1!
x = <- id // x will be 2!

www.cloudflare.com!
Example: memory recycler
func recycler(give, get chan []byte) {!
q := new(list.List)!
!
for {!
if q.Len() == 0 {!
q.PushFront(make([]byte, 100))!
}!
!
e := q.Front()!
!
select {!
case s := <-give:!
q.PushFront(s[:0])!
!
case get <- e.Value.([]byte):!
q.Remove(e)!
}!
}!
}!
www.cloudflare.com!
Timeout
func worker(start chan bool) {!
for {!
!timeout := time.After(30 * time.Second)!
!select {!
// ... do some stuff!
!
case <- timeout:!
return!
}!
func worker(start chan bool) {!
}!
timeout := time.After(30 * time.Second)!
}!
for {!
!select {!
// ... do some stuff!
!
case <- timeout:!
return!
}!
}!
}!
www.cloudflare.com!
Heartbeat
func worker(start chan bool) {!
heartbeat := time.Tick(30 * time.Second)!
for {!
!select {!
// ... do some stuff!
!
case <- heartbeat:!
// ... do heartbeat stuff!
}!
}!
}!

www.cloudflare.com!
Example: network multiplexor
•  Multiple goroutines can send on the same channel
func worker(messages chan string) {!
for {!
var msg string // ... generate a message!
messages <- msg!
}!
}!
func main() {!
messages := make(chan string)!
conn, _ := net.Dial("tcp", "example.com")!
!
for i := 0; i < 100; i++ {!
go worker(messages)!
}!
for {!
msg := <- messages!
conn.Write([]byte(msg))!
}!
}!

www.cloudflare.com!
Example: first of N
•  Dispatch requests and get back the first one to complete
type response struct {!
resp *http.Response!
url string!
}!
!
func get(url string, r chan response ) {!
if resp, err := http.Get(url); err == nil {!
r <- response{resp, url}!
}!
}!
!
func main() {!
first := make(chan response)!
for _, url := range []string{"http://code.jquery.com/jquery-1.9.1.min.js",!
"http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js",!
"http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js",!
"http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"} {!
go get(url, first)!
}!
!
r := <- first!
// ... do something!
}!
www.cloudflare.com!
range!
•  Can be used to consume all values from a channel
func generator(strings chan string) {!
strings <- "Five hour's New York jet lag"!
strings <- "and Cayce Pollard wakes in Camden Town"!
strings <- "to the dire and ever-decreasing circles"!
strings <- "of disrupted circadian rhythm."!
close(strings)!
}!
!
func main() {!
strings := make(chan string)!
go generator(strings)!
!
for s := range strings {!
fmt.Printf("%s ", s)!
}!
fmt.Printf("n");!
}!
www.cloudflare.com!
Passing a ‘response’ channel
type work struct {!
url string!
resp chan *http.Response!
}!
!
func getter(w chan work) {!
for {!
do := <- w!
resp, _ := http.Get(do.url)!
do.resp <- resp!
}!
}!
!
func main() {!
w := make(chan work)!
!
go getter(w)!
!
resp := make(chan *http.Response)!
w <- work{"http://cdnjs.cloudflare.com/jquery/1.9.1/jquery.min.js",!
resp}!
!
r := <- resp!
}!
www.cloudflare.com!
Buffered channels
•  Can be useful to create queues
•  But make reasoning about concurrency more difficult

c := make(chan bool, 100) !

www.cloudflare.com!
High Speed Compilation
•  Go includes its own tool chain
•  Go language enforces removal of unused dependencies
•  Output is a single static binary
•  Result is very large builds in seconds

www.cloudflare.com!
Things not in Go
•  Generics of any kind
•  Assertions
•  Type inheritance
•  Operator overloading
•  Pointer arithmetic
•  Exceptions

www.cloudflare.com!
THANKS
The Go Way: “small sequential pieces joined
by channels”

www.cloudflare.com!
APPENDIX

www.cloudflare.com!
Example: an HTTP load balancer
•  Limited number of HTTP clients can make requests for

URLs
•  Unlimited number of goroutines need to request URLs
and get responses

•  Solution: an HTTP request load balancer

www.cloudflare.com!
A URL getter
type job struct {!
url string!
resp chan *http.Response!
}!
!
type worker struct {!
jobs chan *job!
count int!
}!
!
func (w *worker) getter(done chan *worker) {!
for {!
j := <- w.jobs!
resp, _ := http.Get(j.url)!
j.resp <- resp!
done <- w!
}!
}!
www.cloudflare.com!
A way to get URLs
func get(jobs chan *job, url string, answer chan string) {!
resp := make(chan *http.Response)!
jobs <- &job{url, resp}!
r := <- resp!
answer <- r.Request.URL.String()!
}!
!
func main() {!
jobs := balancer(10, 10)!
answer := make(chan string)!
for {!
var url string!
if _, err := fmt.Scanln(&url); err != nil {!
break!
}!
go get(jobs, url, answer)!
}!
for u := range answer {!
fmt.Printf("%sn", u)!
}!
}!
www.cloudflare.com!
A load balancer
func balancer(count int, depth int) chan *job {!
jobs := make(chan *job)!
done := make(chan *worker)!
workers := make([]*worker, count)!
!
for i := 0; i < count; i++ {!
workers[i] = &worker{make(chan *job,

depth), 0}!
go workers[i].getter(done)!
}!
!
!
select {!
go func() {!
case j := <- jobsource:!
for {!
free.jobs <- j!
var free *worker!
free.count++!
min := depth!
!
for _, w := range workers {!
case w := <- done:!
if w.count < min {!
w.count—!
free = w!
}!
min = w.count!
}!
}!
}()!
}!
!
!
return jobs!
var jobsource chan *job!
}!
if free != nil {!
jobsource = jobs!
}!
www.cloudflare.com!
Top 500 web sites loaded

www.cloudflare.com!

More Related Content

What's hot (20)

PPTX
Lua: the world's most infuriating language
jgrahamc
 
KEY
Python在豆瓣的应用
Qiangning Hong
 
PDF
JVMLS 2016. Coroutines in Kotlin
Andrey Breslav
 
PDF
Aplicações assíncronas no Android com Coroutines & Jetpack
Nelson Glauber Leal
 
PDF
Python高级编程(二)
Qiangning Hong
 
PDF
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
PDF
Mastering Kotlin Standard Library
Nelson Glauber Leal
 
PDF
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
Wanbok Choi
 
PDF
Practical Testing of Ruby Core
Hiroshi SHIBATA
 
PPTX
Terraform Immutablish Infrastructure with Consul-Template
Zane Williamson
 
PDF
Letswift19-clean-architecture
Jung Kim
 
PDF
Exploring Clojurescript
Luke Donnet
 
PDF
Plumbin Pipelines - A Gulp.js workshop
Stefan Baumgartner
 
PDF
The future of async i/o in Python
Saúl Ibarra Corretgé
 
PDF
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
Jeongkyu Shin
 
PDF
Web Crawling with NodeJS
Sylvain Zimmer
 
PDF
Advanced JavaScript build pipelines using Gulp.js
Stefan Baumgartner
 
PDF
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Tom Croucher
 
PDF
Microarmy - by J2 Labs
James Dennis
 
Lua: the world's most infuriating language
jgrahamc
 
Python在豆瓣的应用
Qiangning Hong
 
JVMLS 2016. Coroutines in Kotlin
Andrey Breslav
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Nelson Glauber Leal
 
Python高级编程(二)
Qiangning Hong
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
Mastering Kotlin Standard Library
Nelson Glauber Leal
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
Wanbok Choi
 
Practical Testing of Ruby Core
Hiroshi SHIBATA
 
Terraform Immutablish Infrastructure with Consul-Template
Zane Williamson
 
Letswift19-clean-architecture
Jung Kim
 
Exploring Clojurescript
Luke Donnet
 
Plumbin Pipelines - A Gulp.js workshop
Stefan Baumgartner
 
The future of async i/o in Python
Saúl Ibarra Corretgé
 
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
Jeongkyu Shin
 
Web Crawling with NodeJS
Sylvain Zimmer
 
Advanced JavaScript build pipelines using Gulp.js
Stefan Baumgartner
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Tom Croucher
 
Microarmy - by J2 Labs
James Dennis
 

Viewers also liked (20)

PPT
Why Outsource Business Issues
brooklynclasby
 
ODP
Winter 1 vega
Simpony
 
ODP
Dualacy uni chapter one
Simpony
 
DOC
Bio Lab Paper
tclythgoe84
 
PDF
Sullivan handshake proxying-ieee-sp_2014
Cloudflare
 
PPTX
rowell resperatory system
rowellcabate
 
PDF
Architectural arcadia
Devon Tl
 
PDF
Chapter 6
Simpony
 
PDF
Winter 2 goodie
Simpony
 
PDF
Chapter 8
Simpony
 
PDF
Cloud flare jgc bigo meetup rolling hashes
Cloudflare
 
PPTX
Harriyadi Irawan Menu project
Harry Copeland
 
PPTX
CMC Teacher Education SIG Presentation; Kurek
CmcTchrEdSIG
 
PDF
Fall 2 smithe
Simpony
 
PDF
Alcinen heights intro
Simpony
 
PDF
Spring 3 vega
Simpony
 
PPT
Prezentangielskizrobiona 110509171449-phpapp02
monia1989
 
PDF
Highlights of Go 1.1
Cloudflare
 
ODP
Spring 2 cooke
Simpony
 
ODP
Summer 2 smithe
Simpony
 
Why Outsource Business Issues
brooklynclasby
 
Winter 1 vega
Simpony
 
Dualacy uni chapter one
Simpony
 
Bio Lab Paper
tclythgoe84
 
Sullivan handshake proxying-ieee-sp_2014
Cloudflare
 
rowell resperatory system
rowellcabate
 
Architectural arcadia
Devon Tl
 
Chapter 6
Simpony
 
Winter 2 goodie
Simpony
 
Chapter 8
Simpony
 
Cloud flare jgc bigo meetup rolling hashes
Cloudflare
 
Harriyadi Irawan Menu project
Harry Copeland
 
CMC Teacher Education SIG Presentation; Kurek
CmcTchrEdSIG
 
Fall 2 smithe
Simpony
 
Alcinen heights intro
Simpony
 
Spring 3 vega
Simpony
 
Prezentangielskizrobiona 110509171449-phpapp02
monia1989
 
Highlights of Go 1.1
Cloudflare
 
Spring 2 cooke
Simpony
 
Summer 2 smithe
Simpony
 
Ad

Similar to An Introduction to Go (20)

PDF
Go Concurrency
jgrahamc
 
PDF
A Channel Compendium
Cloudflare
 
PDF
LCA2014 - Introduction to Go
dreamwidth
 
PDF
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
PROIDEA
 
PDF
Go, the one language to learn in 2014
Andrzej Grzesik
 
PDF
Concurrency in Golang
Oliver N
 
PDF
Goroutines and Channels in practice
Guilherme Garnier
 
PDF
WebSummit 2015 - Gopher it
Gautam Rege
 
PDF
Go concurrency
siuyin
 
PPTX
Go Concurrency Patterns
ElifTech
 
PPT
go.ppt
ssuser4ca1eb
 
PDF
Go for Rubyists
tchandy
 
PPTX
Fundamental concurrent programming
Dimas Prawira
 
KEY
Google Go Overview
Moritz Haarmann
 
PDF
Golang Channels
Joris Bonnefoy
 
PPT
Concurrency in go
borderj
 
PDF
Inroduction to golang
Yoni Davidson
 
KEY
Beauty and Power of Go
Frank Müller
 
PDF
Let's Go-lang
Luka Zakrajšek
 
PDF
The async/await concurrency pattern in Golang
Matteo Madeddu
 
Go Concurrency
jgrahamc
 
A Channel Compendium
Cloudflare
 
LCA2014 - Introduction to Go
dreamwidth
 
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
PROIDEA
 
Go, the one language to learn in 2014
Andrzej Grzesik
 
Concurrency in Golang
Oliver N
 
Goroutines and Channels in practice
Guilherme Garnier
 
WebSummit 2015 - Gopher it
Gautam Rege
 
Go concurrency
siuyin
 
Go Concurrency Patterns
ElifTech
 
go.ppt
ssuser4ca1eb
 
Go for Rubyists
tchandy
 
Fundamental concurrent programming
Dimas Prawira
 
Google Go Overview
Moritz Haarmann
 
Golang Channels
Joris Bonnefoy
 
Concurrency in go
borderj
 
Inroduction to golang
Yoni Davidson
 
Beauty and Power of Go
Frank Müller
 
Let's Go-lang
Luka Zakrajšek
 
The async/await concurrency pattern in Golang
Matteo Madeddu
 
Ad

More from Cloudflare (20)

PDF
Succeeding with Secure Access Service Edge (SASE)
Cloudflare
 
PPTX
Close your security gaps and get 100% of your traffic protected with Cloudflare
Cloudflare
 
PPTX
Why you should replace your d do s hardware appliance
Cloudflare
 
PPTX
Don't Let Bots Ruin Your Holiday Business - Snackable Webinar
Cloudflare
 
PPTX
Why Zero Trust Architecture Will Become the New Normal in 2021
Cloudflare
 
PPTX
HARTMANN and Cloudflare Learn how healthcare providers can build resilient in...
Cloudflare
 
PPTX
Zero trust for everybody: 3 ways to get there fast
Cloudflare
 
PPTX
LendingTree and Cloudflare: Ensuring zero trade-off between security and cust...
Cloudflare
 
PPTX
Network Transformation: What it is, and how it’s helping companies stay secur...
Cloudflare
 
PPTX
Scaling service provider business with DDoS-mitigation-as-a-service
Cloudflare
 
PPTX
Application layer attack trends through the lens of Cloudflare data
Cloudflare
 
PPTX
Recent DDoS attack trends, and how you should respond
Cloudflare
 
PPTX
Cybersecurity 2020 threat landscape and its implications (AMER)
Cloudflare
 
PPTX
Strengthening security posture for modern-age SaaS providers
Cloudflare
 
PPTX
Kentik and Cloudflare Partner to Mitigate Advanced DDoS Attacks
Cloudflare
 
PDF
Stopping DDoS Attacks in North America
Cloudflare
 
PPTX
It’s 9AM... Do you know what’s happening on your network?
Cloudflare
 
PPTX
Cyber security fundamentals (simplified chinese)
Cloudflare
 
PPTX
Bring speed and security to the intranet with cloudflare for teams
Cloudflare
 
PPTX
Accelerate your digital transformation
Cloudflare
 
Succeeding with Secure Access Service Edge (SASE)
Cloudflare
 
Close your security gaps and get 100% of your traffic protected with Cloudflare
Cloudflare
 
Why you should replace your d do s hardware appliance
Cloudflare
 
Don't Let Bots Ruin Your Holiday Business - Snackable Webinar
Cloudflare
 
Why Zero Trust Architecture Will Become the New Normal in 2021
Cloudflare
 
HARTMANN and Cloudflare Learn how healthcare providers can build resilient in...
Cloudflare
 
Zero trust for everybody: 3 ways to get there fast
Cloudflare
 
LendingTree and Cloudflare: Ensuring zero trade-off between security and cust...
Cloudflare
 
Network Transformation: What it is, and how it’s helping companies stay secur...
Cloudflare
 
Scaling service provider business with DDoS-mitigation-as-a-service
Cloudflare
 
Application layer attack trends through the lens of Cloudflare data
Cloudflare
 
Recent DDoS attack trends, and how you should respond
Cloudflare
 
Cybersecurity 2020 threat landscape and its implications (AMER)
Cloudflare
 
Strengthening security posture for modern-age SaaS providers
Cloudflare
 
Kentik and Cloudflare Partner to Mitigate Advanced DDoS Attacks
Cloudflare
 
Stopping DDoS Attacks in North America
Cloudflare
 
It’s 9AM... Do you know what’s happening on your network?
Cloudflare
 
Cyber security fundamentals (simplified chinese)
Cloudflare
 
Bring speed and security to the intranet with cloudflare for teams
Cloudflare
 
Accelerate your digital transformation
Cloudflare
 

Recently uploaded (20)

PPTX
Machine Learning Benefits Across Industries
SynapseIndia
 
PPTX
AI Code Generation Risks (Ramkumar Dilli, CIO, Myridius)
Priyanka Aash
 
PDF
Women in Automation Presents: Reinventing Yourself — Bold Career Pivots That ...
DianaGray10
 
PPTX
The Yotta x CloudStack Advantage: Scalable, India-First Cloud
ShapeBlue
 
PDF
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
PDF
NewMind AI Weekly Chronicles – July’25, Week III
NewMind AI
 
PPTX
Simplifying End-to-End Apache CloudStack Deployment with a Web-Based Automati...
ShapeBlue
 
PDF
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
PDF
Novus-Safe Pro: Brochure-What is Novus Safe Pro?.pdf
Novus Hi-Tech
 
PDF
UiPath vs Other Automation Tools Meeting Presentation.pdf
Tracy Dixon
 
PDF
2025-07-15 EMEA Volledig Inzicht Dutch Webinar
ThousandEyes
 
PPTX
Building and Operating a Private Cloud with CloudStack and LINBIT CloudStack ...
ShapeBlue
 
PDF
Novus Safe Lite- What is Novus Safe Lite.pdf
Novus Hi-Tech
 
PDF
CIFDAQ'S Token Spotlight for 16th July 2025 - ALGORAND
CIFDAQ
 
PDF
Trading Volume Explained by CIFDAQ- Secret Of Market Trends
CIFDAQ
 
PDF
Shuen Mei Parth Sharma Boost Productivity, Innovation and Efficiency wit...
AWS Chicago
 
PDF
OpenInfra ID 2025 - Are Containers Dying? Rethinking Isolation with MicroVMs.pdf
Muhammad Yuga Nugraha
 
PDF
Bitcoin+ Escalando sin concesiones - Parte 1
Fernando Paredes García
 
PDF
State-Dependent Conformal Perception Bounds for Neuro-Symbolic Verification
Ivan Ruchkin
 
PDF
UiPath on Tour London Community Booth Deck
UiPathCommunity
 
Machine Learning Benefits Across Industries
SynapseIndia
 
AI Code Generation Risks (Ramkumar Dilli, CIO, Myridius)
Priyanka Aash
 
Women in Automation Presents: Reinventing Yourself — Bold Career Pivots That ...
DianaGray10
 
The Yotta x CloudStack Advantage: Scalable, India-First Cloud
ShapeBlue
 
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
NewMind AI Weekly Chronicles – July’25, Week III
NewMind AI
 
Simplifying End-to-End Apache CloudStack Deployment with a Web-Based Automati...
ShapeBlue
 
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
Novus-Safe Pro: Brochure-What is Novus Safe Pro?.pdf
Novus Hi-Tech
 
UiPath vs Other Automation Tools Meeting Presentation.pdf
Tracy Dixon
 
2025-07-15 EMEA Volledig Inzicht Dutch Webinar
ThousandEyes
 
Building and Operating a Private Cloud with CloudStack and LINBIT CloudStack ...
ShapeBlue
 
Novus Safe Lite- What is Novus Safe Lite.pdf
Novus Hi-Tech
 
CIFDAQ'S Token Spotlight for 16th July 2025 - ALGORAND
CIFDAQ
 
Trading Volume Explained by CIFDAQ- Secret Of Market Trends
CIFDAQ
 
Shuen Mei Parth Sharma Boost Productivity, Innovation and Efficiency wit...
AWS Chicago
 
OpenInfra ID 2025 - Are Containers Dying? Rethinking Isolation with MicroVMs.pdf
Muhammad Yuga Nugraha
 
Bitcoin+ Escalando sin concesiones - Parte 1
Fernando Paredes García
 
State-Dependent Conformal Perception Bounds for Neuro-Symbolic Verification
Ivan Ruchkin
 
UiPath on Tour London Community Booth Deck
UiPathCommunity
 

An Introduction to Go

  • 1. Trends in concurrent programming languages Google’s Go April 7, 2013 John Graham-Cumming www.cloudflare.com!
  • 2. Go (golang) •  Created in 2007 internally at Google •  Announced in 2009 •  Currently on Go 1.0.3 (Go 1.1RC2 released yesterday) •  Headlines •  Intended for ‘systems programming’ •  Statically typed •  Garbage collected •  Designed for concurrency •  Very high speed compilation •  Syntax very familiar to C/C++/Java programmers •  “A small language” www.cloudflare.com!
  • 3. Small number of built in types •  int, float, string (mutable), boolean •  pointers •  map m := make(map[string]int)! m[“Hello”] = 10! •  slice (bounds checked) a := make([]int, 10)
 ! a[0] = 42! b := a[1,3]! •  channel •  structure, function, interface www.cloudflare.com!
  • 4. OO using interfaces •  Interface type •  Static ‘duck’ typing type Sequence []int! ! func (s Sequence) Size() int {! return len(s)! }! ! type Sizer interface {! Size() int! }! ! func Foo (o Sizer) {! ...! }! www.cloudflare.com!
  • 5. Statically typed •  Familiar type declarations type currency struct {! id string! longName string! }! ! type transaction struct {! cur currency! amnt int! }! ! sterling := currency{“GBP”, “British Pounds Sterling”}! ! var credit = transaction{cur: sterling, amnt: 100}! ! lastCredit = &credit! ! lastCredit.amnt += 100! www.cloudflare.com!
  • 6. One type of loop, one iterator for i := 0; i < 10; i++ {! ...! }! ! for {! ...! }! ! for some_boolean {! ...! }! ! for i, v := range some_slice {! ...! }! ! for k, v := range some_map {! ...! }! www.cloudflare.com!
  • 7. Explicit error returns •  No (actually, very limited) exception mechanism •  The Go way is multiple returns with errors conn, err := net.Dial("tcp", "example.com”)! ! if x, err := do(); err == nil {! ...! } else {! ...! }! •  Can explicitly ignore errors if desired conn, _ := net.Dial("tcp", "example.com”)! www.cloudflare.com!
  • 8. Garbage Collected •  Parallel mark-and-sweep garbage collector www.cloudflare.com!
  • 9. Possible Concurrency Options •  Processes with IPC •  Classic ‘Unix’ processes •  Erlang processes and mailboxes •  coroutines •  Lua uses coroutines with explicit yields •  Threads with shared memory •  OS vs. user space •  Go’s goroutines are close to ‘green threads’ •  Event driven •  node.js, JavaScript •  Many GUI frameworks www.cloudflare.com!
  • 10. Concurrency •  goroutines •  Very lightweight processes/threads •  All scheduling handled internally by the Go runtime •  Unless you are CPU bound you do not have to think about scheduling •  Multiplexed onto system threads, OS polling for I/O •  Channel-based communication •  The right way for goroutines to talk to each other •  Synchronization Library (sync) •  For when a channel is too heavyweight •  Rarely used—not going to discuss www.cloudflare.com!
  • 11. goroutines •  “Lightweight” •  Starting 10,000 goroutines on my MacBook Pro took 22ms •  Allocated memory increased by 3,014,000 bytes (301 bytes per goroutine) •  https://gist.github.com/jgrahamc/5253020 •  Not unusual at CloudFlare to have a single Go program running 10,000s of goroutines with 1,000,000s of goroutines created during life program. •  So, go yourFunc() as much as you like. www.cloudflare.com!
  • 12. Channels •  c := make(chan bool)– Makes an unbuffered channel of bools c <- x – Sends a value on the channel <- c – Waits to receive a value on the channel x = <- c – Waits to receive a value and stores it in x x, ok = <- c – Waits to receive a value; ok will be false if channel is closed and empty. www.cloudflare.com!
  • 13. Unbuffered channels are best •  They provide both communication and synchronization func from(connection chan int) {! connection <- rand.Intn(100)! }! ! func to(connection chan int) {! i := <- connection! fmt.Printf("Someone sent me %dn", i)! }! ! func main() {! cpus := runtime.NumCPU()! runtime.GOMAXPROCS(cpus)! ! connection := make(chan int)! go from(connection)! go to(connection)! ...! }! www.cloudflare.com!
  • 14. Using channels for signaling (1) •  Sometimes just closing a channel is enough c := make(chan bool)! ! go func() {! !// ... do some stuff! !close(c)! }()! ! // ... do some other stuff! <- c! www.cloudflare.com!
  • 15. Using channels for signaling (2) •  Close a channel to coordinate multiple goroutines func worker(start chan bool) {! <- start! // ... do stuff! }! ! func main() {! start := make(chan bool)! ! for i := 0; i < 100; i++ {! go worker(start)! }! ! close(start)! ! // ... all workers running now! }! www.cloudflare.com!
  • 16. Select •  Select statement enables sending/receiving on multiple channels at once select {! case x := <- somechan:! // ... do stuff with x! ! case y, ok := <- someOtherchan:! // ... do stuff with y! // check ok to see if someOtherChan! // is closed! ! case outputChan <- z:! // ... ok z was sent! ! default:! // ... no one wants to communicate! }! www.cloudflare.com!
  • 17. Common idiom: for/select! for {! select {! case x := <- somechan:! // ... do stuff with x! ! case y, ok := <- someOtherchan:! // ... do stuff with y! // check ok to see if someOtherChan! // is closed! ! case outputChan <- z:! // ... ok z was sent! ! default:! // ... no one wants to communicate! }! }! www.cloudflare.com!
  • 18. Using channels for signaling (4) •  Close a channel to terminate multiple goroutines func worker(die chan bool) {! for {! select {! // ... do stuff cases! case <- die: ! return! }! }! }! ! func main() {! die := make(chan bool)! for i := 0; i < 100; i++ {! go worker(die)! }! close(die)! }! www.cloudflare.com!
  • 19. Using channels for signaling (5) •  Terminate a goroutine and verify termination func worker(die chan bool) {! for {! select {! // ... do stuff cases! case <- die:! // ... do termination tasks ! die <- true! return! }! }! }! func main() {! die := make(chan bool)! go worker(die)! die <- true! <- die! }! www.cloudflare.com!
  • 20. Example: unique ID service •  Just receive from id to get a unique ID •  Safe to share id channel across routines id := make(chan string)! ! go func() {! var counter int64 = 0! for {! id <- fmt.Sprintf("%x", counter)! counter += 1! }! }()! ! x := <- id // x will be 1! x = <- id // x will be 2! www.cloudflare.com!
  • 21. Example: memory recycler func recycler(give, get chan []byte) {! q := new(list.List)! ! for {! if q.Len() == 0 {! q.PushFront(make([]byte, 100))! }! ! e := q.Front()! ! select {! case s := <-give:! q.PushFront(s[:0])! ! case get <- e.Value.([]byte):! q.Remove(e)! }! }! }! www.cloudflare.com!
  • 22. Timeout func worker(start chan bool) {! for {! !timeout := time.After(30 * time.Second)! !select {! // ... do some stuff! ! case <- timeout:! return! }! func worker(start chan bool) {! }! timeout := time.After(30 * time.Second)! }! for {! !select {! // ... do some stuff! ! case <- timeout:! return! }! }! }! www.cloudflare.com!
  • 23. Heartbeat func worker(start chan bool) {! heartbeat := time.Tick(30 * time.Second)! for {! !select {! // ... do some stuff! ! case <- heartbeat:! // ... do heartbeat stuff! }! }! }! www.cloudflare.com!
  • 24. Example: network multiplexor •  Multiple goroutines can send on the same channel func worker(messages chan string) {! for {! var msg string // ... generate a message! messages <- msg! }! }! func main() {! messages := make(chan string)! conn, _ := net.Dial("tcp", "example.com")! ! for i := 0; i < 100; i++ {! go worker(messages)! }! for {! msg := <- messages! conn.Write([]byte(msg))! }! }! www.cloudflare.com!
  • 25. Example: first of N •  Dispatch requests and get back the first one to complete type response struct {! resp *http.Response! url string! }! ! func get(url string, r chan response ) {! if resp, err := http.Get(url); err == nil {! r <- response{resp, url}! }! }! ! func main() {! first := make(chan response)! for _, url := range []string{"http://code.jquery.com/jquery-1.9.1.min.js",! "http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js",! "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js",! "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"} {! go get(url, first)! }! ! r := <- first! // ... do something! }! www.cloudflare.com!
  • 26. range! •  Can be used to consume all values from a channel func generator(strings chan string) {! strings <- "Five hour's New York jet lag"! strings <- "and Cayce Pollard wakes in Camden Town"! strings <- "to the dire and ever-decreasing circles"! strings <- "of disrupted circadian rhythm."! close(strings)! }! ! func main() {! strings := make(chan string)! go generator(strings)! ! for s := range strings {! fmt.Printf("%s ", s)! }! fmt.Printf("n");! }! www.cloudflare.com!
  • 27. Passing a ‘response’ channel type work struct {! url string! resp chan *http.Response! }! ! func getter(w chan work) {! for {! do := <- w! resp, _ := http.Get(do.url)! do.resp <- resp! }! }! ! func main() {! w := make(chan work)! ! go getter(w)! ! resp := make(chan *http.Response)! w <- work{"http://cdnjs.cloudflare.com/jquery/1.9.1/jquery.min.js",! resp}! ! r := <- resp! }! www.cloudflare.com!
  • 28. Buffered channels •  Can be useful to create queues •  But make reasoning about concurrency more difficult c := make(chan bool, 100) ! www.cloudflare.com!
  • 29. High Speed Compilation •  Go includes its own tool chain •  Go language enforces removal of unused dependencies •  Output is a single static binary •  Result is very large builds in seconds www.cloudflare.com!
  • 30. Things not in Go •  Generics of any kind •  Assertions •  Type inheritance •  Operator overloading •  Pointer arithmetic •  Exceptions www.cloudflare.com!
  • 31. THANKS The Go Way: “small sequential pieces joined by channels” www.cloudflare.com!
  • 33. Example: an HTTP load balancer •  Limited number of HTTP clients can make requests for URLs •  Unlimited number of goroutines need to request URLs and get responses •  Solution: an HTTP request load balancer www.cloudflare.com!
  • 34. A URL getter type job struct {! url string! resp chan *http.Response! }! ! type worker struct {! jobs chan *job! count int! }! ! func (w *worker) getter(done chan *worker) {! for {! j := <- w.jobs! resp, _ := http.Get(j.url)! j.resp <- resp! done <- w! }! }! www.cloudflare.com!
  • 35. A way to get URLs func get(jobs chan *job, url string, answer chan string) {! resp := make(chan *http.Response)! jobs <- &job{url, resp}! r := <- resp! answer <- r.Request.URL.String()! }! ! func main() {! jobs := balancer(10, 10)! answer := make(chan string)! for {! var url string! if _, err := fmt.Scanln(&url); err != nil {! break! }! go get(jobs, url, answer)! }! for u := range answer {! fmt.Printf("%sn", u)! }! }! www.cloudflare.com!
  • 36. A load balancer func balancer(count int, depth int) chan *job {! jobs := make(chan *job)! done := make(chan *worker)! workers := make([]*worker, count)! ! for i := 0; i < count; i++ {! workers[i] = &worker{make(chan *job,
 depth), 0}! go workers[i].getter(done)! }! ! ! select {! go func() {! case j := <- jobsource:! for {! free.jobs <- j! var free *worker! free.count++! min := depth! ! for _, w := range workers {! case w := <- done:! if w.count < min {! w.count—! free = w! }! min = w.count! }! }! }()! }! ! ! return jobs! var jobsource chan *job! }! if free != nil {! jobsource = jobs! }! www.cloudflare.com!
  • 37. Top 500 web sites loaded www.cloudflare.com!