SlideShare a Scribd company logo
Go Concurrency
                     March 27, 2013



                      John Graham-Cumming




www.cloudflare.com!
Fundamentals
 •  goroutines
    •  Very lightweight processes
    •  All scheduling handled internally by the Go runtime
    •  Unless you are CPU bound you do not have to think about
       scheduling
       
 •  Channel-based communication
    •  The right way for goroutines to talk to each other
       
 •  Synchronization Primitives
    •  For when a channel is too heavyweight
    •  Not covered in this talk




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
 •  Quick syntax review

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




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




www.cloudflare.com!

More Related Content

What's hot

Rust
RustRust
Go. Why it goes
Go. Why it goesGo. Why it goes
Go. Why it goes
Sergey Pichkurov
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
Slawomir Dorzak
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
Designveloper
 
An Actor Model in Go
An Actor Model in GoAn Actor Model in Go
An Actor Model in Go
Weaveworks
 
Go Programming Language by Google
Go Programming Language by GoogleGo Programming Language by Google
Go Programming Language by Google
Uttam Gandhi
 
Completable future
Completable futureCompletable future
Completable future
Srinivasan Raghvan
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
Roman Elizarov
 
Golang
GolangGolang
Golang
Felipe Mamud
 
The Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventureThe Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventure
mylittleadventure
 
Golang workshop
Golang workshopGolang workshop
Golang workshop
Victor S. Recio
 
Introduction to memcached
Introduction to memcachedIntroduction to memcached
Introduction to memcached
Jurriaan Persyn
 
Golang
GolangGolang
Rust-lang
Rust-langRust-lang
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
Nascenia IT
 
Go Lang Tutorial
Go Lang TutorialGo Lang Tutorial
Go Lang Tutorial
Wei-Ning Huang
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
Garrett Welson
 
gRPC: The Story of Microservices at Square
gRPC: The Story of Microservices at SquaregRPC: The Story of Microservices at Square
gRPC: The Story of Microservices at Square
Apigee | Google Cloud
 
Rust vs C++
Rust vs C++Rust vs C++
Rust vs C++
corehard_by
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
Derek Willian Stavis
 

What's hot (20)

Rust
RustRust
Rust
 
Go. Why it goes
Go. Why it goesGo. Why it goes
Go. Why it goes
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
An Actor Model in Go
An Actor Model in GoAn Actor Model in Go
An Actor Model in Go
 
Go Programming Language by Google
Go Programming Language by GoogleGo Programming Language by Google
Go Programming Language by Google
 
Completable future
Completable futureCompletable future
Completable future
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
Golang
GolangGolang
Golang
 
The Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventureThe Go programming language - Intro by MyLittleAdventure
The Go programming language - Intro by MyLittleAdventure
 
Golang workshop
Golang workshopGolang workshop
Golang workshop
 
Introduction to memcached
Introduction to memcachedIntroduction to memcached
Introduction to memcached
 
Golang
GolangGolang
Golang
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
Go Lang Tutorial
Go Lang TutorialGo Lang Tutorial
Go Lang Tutorial
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
gRPC: The Story of Microservices at Square
gRPC: The Story of Microservices at SquaregRPC: The Story of Microservices at Square
gRPC: The Story of Microservices at Square
 
Rust vs C++
Rust vs C++Rust vs C++
Rust vs C++
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 

Viewers also liked

Go Containers
Go ContainersGo Containers
Go Containers
jgrahamc
 
Demystifying the Go Scheduler
Demystifying the Go SchedulerDemystifying the Go Scheduler
Demystifying the Go Scheduler
matthewrdale
 
Introduction to Go scheduler
Introduction to Go schedulerIntroduction to Go scheduler
Introduction to Go scheduler
Bin Wang
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
borderj
 
Concurrency patterns
Concurrency patternsConcurrency patterns
Concurrency patterns
Aaron Schlesinger
 
An introduction to programming in Go
An introduction to programming in GoAn introduction to programming in Go
An introduction to programming in Go
David Robert Camargo de Campos
 
