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

Concorrência em GO

Duke
July 29, 2014

Concorrência em GO

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)