No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Implementaci贸n de Goroutines y channels

26/42
Recursos

Aportes 20

Preguntas 3

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Reg铆strate o inicia sesi贸n para participar.

Si se incluye 鈥渇mt.Println(<- chanel)鈥 en el mismo ciclo for del 鈥済o鈥 no se obtiene el mismo rendimiento.

for _, server := range servers {
	go checkServer(server, chanel)
	fmt.Println(<- chanel)
}

Me pueden ayudar para saber porque me sale el error to many arguments in call to checkStatusServer
have (string, chan string)
want (string)

El codigo con el ejercicio funcion贸 de maravilla pero me qued贸 la duda de porque a m铆 si me sali贸 est谩 advertencia y al tutor no.

package main

import (
	"fmt"
	"net/http"
	"time"
)

func main() {
	startWatch := time.Now()
	channel1 := make(chan string)
	servers := []string{
		"http://platzi.com",
		"http://google.com",
		"http://facebook.com",
		"http://instagram.com",
	}

	for _, server := range servers {
		go checkStatusServer(server, channel1)

	}

	for index, _ := range servers {
		fmt.Println(<-channel1, index+1)
	}

	timeExec := time.Since(startWatch)

	fmt.Printf("Execution time: %s", timeExec)
}

func checkStatusServer(server string, channel chan string) {
	_, err := http.Get(server)
	if err != nil {
		//fmt.Println(server, "Is not Available =(")
		channel <- server + " Is not Available =("
	} else {
		//fmt.Println(server, "It's working OK")
		channel <- server + " It's working OK"
	}
}

No se si estoy mal, pero sin las rutinas el proceso tomo 2.086 segundos, y usando rutinas tomo 2.736 segundos, entonces no veo la mejora al usar las Goroutines o no se implementarion bien, porque aunque los servidores no siempre responden en un tiempo fijo la idea idea era mejorar los tiempos y 0.7seg es bastante para los llamados

La palabra clave go lo que hace es crear un nuevo proceso o hilo que se ejecuta independiente de main.

Main al mandar a ejecutar goroutines, aunque no hayan acabado, termina la ejecuci贸n de su c贸digo. Channels es el mecanismo de comunicaci贸n entre las mismas goroutines y tambi茅n el proceso main.

// definici贸n de un channel.
c := make(chan string)

// sintaxis para transmitir informaci贸n al channel
c <- "sending data"

// sintaxis para recibir informaci贸n del channel
received := <-c

Los channels alojan un tipo espec铆fico de dato que se debe definir expl铆citamente.

Si 煤nicamente pusi茅ramos una vez la recepci贸n de informaci贸n de un channel, main continuar铆a con su ejecuci贸n, porque no especificamos que ten铆a que esperar m谩s informaci贸n. Para recibir la informaci贸n de m煤ltiples goroutines, tenemos que definir las veces que nuestro channel debe esperar informaci贸n.

Por otro lado, si no recibiera informaci贸n se quedar铆a bloqueado, porque utilizamos un channel de tipo unbuffered, un tipo de channel que no definimos su capacidad o tama帽o de manera expl铆cita, que se quedar铆a esperando a recibir un informaci贸n.

Se nota la diferencia 馃槂

Quer铆a aclarar algunas cosas

  1. La primera vez que ejecuta el programa, no aparecen los mensajes, porque primero se acaba de ejecutar el main, que las subrutinas, esto se podr铆a solucionar con un sleep que es muy mala practica, un waitgroup que espera que se ejecuten todas las gorutinas https://gobyexample.com/waitgroups o con canales

  2. Como esta tarea no requiere compartir las respuestas entre las go rutinas waitgroup es una muy buena opci贸n

  3. Quisiera aclarar que la go rutina no va a esperar hasta que acabe la primera para continuar. Tratar茅 de explicarlo

Si tenemos dos gorutinas , que tiene que ejecutar una funci贸n

 --  Go rutina 1 
 --  Go rutina 2

func Sumar(num1, num2 int){
	imprime un mensaje
	hace la suma 
	la envia por el canal 
	c <- resultado
}

el proceso ser铆a asi:

Ambas gorutinas empiezan, imprimen, suman, pero al momento de enviar por el canal la primera envia porque nadie ha usado el canal, pero la segunda se queda en pausa, esperando que la primera envie la informaci贸n, cuando ya el mensaje haya sido recibido por alguien, ahi si la segunda envie su mensaje
  1. Se puede hacer el for de la siguiente manera
 for elem := range queue {
        fmt.Println(elem)
    } 
package main

import (
	"fmt"
	"net/http"
	"time"
)

func main() {
	inicio := time.Now()

	ch := make(chan string)
	servidores := []string{
		"h t t p   : / / p  l a tz i . c o m",
		"h t t p : // g o o g le . c o m ",
		"h t t p : / / f ac e b o o k . c o m ",
		"h t t p : / / I n s t a g ra m .   co  m",
	}

	for _, servidor := range servidores {
		go revisarServidor(servidor, ch)
	}

	for i := 0; i < len(servidores); i++ {
		fmt.Println(<-ch)
	}

	tiempoPasado := time.Since(inicio)
	fmt.Printf("Done in %s", tiempoPasado)
}

func revisarServidor(servidor string, ch chan string) {
	_, err := http.Get(servidor)

	if err != nil {
		ch <- servidor + "no esta disponible"
	} else {
		ch <- servidor + "esta funcionando"
	}

}

package main

import (
	"fmt"
	"net/http"
	"time"
)

func main() {
	channel := make(chan string, 4)
	links := []string{
		"https://www.digitalocean.com",
		"https://jsonplaceholder.typicode.com",
		"https://platzi.com/",
		"https://github.com/",
	}
	start := time.Now()
	go func() {
		for _, url := range links {
			if 	_, err := http.Get(url); err != nil {
				fmt.Println("El servidor esta fuera!")
			} else {
				channel <- fmt.Sprintf("%s --> Ok", url)
			}
		}
		defer close(channel)
	}()

	for msg := range channel {
		fmt.Println(msg)
	}
	end := time.Since(start)
	fmt.Println(end)
}

la combinaci贸n Goroutines y channels hacen de Go un lenguaje muy poderoso.

Que poder tan abismal tiene Go routines y que sencillo fue implementarlo.
seg煤n entiendo Go administra los hilos para no tener que abrir tantos hilos como en otros lenguajes.
Esta es una ventaja total de go contra el resto.

Los channel nos dice que paso con la ejecucion de las gorutines

con la palabra reservada **chan string ** no dice que estamos declarando un canal con su tipo de datos

canal es el channel y con la flecha <- lo que esta a la derecha de la flecha sera el contenido de lo que se esta transmitiendo

Con gorutines utilizamos programacion concurrente, para que se secuencial.

De esta manera imprimira solo el nombre del servidor por ejemplo, 鈥減latzi鈥, y no toda la URL 鈥http://platzi.com

<code>servers := []string{
		"platzi",
		"youtube",
		"google",
		"instagram",
		"facebook",
		"twitter",
	}

	for _, server := range servers {
		go checkStatus("http://"+server+".com", channel)
	}

	for i := 0; i < len(servers); i++ {
		avaible := <-channel

		fmt.Println(avaible)
	}

	finishProcessTime := time.Since(startProcessTime)

	fmt.Printf("estimated time to get result: ")
	fmt.Println(finishProcessTime)

}

func checkStatus(server string, channel chan string) {
	_, err := http.Get(server)
	svWithExtension := strings.Split(server, "//")
	svName := strings.Split(svWithExtension[1], ".")
	sv := svName[0]
	if err != nil {
		channel <- sv + " status: NO AVAIBLE"
	}
	channel <- sv + " status: AVAIBLE"

Obtienes el mismo resultado al escribir el Println dentro del for con la concurrencia:

//recorrer slice
	for _, servidor := range servidores{
		go revisarServidor(servidor, canal)
		//leer un canal
		fmt.Println(<-canal)
	}```

con esto reduces las lineas de codigo 

Me pas贸 que las rutinas morian antes de terminar de ejecutarse .-. pens茅 que habia hecho algo mal xd

quer铆a resaltar que el asincronismo y la concurrencia no son lo mismo.

soy el unico que nota que los canales aumentan levemente el tiempo de ejecucion ?

Para crear un canal con varios valores como un objeto puedes crear un struct

//MessageStruct Struct for message
type MessageStruct struct {
	message    string
	status    bool
	err error
}

c := make(chan MessageStruct)

Esto creara un canal como un objeto con un message, status y err.