Concurrent programming1
Concurrent programming1Concurrent programming1
Concurrent programming1
Nick Brandaleone
 
The low level awesomeness of Go
The low level awesomeness of GoThe low level awesomeness of Go
The low level awesomeness of Go
Jean-Bernard Jansen
 
Golang
GolangGolang
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
Hakim El Hattab
 

Viewers also liked (10)

Go Containers
Go ContainersGo Containers
Go Containers
 
Demystifying the Go Scheduler
Demystifying the Go SchedulerDemystifying the Go Scheduler
Demystifying the Go Scheduler
 
Introduction to Go scheduler
Introduction to Go schedulerIntroduction to Go scheduler
Introduction to Go scheduler
 
Concurrency in go
Concurrency in goConcurrency in go
Concurrency in go
 
Concurrency patterns
Concurrency patternsConcurrency patterns
Concurrency patterns
 
An introduction to programming in Go
An introduction to programming in GoAn introduction to programming in Go
An introduction to programming in Go
 
Concurrent programming1
Concurrent programming1Concurrent programming1
Concurrent programming1
 
The low level awesomeness of Go
The low level awesomeness of GoThe low level awesomeness of Go
The low level awesomeness of Go
 
Golang
GolangGolang
Golang
 
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
 

Similar to Go Concurrency

Go Concurrency
Go ConcurrencyGo Concurrency
Go ConcurrencyCloudflare
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to GoCloudflare
 
A Channel Compendium
A Channel CompendiumA Channel Compendium
A Channel Compendium
Cloudflare
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
Andrey Breslav
 
Go memory
Go memoryGo memory
Go memory
jgrahamc
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1
jgrahamc
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1Cloudflare
 
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej GrzesikJDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
PROIDEA
 
Go, the one language to learn in 2014
Go, the one language to learn in 2014Go, the one language to learn in 2014
Go, the one language to learn in 2014
Andrzej Grzesik
 
Beyond Page Level Metrics
Beyond Page Level MetricsBeyond Page Level Metrics
Beyond Page Level Metrics
Philip Tellis
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency Patterns
ElifTech
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with Go
Naoki AINOYA
 
Elegant concurrency
Elegant concurrencyElegant concurrency
Elegant concurrency
Mosky Liu
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
Bo-Yi Wu
 
Quick swift tour
Quick swift tourQuick swift tour
Quick swift tour
Kazunobu Tasaka
 
Programming ppt files (final)
Programming ppt files (final)Programming ppt files (final)
Programming ppt files (final)
yap_raiza
 
Akka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesAkka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutes
Konrad Malawski
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
Frank Müller
 
Hadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm ArchitectureHadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm Architecture
P. Taylor Goetz
 

Similar to Go Concurrency (20)

Go Concurrency
Go ConcurrencyGo Concurrency
Go Concurrency
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to Go
 
A Channel Compendium
A Channel CompendiumA Channel Compendium
A Channel Compendium
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
 
Go memory
Go memoryGo memory
Go memory
 
Go Memory
Go MemoryGo Memory
Go Memory
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1
 
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej GrzesikJDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
JDD2014: GO! The one language you have to try in 2014 - Andrzej Grzesik
 
Go, the one language to learn in 2014
Go, the one language to learn in 2014Go, the one language to learn in 2014
Go, the one language to learn in 2014
 
Beyond Page Level Metrics
Beyond Page Level MetricsBeyond Page Level Metrics
Beyond Page Level Metrics
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency Patterns
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with Go
 
Elegant concurrency
Elegant concurrencyElegant concurrency
Elegant concurrency
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
 
Quick swift tour
Quick swift tourQuick swift tour
Quick swift tour
 
Programming ppt files (final)
Programming ppt files (final)Programming ppt files (final)
Programming ppt files (final)
 
Akka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutesAkka persistence == event sourcing in 30 minutes
Akka persistence == event sourcing in 30 minutes
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
Hadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm ArchitectureHadoop Summit Europe 2014: Apache Storm Architecture
Hadoop Summit Europe 2014: Apache Storm Architecture
 

