Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Concorrência em GO

Avatar for Duke Duke
July 29, 2014

Concorrência em GO

Avatar for Duke

Duke

July 29, 2014
Tweet

More Decks by Duke

Other Decks in Programming

Transcript

  1. Goroutines Uma goroutine é uma função que é capaz de

    executar de forma concorrente com outras funções. func ola(name string) { fmt.Println("Buscando", name) time.Sleep(2 * time.Second) fmt.Println("Olá", name) } func main() { ola("João") ola("Pedro") time.Sleep(4 * time.Second) } Run
  2. Channels Channels prover uma forma das goroutines se comunicarem umas

    com as outras e sincronizar sua execução func ola(name string, start chan bool) { <-start fmt.Println("Buscando", name) time.Sleep(2 * time.Second) fmt.Println("Olá", name) } func main() { start := make(chan bool) go ola("João", start) go ola("Pedro", start) fmt.Println("Iniciando Saudações") start <- true start <- true time.Sleep(4 * time.Second) }
  3. bidirecional/unidirecional Um channel é uma conexão bidirecional ou unidirecional entre

    duas goroutines www.confreaks.com/videos/3422-gophercon2014-a-channel-compendium (http://www.confreaks.com/videos/3422- gophercon2014-a-channel-compendium) func from(connection chan int) { connection <- rand.Intn(100) } func to(connection chan int) { i := <-connection fmt.Printf("Someone sent me %d\n", i) } func main() { connection := make(chan int) go from(connection) go to(connection) time.Sleep(2 * time.Second) } Run
  4. for...range loop Um channel pode ser usado sobre um for...range

    loop pivotallabs.com/channels-in-go-beyond-the-basics/ (http://pivotallabs.com/channels-in-go-beyond-the-basics/) func process(tasks []string) <-chan string { ch := make(chan string) go func() { for index, task := range tasks { ch <- fmt.Sprintf("processed task %d: %s", index, task) } close(ch) }() return ch } func main() { results := process([]string{"foo", "bar", "baz"}) for result := range results { fmt.Println(result) } } Run
  5. select O select permite enviar e receber informação de multiplos

    canais ao mesmo tempo select { case x := <-meuchannel: // faz algo com x case y, ok := <-outrochannel: // faz algo com y // ok verifica se o channel está fechado case <-z: // faz algo quando z for enviado default: // nenhum dos anteriores for selecionados }
  6. For/Select for { select { case x := <-meuchannel: //

    faz algo com x case y, ok := <-outrochannel: // faz algo com y // ok verifica se o channel está fechado case <-z: // faz algo quando z for enviado default: // nenhum dos anteriores for selecionados } }
  7. For/Select gobyexample.com/select (https://gobyexample.com/select) func main() { c1 := make(chan string)

    c2 := make(chan string) go func() { time.Sleep(time.Second * 1) c1 <- "one" }() go func() { time.Sleep(time.Second * 2) c2 <- "two" }() for i := 0; i < 2; i++ { select { case msg1 := <-c1: fmt.Println("received", msg1) case msg2 := <-c2: fmt.Println("received", msg2) } } } Run
  8. http handler m.Get("/api/imoveis/:state/:city/:neighborhood", func(res http.ResponseWriter, req *http.Request, params martini.Params) {

    res.Header().Set("Content-Type", "text/event-stream") item, timeout := crawlers.Get(params["state"], params["city"], params["neighborhood"]) for { select { case property, ok := <-item: if !ok { item = nil } b, _ := json.Marshal(property) b = append(b, []byte("\n")...) res.Write(b) res.(http.Flusher).Flush() case <-timeout: item = nil return } } })
  9. Bot Manager func Get(state, city, neighborhood string) (chan *Property, <-chan

    time.Time) { item, timeout := make(chan *Property), time.After(time.Second*20) go func() { for i := 0; i < len(bots); i++ { pages := bots[i].FirstRun(item, state, city, neighborhood) if pages > 1 { for page := 2; page <= pages; page++ { go bots[i].Get(item, page, state, city, neighborhood) } } } }() return item, timeout }
  10. Bot func (i *ImovelWebBot) parserPage(channel chan *Property, url string) *goquery.Document

    { // ... doc.Find("ul[itemtype='http://www.schema.org/RealEstateAgent'] > li").Each(func(_ int, s *goquery.Selection) { pType := i.getType(s.Find(".busca-item-heading2").Text()) if pType > 0 { var property Property property.Title = s.Find(".busca-item-heading1").Text() property.Address = s.Find(".busca-item-endereco").Text() // ... channel <- &property } }) return doc }
  11. Links gobyexample.com/channels (https://gobyexample.com/channels) www.golang-book.com/10/index.htm (http://www.golang-book.com/10/index.htm) pivotallabs.com/a-beginning-look-at-concurrency-in-go/ (http://pivotallabs.com/a-beginning-look-at-concurrency-in-go/) pivotallabs.com/channels-in-go-beyond-the-basics/ (http://pivotallabs.com/channels-in-go-beyond-the-basics/) blog.golang.org/concurrency-is-not-parallelism

    (http://blog.golang.org/concurrency-is-not-parallelism) www.confreaks.com/videos/3422-gophercon2014-a-channel-compendium (http://www.confreaks.com/videos/3422-gophercon2014- a-channel-compendium) blog.golang.org/go-concurrency-patterns-timing-out-and (http://blog.golang.org/go-concurrency-patterns-timing-out-and) blog.golang.org/pipelines (http://blog.golang.org/pipelines) talks.golang.org/2012/concurrency.slide (http://talks.golang.org/2012/concurrency.slide)