SlideShare uma empresa Scribd logo
1 de 26
Baixar para ler offline
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!

Mais conteúdo relacionado

Mais procurados

Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming languageSlawomir Dorzak
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golangBo-Yi Wu
 
Go language presentation
Go language presentationGo language presentation
Go language presentationparamisoft
 
Microservices in Golang
Microservices in GolangMicroservices in Golang
Microservices in GolangMo'ath Qasim
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event LoopDesignveloper
 
Go Programming language, golang
Go Programming language, golangGo Programming language, golang
Go Programming language, golangBasil N G
 
Introduction to go lang
Introduction to go langIntroduction to go lang
Introduction to go langAmal Mohan N
 
Golang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / OverviewGolang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / OverviewMarkus Schneider
 
From Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPFrom Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPAlbert Chen
 
Introduction to Rust language programming
Introduction to Rust language programmingIntroduction to Rust language programming
Introduction to Rust language programmingRodolfo Finochietti
 

Mais procurados (20)

Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golang
 
Go language presentation
Go language presentationGo language presentation
Go language presentation
 
Microservices in Golang
Microservices in GolangMicroservices in Golang
Microservices in Golang
 
Go. Why it goes
Go. Why it goesGo. Why it goes
Go. Why it goes
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Go Lang Tutorial
Go Lang TutorialGo Lang Tutorial
Go Lang Tutorial
 
GoLang Introduction
GoLang IntroductionGoLang Introduction
GoLang Introduction
 
Golang
GolangGolang
Golang
 
Go Programming language, golang
Go Programming language, golangGo Programming language, golang
Go Programming language, golang
 
Introduction to go lang
Introduction to go langIntroduction to go lang
Introduction to go lang
 
Rust vs C++
Rust vs C++Rust vs C++
Rust vs C++
 
Golang
GolangGolang
Golang
 
Golang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / OverviewGolang and Eco-System Introduction / Overview
Golang and Eco-System Introduction / Overview
 
Completable future
Completable futureCompletable future
Completable future
 
gRPC Overview
gRPC OverviewgRPC Overview
gRPC Overview
 
From Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPFrom Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHP
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Go Language presentation
Go Language presentationGo Language presentation
Go Language presentation
 
Introduction to Rust language programming
Introduction to Rust language programmingIntroduction to Rust language programming
Introduction to Rust language programming
 

Destaque

Destaque (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
 

Semelhante a 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 CompendiumCloudflare
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinAndrey Breslav
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1jgrahamc
 
Highlights of Go 1.1
Highlights of Go 1.1Highlights of Go 1.1
Highlights of Go 1.1Cloudflare
 
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 2014Andrzej Grzesik
 
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 GrzesikPROIDEA
 
Beyond Page Level Metrics
Beyond Page Level MetricsBeyond Page Level Metrics
Beyond Page Level MetricsPhilip Tellis
 
Go Concurrency Patterns
Go Concurrency PatternsGo Concurrency Patterns
Go Concurrency PatternsElifTech
 
Writing Docker monitoring agent with Go
Writing Docker monitoring agent with GoWriting Docker monitoring agent with Go
Writing Docker monitoring agent with GoNaoki AINOYA
 
Elegant concurrency
Elegant concurrencyElegant concurrency
Elegant concurrencyMosky Liu
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in GolangBo-Yi Wu
 
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 minutesKonrad Malawski
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of GoFrank 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 ArchitectureP. Taylor Goetz
 

Semelhante a 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
 
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
 
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
 
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
 

Mais de jgrahamc

Better living through microcontrollers
Better living through microcontrollersBetter living through microcontrollers
Better living through microcontrollersjgrahamc
 
Big O London Meetup April 2015
Big O London Meetup April 2015Big O London Meetup April 2015
Big O London Meetup April 2015jgrahamc
 
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 languagejgrahamc
 
Software Debugging for High-altitude Balloons
Software Debugging for High-altitude BalloonsSoftware Debugging for High-altitude Balloons
Software Debugging for High-altitude Balloonsjgrahamc
 
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 Woesjgrahamc
 
Javascript Security
Javascript SecurityJavascript Security
Javascript Securityjgrahamc
 

Mais de 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
 

Último

Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 

Último (20)

Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 

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!