More from jgrahamc

Better living through microcontrollers
Better living through microcontrollersBetter living through microcontrollers
Better living through microcontrollers
jgrahamc
 
Big O London Meetup April 2015
Big O London Meetup April 2015Big O London Meetup April 2015
Big O London Meetup April 2015
jgrahamc
 
How to launch and defend against a DDoS
How to launch and defend against a DDoSHow to launch and defend against a DDoS
How to launch and defend against a DDoSjgrahamc
 
Lua: the world's most infuriating language
Lua: the world's most infuriating languageLua: the world's most infuriating language
Lua: the world's most infuriating language
jgrahamc
 
Software Debugging for High-altitude Balloons
Software Debugging for High-altitude BalloonsSoftware Debugging for High-altitude Balloons
Software Debugging for High-altitude Balloons
jgrahamc
 
That'll never work!
That'll never work!That'll never work!
That'll never work!jgrahamc
 
HAB Software Woes
HAB Software WoesHAB Software Woes
HAB Software Woes
jgrahamc
 
Javascript Security
Javascript SecurityJavascript Security
Javascript Security
jgrahamc
 

More from jgrahamc (8)

Better living through microcontrollers
Better living through microcontrollersBetter living through microcontrollers
Better living through microcontrollers
 
Big O London Meetup April 2015
Big O London Meetup April 2015Big O London Meetup April 2015
Big O London Meetup April 2015
 
How to launch and defend against a DDoS
How to launch and defend against a DDoSHow to launch and defend against a DDoS
How to launch and defend against a DDoS
 
Lua: the world's most infuriating language
Lua: the world's most infuriating languageLua: the world's most infuriating language
Lua: the world's most infuriating language
 
Software Debugging for High-altitude Balloons
Software Debugging for High-altitude BalloonsSoftware Debugging for High-altitude Balloons
Software Debugging for High-altitude Balloons
 
That'll never work!
That'll never work!That'll never work!
That'll never work!
 
HAB Software Woes
HAB Software WoesHAB Software Woes
HAB Software Woes
 
Javascript Security
Javascript SecurityJavascript Security
Javascript Security
 

Recently uploaded

FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 

Go Concurrency

  • 1. Go Concurrency March 27, 2013 John Graham-Cumming www.cloudflare.com!
  • 2. Fundamentals •  goroutines •  Very lightweight processes •  All scheduling handled internally by the Go runtime •  Unless you are CPU bound you do not have to think about scheduling •  Channel-based communication •  The right way for goroutines to talk to each other •  Synchronization Primitives •  For when a channel is too heavyweight •  Not covered in this talk www.cloudflare.com!
  • 3. 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!
  • 4. Channels •  Quick syntax review 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!
  • 5. 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!
  • 6. 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!
  • 7. 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!
  • 8. 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!
  • 9. 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!
  • 10. 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!
  • 11. 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!
  • 12. 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!
  • 13. 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!
  • 14. 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!
  • 15. 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!
  • 16. 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!
  • 17. 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!
  • 18. 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!
  • 19. 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!
  • 20. Buffered channels •  Can be useful to create queues •  But make reasoning about concurrency more difficult c := make(chan bool, 100) ! www.cloudflare.com!
  • 21. 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!
  • 22. 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!
  • 23. 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!
  • 24. 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)! }! ! ! go func() {! select {! for {! case j := <- jobsource:! var free *worker! free.jobs <- j! min := depth! free.count++! for _, w := range workers {! ! if w.count < min {! case w := <- done:! free = w! w.count—! min = w.count! }! }! }! }! }()! ! ! var jobsource chan *job! return jobs! if free != nil {! }! jobsource = jobs! }! www.cloudflare.com!
  • 25. Top 500 web sites loaded www.cloudflare.com!
  • 26. THANKS The Go Way: “small sequential pieces joined by channels” www.cloudflare.com!