Translate

Mostrando las entradas para la consulta go ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas
Mostrando las entradas para la consulta go ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas

domingo, 25 de febrero de 2024

Instalando go zero

 


Ya hemos hablado de zero el framework de go para hacer microservicios. Ahora vamos a bajar las herramientas para trabajar con él. 

Primero, tenemos que tener go instalado. Yo tengo la versión 1.22.0

$ go version

go version go1.22.0 linux/amd64


Después de la versión 1.11, se recomienda que el valor GO111MODULE se establezca en on para evitar errores innecesarios.

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct

$ go env GO111MODULE
on
$ go env GOPROXY
https://goproxy.cn,direct

goctl es una herramienta incorporada de go-zero que es importante para aumentar la eficiencia del desarrollo, generar código, documentos, implementar k8s yaml, dockerfile, etc.

$ go install github.com/zeromicro/go-zero/tools/goctl@latest
go: downloading github.com/gookit/color v1.5.4
go: downloading github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1
go: downloading github.com/spf13/cobra v1.8.0
...

$ goctl -version
goctl version 1.6.2 linux/amd64

Ahora tenemos que installar docker. Yo ya tengo docker instalado por lo tanto siguo: 

$ sudo docker pull kevinwan/goctl
$ sudo docker run --rm -it -v `pwd`:/app kevinwan/goctl goctl --help

Y si todo anda bien hacemos : 

$ sudo docker run --rm -it -v `pwd`:/app kevinwan/goctl:latest goctl --version
goctl version 1.3.5 linux/amd64

protoc es una herramienta para generar código basado en archivos proto, este genern código en múltiples lenguajes como C++, Java, Python, Go, PHP, etc. para nuestros servicios gRPC. Lo tenemos que instalar, en mi caso yo lo tenia instalado y lo sé porque hice : 

$ goctl env check --install --verbose --force
[goctl-env]: preparing to check env

[goctl-env]: looking up "protoc"
[goctl-env]: "protoc" is installed

[goctl-env]: looking up "protoc-gen-go"
[goctl-env]: "protoc-gen-go" is installed

[goctl-env]: looking up "protoc-gen-go-grpc"
[goctl-env]: "protoc-gen-go-grpc" is installed

[goctl-env]: congratulations! your goctl environment is ready!

Y ahora por fin, vamos a crear nuestro proyecto go-zero!! 

Creamos el proyecto: 
$ mkdir myapp && cd myapp
$ go mod init myapp
$ go get github.com/zeromicro/go-zero@latest
go: added github.com/zeromicro/go-zero v1.6.2


Y Listo!! 


miércoles, 6 de marzo de 2024

Primera API con Go-zero


Después de completar la instalación de goctl, podemos crear un servicio HTTP mínimo para obtener una descripción general del servicio API go-zero de goctl.


# Create workspaces and enter the directory

$ mkdir -p ~/workspace/api && cd ~/workspace/api

# Execute instructions generated demo service

$ goctl api new demo

Done.


Después de ejecutar la instrucción, se generará un directorio de demostración en el directorio actual que contiene un servicio HTTP minimizado, verificaremos la estructura del directorio del servicio.


$ cd ~/workspace/api/demo

$ ls

demo.api demo.go  etc      go.mod   internal

$ tree

.

├── demo.api

├── demo.go

├── etc

│   └── demo-api.yaml

├── go.mod

└── internal

    ├── config

    │   └── config.go

    ├── handler

    │   ├── demohandler.go

    │   └── routes.go

    ├── logic

    │   └── demologic.go

    ├── svc

    │   └── servicecontext.go

    └── types

        └── types.go


Después de completar la generación del código anterior, podemos encontrar los archivos ~/workspace/api/demo/internal/logic/demologic.go, y podemos completar el códigos entre las líneas 27 y 28:

resp = new(types.Response)

resp.Message = req.Name


Después de escribir el código anterior, podemos iniciar el servicio con las siguientes instrucciones:


# Enter service directory

$ cd ~/workspace/api/demo

# to organize dependencies

$ go mod tidy

# Run go program

$ go run demo.go


Cuando vea el siguiente resultado "Starting server at 0.0.0.0.0:888.." indica que el servicio se ha iniciado correctamente, entonces visitamos el servicio HTTP.


$ curl --request GET 'http://127.0.0.0.1:8888/from/me'


Cuando vea el resultado en la terminal {"message":"me"} en nombre de su servicio se inició con éxito.


Y listo!!

Dejo link: https://go-zero.dev/en/docs/tasks/cli/api-demo


miércoles, 13 de diciembre de 2023

¿Qué es Go-Zero?

 


En el mundo del desarrollo de software, la velocidad, la eficiencia y la simplicidad son pilares fundamentales. El framework Go-Zero emerge como una solución poderosa para aquellos que buscan crear aplicaciones escalables y de alto rendimiento utilizando el lenguaje de programación Go (Golang).


Pero ¿Qué es Go-Zero? Go-Zero es un framework moderno y de código abierto diseñado para acelerar el proceso de desarrollo de aplicaciones en Go. Ofrece una arquitectura robusta y flexible, proporcionando herramientas y patrones que permiten construir aplicaciones web, API y microservicios de manera eficiente.


Características Principales:

  • Alto rendimiento: Go-Zero se destaca por su capacidad para manejar cargas de trabajo intensivas y mantener un alto rendimiento incluso en entornos de gran escala.
  • Productividad mejorada: Proporciona abstracciones y utilidades que reducen la complejidad del código, permitiendo a los desarrolladores enfocarse en la lógica de negocio en lugar de detalles de implementación.
  • Facilidad de uso: Con una curva de aprendizaje amigable, su estructura modular y su amplia documentación, Go-Zero facilita a los desarrolladores tanto principiantes como experimentados.
  • Soporte para microservicios: Ofrece herramientas específicas para la construcción de arquitecturas de microservicios, simplificando la comunicación entre ellos y la gestión de datos distribuidos.
Veamos un ejemplo básico de cómo se podría crear un servidor HTTP simple utilizando el framework Go-Zero:

package main

import (
"github.com/tal-tech/go-zero/core/conf"
"github.com/tal-tech/go-zero/rest"
"github.com/tal-tech/go-zero/rest/httpx"
)

type Request struct {
Name string `form:"name"`
}

type Response struct {
Message string `json:"message"`
}

func helloHandler(w httpx.ResponseWriter, r *httpx.Request) {
var req Request
if err := r.ParseForm(&req); err != nil {
w.Error(httpx.BadRequest(err.Error()))
return
}

resp := Response{
Message: "Hello, " + req.Name + "!",
}
w.WriteJson(resp)
}

func main() {
var c rest.RestConf
conf.MustLoad("path/to/config.yaml", &c)

server := rest.MustNewServer(c)
server.AddRoute(rest.Route{
Method:  "GET",
Path:    "/hello",
Handler: helloHandler,
})
defer server.Stop()

server.Start()
}


Go-Zero representa una opción valiosa para aquellos que buscan desarrollar aplicaciones en Go de manera rápida, eficiente y escalable. Su enfoque en el rendimiento y la productividad lo convierten en una herramienta atractiva para proyectos de diversos tamaños y complejidades.

Dejo link: https://github.com/zeromicro/go-zero

martes, 9 de enero de 2024

Primer servicio GRpc con Go


Vamos a hacer un servicio que salude en Go y GRpc. Lo primero que tenemos que hacer es instalar las dependencias: 

$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

go: downloading google.golang.org/protobuf v1.28.1

$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

go: downloading google.golang.org/grpc v1.2.1


Luego escribir el .proto : 

syntax = "proto3";


option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";

option java_multiple_files = true;

option java_package = "io.grpc.examples.helloworld";

option java_outer_classname = "HelloWorldProto";


package helloworld;


// The greeting service definition.

service Greeter {

  // Sends a greeting

  rpc SayHello (HelloRequest) returns (HelloReply) {}

}


// The request message containing the user's name.

message HelloRequest {

  string name = 1;

}


// The response message containing the greetings

message HelloReply {

  string message = 1;

}

Este archivo, es un descriptor del servicio y nos permite generar código con el comando protoc, por ejemplo: 

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative ./greetings/greetings.proto


Y luego podemos escribir el cliente y el servidor. Por ejemplo: 

Server: 

package main


import (

"context"

"flag"

"fmt"

"log"

"net"


"google.golang.org/grpc"

pb "google.golang.org/grpc/examples/helloworld/helloworld"

)


var (

port = flag.Int("port", 50051, "The server port")

)


// server is used to implement helloworld.GreeterServer.

type server struct {

pb.UnimplementedGreeterServer

}


// SayHello implements helloworld.GreeterServer

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {

log.Printf("Received: %v", in.GetName())

return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil

}


func main() {

flag.Parse()

lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))

if err != nil {

log.Fatalf("failed to listen: %v", err)

}

s := grpc.NewServer()

pb.RegisterGreeterServer(s, &server{})

log.Printf("server listening at %v", lis.Addr())

if err := s.Serve(lis); err != nil {

log.Fatalf("failed to serve: %v", err)

}

}


y el cliente: 


package main


import (

"context"

"flag"

"log"

"time"


"google.golang.org/grpc"

"google.golang.org/grpc/credentials/insecure"

pb "google.golang.org/grpc/examples/helloworld/helloworld"

)


const (

defaultName = "world"

)


var (

addr = flag.String("addr", "localhost:50051", "the address to connect to")

name = flag.String("name", defaultName, "Name to greet")

)


func main() {

flag.Parse()

// Set up a connection to the server.

conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))

if err != nil {

log.Fatalf("did not connect: %v", err)

}

defer conn.Close()

c := pb.NewGreeterClient(conn)


// Contact the server and print out its response.

ctx, cancel := context.WithTimeout(context.Background(), time.Second)

defer cancel()

r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})

if err != nil {

log.Fatalf("could not greet: %v", err)

}

log.Printf("Greeting: %s", r.GetMessage())

}


Y listo!

Para probarlo, ejecutamos el server : 

$ go run greeter_server/main.go


Y luego el cliente : 

$ go run greeter_client/main.go


Dejo link: https://grpc.io/docs/languages/go/quickstart/


sábado, 7 de octubre de 2023

bbolt: Una Base de Datos Embebida para Go


Cuando se trata de almacenar y gestionar datos en una aplicación Go, una de las opciones más populares y eficientes es bbolt. bbolt es una base de datos embebida de código abierto diseñada específicamente para aplicaciones Go. 

Pero, ¿Qué es bbolt? bbolt, también conocida como "BoltDB", es una base de datos embebida escrita en Go que se centra en la simplicidad, el rendimiento y la eficiencia en la utilización de recursos. A diferencia de las bases de datos tradicionales que se ejecutan como procesos separados, bbolt se integra directamente en la aplicación Go, lo que la convierte en una excelente opción para aplicaciones que necesitan un almacenamiento local y ligero sin la necesidad de un servidor de base de datos independiente.

Características Clave de bbolt son: 

  • Transacciones ACID: bbolt garantiza la integridad de los datos mediante transacciones ACID (Atomicidad, Consistencia, Aislamiento y Durabilidad). Esto significa que las operaciones de lectura y escritura se realizan de manera segura y confiable.
  • Soporte para Índices:Puedes crear índices para acelerar las consultas de datos, lo que es especialmente útil cuando necesitas recuperar datos de manera eficiente en función de ciertos criterios.
  • Eficiencia en el Uso de la Memoria: bbolt está diseñada para utilizar la memoria de manera eficiente, lo que la hace adecuada para aplicaciones con recursos limitados.
  • Almacenamiento Duradero: Los datos almacenados en bbolt son persistentes y duraderos. Puedes confiar en que los datos sobrevivirán incluso después de reiniciar la aplicación.


Para comenzar a usar bbolt en tu proyecto Go, primero debemos agregar la dependencia:


go get go.etcd.io/bbolt@latest


Vamos a importar bbolt : 


import bolt "go.etcd.io/bbolt"


Luego, podemos abrir una base de datos o crear una nueva:


db, err := bolt.Open(path, 0600, nil)

if err != nil {

  return err

}

defer db.Close()


A partir de ahí, puedes crear buckets (similares a tablas en una base de datos relacional), almacenar y recuperar datos, y gestionar transacciones de manera similar a otras bases de datos. El enfoque es simple y eficiente, lo que facilita el trabajo con la base de datos.


// Abre una transacción de escritura.

tx, err := db.Begin(true)

if err != nil {

    log.Fatal(err)

}

defer tx.Rollback()


// Obtiene un bucket (o lo crea si no existe).

bucket, err := tx.CreateBucketIfNotExists([]byte("mi-bucket"))

if err != nil {

    log.Fatal(err)

}


// Almacena un valor en el bucket.

err = bucket.Put([]byte("clave"), []byte("valor"))

if err != nil {

    log.Fatal(err)

}


// Realiza commit de la transacción.

if err := tx.Commit(); err != nil {

    log.Fatal(err)

}


// Recupera un valor del bucket.

valor := bucket.Get([]byte("clave"))

fmt.Printf("Valor recuperado: %s\n", valor)


bbolt es una opción atractiva para aplicaciones Go que necesitan una base de datos embebida rápida, eficiente y fácil de usar. Su diseño simple, soporte para transacciones ACID y eficiencia en el uso de recursos la convierten en una elección sólida para muchas aplicaciones. Podemos considerar a bbolt para tus proyectos Go que requieran almacenamiento de datos local y duradero.


Dejo link: 

https://pkg.go.dev/go.etcd.io/bbolt

https://github.com/etcd-io/bbolt

domingo, 1 de octubre de 2023

Comentarios en Go


Go proporciona comentarios de bloque /* */ estilo C y comentarios de línea // estilo C++. Los comentarios de línea son la norma; Los comentarios de bloque aparecen principalmente como comentarios de paquete, pero son útiles dentro de una expresión o para deshabilitar grandes extensiones de código.

Se considera que los comentarios que aparecen antes de las declaraciones de nivel superior, sin nuevas líneas intermedias, documentan la declaración misma. Estos "comentarios de documentos" son la documentación principal de un paquete o comando de Go determinado. 

Los “comentarios de documentos” son comentarios que aparecen inmediatamente antes de las declaraciones de paquete, const, func, type y var de nivel superior sin nuevas líneas intermedias. Cada nombre exportado (en mayúscula) debe tener un comentario de documento.

Los paquetes go/doc y go/doc/comment brindan la capacidad de extraer documentación del código fuente de Go, y una variedad de herramientas utilizan esta funcionalidad. El comando go doc busca e imprime el comentario del documento para un paquete o símbolo determinado. (Un símbolo es una constante, función, tipo o var de nivel superior). El servidor web pkg.go.dev muestra la documentación para los paquetes públicos de Go (cuando sus licencias permiten ese uso). El programa que sirve a ese sitio es golang.org/x/pkgsite/cmd/pkgsite, que también se puede ejecutar localmente para ver la documentación de módulos privados o sin conexión a Internet. El servidor de idiomas gopls proporciona documentación al editar archivos fuente de Go en IDE.

Por ejemplo, Cada paquete debe tener un comentario que lo presente. Proporciona información relevante para el paquete en su conjunto y, en general, establece expectativas para el paquete. Especialmente en paquetes grandes, puede resultar útil que el comentario del paquete brinde una breve descripción general de las partes más importantes de la API, vinculando a otros comentarios de documentos según sea necesario.

Si el paquete es simple, el comentario del paquete puede ser breve. Por ejemplo:


// Package path implements utility routines for manipulating slash-separated

// paths.

//

// The path package should only be used for paths separated by forward

// slashes, such as the paths in URLs. This package does not deal with

// Windows paths with drive letters or backslashes; to manipulate

// operating system paths, use the [path/filepath] package.

package path


Los corchetes en [ruta/ruta de archivo] crean un enlace de documentación.

Como se puede ver en este ejemplo, los comentarios de Go doc utilizan oraciones completas. Para un comentario de paquete, eso significa que la primera oración comienza con "Package".

Dejo link: https://go.dev/doc/comment



domingo, 3 de abril de 2011

GO


...no voy a cambiar, no voy a cambiar mi modo
ellos me dicen : "nena,
nena vos lo tenes todo."
Oh, negro go...

Rara forma de empezar un post del no tan famoso lenguaje de google Go!

El pequeño párrafo de la canción de los piojos “go negro go” resume un poco mi sensación con respecto a este lenguaje, es como que tiene todo pero hecho como le gusta a google. Que no digo que este mal, pero por ahí tantas vueltas de rosca no son muy buenas a veces.

El lenguaje de programación Go es un proyecto de código abierto con el objetivo de la productividad en los programadores.

Go es expresivo, conciso, limpio y eficiente. Sus mecanismos de concurrencia hace fácil escribir programas que sacan el máximo provecho a múltiples núcleos y las máquinas en red, mientras su novedoso sistema de tipado permite la construcción de programas flexibles y modulares. Compila rápidamente a código de máquina, pero tiene la comodidad del garbage collection y el poder de reflexión en tiempo de ejecución.

Veamos un ejemplo:

package main

// fib returns a function that returns
// successive Fibonacci numbers.
func fib() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return b
}
}

func main() {
f := fib()
// Function calls are evaluated left-to-right.
println(f(), f(), f(), f(), f())
}

La salida de este programa es: 1 2 3 5 8

Se puede ver fácilmente la influencia de python y c++

Veamos un hola mundo:

package main

import fmt "fmt" // Package implementing formatted I/O.

func main() {
fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n")
}

Go es un lenguaje compilado. Para compilar este programa podemos utilizar Gccgo que utiliza GCC. También hay una serie de compiladores para diferentes arquitecturas por ejemplo: 6g para 64-bit x86, 8g para 32-bit x86, etc. Estos compiladores corren más rapido que Gccgo pero generan codigo menos eficiente. Veamos como compilar y correr go:

$ 6g helloworld.go # compile; object goes into helloworld.6
$ 6l helloworld.6 # link; output goes into 6.out
$ 6.out
Hello, world; or Καλημέρα κόσμε; or こんにちは 世界
o
$ gccgo helloworld.go
$ a.out
Hello, world; or Καλημέρα κόσμε; or こんにちは 世界


Dejo links como siempre:
http://golang.org/
http://wh3rd.net/practical-go/



miércoles, 1 de noviembre de 2023

Test en Go


Go ofrece soporte integrado para pruebas unitarias que hace que sea más fácil realizar pruebas sobre la marcha. Específicamente, utilizando las convenciones de nomenclatura, el paquete de pruebas de Go y el comando go test, puede escribir y ejecutar pruebas rápidamente.

Veamos un ejemplo, vamos a hacer un archivo greetings con el siguiente contenido : 

package greetings


import "fmt"


// Hello returns a greeting for the named person.

func Hello(name string) (message string) {

// Return a greeting that embeds the name in a message.

if name == "" {

message = "Hi!"

} else {

message = fmt.Sprintf("Hi, %v. Welcome!", name)

}

return message

}


En el directorio greetings, crearemos un archivo llamado greetings_test.go, que son las pruebas. Terminar el nombre de un archivo con _test.go le indica al comando go test que este archivo contiene test.

En Greetings_test.go, vamos a pegar el siguiente código y guardar el archivo.

package greetings


import (

"regexp"

"testing"

)


// TestHelloName calls greetings.Hello with a name, checking

// for a valid return value.

func TestHelloName(t *testing.T) {

name := "Gladys"

want := regexp.MustCompile(`\b` + name + `\b`)

msg := Hello("Gladys")

if !want.MatchString(msg) {

t.Fatalf(`Hello("Gladys") = %q, %v`, msg, want)

}

}


// TestHelloEmpty calls greetings.Hello with an empty string.

func TestHelloEmpty(t *testing.T) {

msg := Hello("")

if msg != "Hi!" {

t.Fatalf(`Hello("") = %q, want "Hi!"`, msg)

}

}


En este código, se puede ver que utilizamos el paquete "test" para hacer uso de función "Fatalf"  que indica que la función no pasa el test. 

Si ejecutamos go test en el directorio obtendremos : 

$ go test

PASS

ok      example.com/greetings   0.364s


$ go test -v

=== RUN   TestHelloName

--- PASS: TestHelloName (0.00s)

=== RUN   TestHelloEmpty

--- PASS: TestHelloEmpty (0.00s)

PASS

ok      example.com/greetings   0.372s


Y eso es todo! 

Dejo link : https://go.dev/doc/tutorial/add-a-test




lunes, 27 de febrero de 2023

Inyección de dependencia en Go usando Fx parte 2

 


Seguimos con fx, ahora vamos a hacer otro ejemplo con fx y Go basados en este ejemplo hecho con spring y java.

Primero vamos a hacer una interfaz que nos permita obtener un saludo : 

type Saludor interface {

GetSaludo() string

}

Luego vamos a implementarla en español e ingles : 


type SaludorEs struct {

}

func (saludoEs SaludorEs) GetSaludo() string {

return "Hola !!"

}


type SaludorEn struct {
}

func (saludoEn SaludorEn) GetSaludo() string {
return "Hi !!"
}

Y vamos a hacer métodos que nos permitan crear estas implementaciones : 

func CrearSaludadorEs() (Saludor, error) {
return SaludorEs{}, nil
}

func CrearSaludadorEn() (Saludor, error) {
return SaludorEn{}, nil
}

Y ahora vamos a hacer un método que sea polimorfico que imprima el saludo : 


func Saludar(saludor Saludor) {
fmt.Println(saludor.GetSaludo())
}

Como ven referencia a la interfaz por lo tanto se puede usar con el SaludadorEs y el SaludadorEn porque implementan esta interfaz. 

Y por ultimo vamos hacer 2 app de fx una en español y la otra en ingles : 


func main() {
appEs := fx.New(

fx.Provide(
CrearSaludadorEs,
),

fx.Invoke(Saludar),
)

ctxEs, cancelEs := context.WithCancel(context.Background())
defer cancelEs()
if err := appEs.Start(ctxEs); err != nil {
log.Fatal(err)
}

appEn := fx.New(

fx.Provide(
CrearSaludadorEn,
),

fx.Invoke(Saludar),
)

ctxEn, cancelEn := context.WithCancel(context.Background())
defer cancelEn()
if err := appEn.Start(ctxEn); err != nil {
log.Fatal(err)
}
}

y la salida es la siguiente : 

[Fx] PROVIDE    main.Saludor <= main.CrearSaludadorEs()
[Fx] PROVIDE    fx.Lifecycle <= go.uber.org/fx.New.func1()
[Fx] PROVIDE    fx.Shutdowner <= go.uber.org/fx.(*App).shutdowner-fm()
[Fx] PROVIDE    fx.DotGraph <= go.uber.org/fx.(*App).dotGraph-fm()
[Fx] INVOKE             main.Saludar()
Hola !!
[Fx] RUNNING
[Fx] PROVIDE    main.Saludor <= main.CrearSaludadorEn()
[Fx] PROVIDE    fx.Lifecycle <= go.uber.org/fx.New.func1()
[Fx] PROVIDE    fx.Shutdowner <= go.uber.org/fx.(*App).shutdowner-fm()
[Fx] PROVIDE    fx.DotGraph <= go.uber.org/fx.(*App).dotGraph-fm()
[Fx] INVOKE             main.Saludar()
Hi !!
[Fx] RUNNING

Y listo!!



martes, 22 de octubre de 2019

Aprender Go en codecademy

En 2009, Google se propuso crear un lenguaje de programación que fuera rápido, productivo y divertido de usar. Y lo más importante, no querían hacer compensaciones entre legibilidad, eficiencia o rendimiento.

10 años después, Go esta estable y lo usan compañías como Netflix, Uber, Codecademy y, por supuesto, Google.

Hoy, nos complace anunciar que nos hemos asociado con Google para crear el mejor curso Go para principiantes más amigable en cualquier lugar. Aprenderá la sintaxis, recibirá preguntas sobre cómo declarar funciones y creará proyectos.

Los primeros cuatro módulos de "Learn Go" están en vivo en nuestro catálogo en este momento.

Este es el mail (la traducción) que me llego de los amigos de Codecademy, con el cual nos invitan a hacer un curso gratuito de Go.

Dejo el link: https://www.codecademy.com/learn/learn-go

Dejo el mail :

 
 
Codeacdemy Presents Learn Go in Partnership with Google
Learn Go
 
 
 
 
In 2009, Google set out to create a programming language that was fast, productive, and fun to use. And most importantly, they didn’t want to make any tradeoffs between readability, efficiency, or performance.
 
10 years later, Go is trusted by developers at companies like Netflix, Uber, Codecademy, and, of course, Google.
 
Today, we’re excited to announce that we’ve partnered with Google to build the best, most beginner-friendly Go course anywhere. You’ll learn the syntax, get quizzed on how to declare functions, and build projects like a flight coordinator for an interstellar travel agency.
 
The first four modules of “Learn Go” are live in our catalog right now.
 
Start Now
 

lunes, 27 de febrero de 2023

Inyección de dependencia en Go usando Fx


Vamos por parte, que es la inyección de dependencias?

Cualquier aplicación no trivial está formada por dos o más objetos que colaboran entre sí para realizar alguna lógica. Tradicionalmente cada objeto se hacía cargo de obtener sus propias referencias a los objetos a los cuales colaboraba (sus dependencias). Esto lleva a código acoplado y difícil de probar. Y para solucionar esto esta la inyección de dependencias. El contexto ingresa las dependencias de un objeto. Para mayor información pueden ir a : https://emanuelpeg.blogspot.com/2009/07/inyeccion-de-dependencias.html


Y que es Fx? Según la documentación oficial publicada por Uber, Fx es un framework para Go que:

  • Facilita la inyección de dependencia.
  • Elimina la necesidad de estado global y func init().

Fx usa el patrón de inyección de constructor, tratemos de entender exactamente cómo hace que la inyección de dependencia sea fácil en Go.

Para usar Fx debemos: 

El primer paso es instalar la biblioteca a través de go get go.uber.org/fx.

Y luego podemos hacer esto: 

package main


import (

"context"

"go.uber.org/fx"

"go.uber.org/fx/fxevent"

"log"

"net"

"net/http"

"os"

"time"

)


func NewLogger() *log.Logger {

logger := log.New(os.Stdout, "" /* prefix */, 0 /* flags */)

logger.Print("Create NewLogger.")

return logger

}


func NewHandler(logger *log.Logger) (http.Handler, error) {

logger.Print("Create NewHandler.")

return http.HandlerFunc(func(http.ResponseWriter, *http.Request) {

logger.Print("Got a request.")

}), nil

}


func NewMux(lc fx.Lifecycle, logger *log.Logger) *http.ServeMux {

logger.Print("Create NewMux.")

mux := http.NewServeMux()

server := &http.Server{

Addr:    "127.0.0.1:8080",

Handler: mux,

}

lc.Append(fx.Hook{

OnStart: func(context.Context) error {

logger.Print("Starting HTTP server.")

ln, err := net.Listen("tcp", server.Addr)

if err != nil {

return err

}

go server.Serve(ln)

return nil

},

OnStop: func(ctx context.Context) error {

logger.Print("Stopping HTTP server.")

return server.Shutdown(ctx)

},

})


return mux

}


func Register(mux *http.ServeMux, h http.Handler) {

mux.Handle("/", h)

}


func main() {

app := fx.New(


fx.Provide(

NewLogger,

NewHandler,

NewMux,

),


fx.Invoke(Register),


fx.WithLogger(

func() fxevent.Logger {

return fxevent.NopLogger

},

),

)


startCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second)

defer cancel()

if err := app.Start(startCtx); err != nil {

log.Fatal(err)

}


if _, err := http.Get("http://localhost:8080/"); err != nil {

log.Fatal(err)

}


stopCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second)

defer cancel()

if err := app.Stop(stopCtx); err != nil {

log.Fatal(err)

}


}


En el ejemplo queremos costruir varias entidades, un *log.Logger,  un http.Handler, un servidor *http.ServeMux y queremos llamar a una request. Y fx, nos construye estos objetos. 

Si ejecutamos esta aplicación el resultado será : 

Create NewLogger.
Create NewMux.
Create NewHandler.
Starting HTTP server.
Got a request.
Stopping HTTP server.


Dejo link: 


domingo, 5 de julio de 2020

¿Por qué las goroutines no son threads?


En el post anterior dije que las Fibras de java son como las goroutines y me quede pensando en esto, y como no sé bien porque es esto... me puse a investigar. 

Go está ganando una popularidad increíble. Una de las razones principales es la concurrencia simple y liviana en forma de goroutines y chanels que ofrece.

Pero porque las gorutines son livianas, simple porque no son threads. A ver, a ver, vamos por parte, porque un thread es pesado o mejor qué es un thread? 

La concurrencia ha existido desde hace mucho tiempo en forma de hilos o threads que se utilizan en casi todas las aplicaciones en estos días.  Un hilo es solo una secuencia de instrucciones que un procesador puede ejecutar independientemente. Los threads son más ligeros que el proceso, por lo que puede generar muchos de ellos.

Un servidor web generalmente está diseñado para manejar múltiples solicitudes al mismo tiempo. Y estas solicitudes normalmente no dependen unas de otras.

Por lo tanto, se puede crear un thread (o un pool de threads) y se pueden delegar cada request a un thread para lograr la concurrencia.

Los procesadores modernos pueden ejecutar varios threads a la vez (multi-threading) y también alternar entre threads para lograr paralelismo. 

Los threads pueden verse como algo liviano, dado que: 

  • Los threads comparten memoria y no necesitan crear un nuevo espacio de memoria virtual cuando se crean y, por lo tanto, no requieren un cambio de contexto MMU (unidad de administración de memoria)
  • La comunicación entre threads es más simple ya que tienen una memoria compartida, mientras que los procesos requieren varios modos de IPC (comunicaciones entre procesos) como semáforos, colas de mensajes, tuberías, etc.
Esto no siempre garantiza un mejor rendimiento que los procesos en este mundo de procesadores multinúcleo. p.ej. Linux no distingue entre hilos y procesos y ambos se denominan tareas. Cada tarea puede tener un nivel mínimo a máximo de uso compartido cuando se clona. 

Hay tres cosas que hacen que los hilos sean lentos:
  • Los hilos consumen mucha memoria debido a su gran tamaño de pila (≥ 1 MB). Por lo tanto, crear miles de hilos significa que ya necesita 1 GB de memoria.
  • Los hilos necesitan restaurar muchos registros, algunos de los cuales incluyen AVX (extensión de vector avanzada), SSE (extensión SIMD de transmisión), registros de punto flotante, contador de programa (PC), puntero de pila (SP) que perjudica el rendimiento de la aplicación.
  • La configuración de los subprocesos y el desmontaje requieren una llamada al sistema operativo para obtener recursos (como la memoria) que es lento.
Goroutines existe solo en el espacio virtual del runtime de go y no en el sistema operativo. Por lo tanto, se necesita un planificador Go Runtime que gestione su ciclo de vida. Go Runtime mantiene tres estructuras C para este propósito:
  • La estructura G: representa una rutina única con sus propiedades, como el puntero de la pila, la base de la pila, su ID, su caché y su estado.
  • La estructura M: Esto representa un hilo del sistema operativo. También contiene un puntero a la cola global de goroutines ejecutables, la goroutine actual en ejecución y la referencia al planificador
  • La estructura programada: es una estructura global y contiene las colas libres y esperando gorutinas, así como subprocesos.
Entonces, en el inicio, go runtime inicia varias rutinas para GC, planificador y código de usuario. Se crea un subproceso OS para manejar estas gorutinas. Estos hilos pueden ser como máximo iguales a GOMAXPROCS.
 
Se crea una rutina con solo 2 KB iniciales de tamaño de pila. Cada función en go ya tiene una comprobación si se necesita más pila o no y la pila se puede copiar a otra región en la memoria con el doble del tamaño original. Esto hace que la gorutina sea muy liviana en recursos.

Si una rutina se bloquea en una llamada al sistema, bloquea su hilo en ejecución. Pero otro hilo se toma de la cola de espera de Scheduler (la estructura Sched) y se usa para otras goroutines ejecutables. Sin embargo, si te comunicas usando canales in go que solo existen en el espacio virtual, el sistema operativo no bloquea el hilo. Tales goroutinas simplemente van en estado de espera y otras goroutinas ejecutables (de la estructura M) están programadas en su lugar.

Runtime de go hace una programación cooperativa, lo que significa que otra rutina solo se programará si la actual está bloqueando o terminada. Algunos de estos casos son:
  • Operaciones de envío y recepción de canales, si esas operaciones se bloquean.
  • La declaración de Go, aunque no hay garantía de que la nueva rutina se programará de inmediato.
  • Bloqueo de llamadas al sistema como operaciones de archivos y redes.
  • Después de ser detenido por un ciclo de recolección de basura.

Más allá de un montón de tecnicismos un conjunto de go rutines puede vivir en un o varios hilos y todo esta manejado por el runtime de go que los administra. 

lunes, 24 de mayo de 2021

Go in Action Gratis hasta el 30 de Mayo!!

Manning nos regala Go in Action hasta el 30 de mayo, miren: 

Don't miss out! Offer ends May 30, 2021. 
Only available to new email subscribers.
Kennedy-GO-HI
$35.99 FREE!
Get your free eBook!
Go in Action introduces the Go language, 
guiding you from inquisitive 
developer to Go guru. The book begins 
by introducing the unique features 
and concepts of Go. Then, 
you’ll get hands-on experience 
writing real-world applications 
including websites and network servers.

Dejo link: 

https://freecontent.manning.com/free-ebook-go-in-action/?utm_source=facebook&utm_medium=organic&utm_campaign=newslettersignup_go_5_24_21

lunes, 2 de octubre de 2023

Crear un proyecto en Go y Echo


Vamos a crear un proyecto con echo y go. Echo es un framework web minimalista y de alto rendimiento para Go. Está diseñado para ser simple y eficiente, lo que lo hace adecuado para el desarrollo rápido de API REST. Echo es especialmente apreciado por su rendimiento y facilidad de uso.


$ mkdir myapp && cd myapp

$ go mod init myapp

$ go get github.com/labstack/echo/v4

$ go get github.com/labstack/echo/v4/middleware


Con esto, hemos importado las librerías necesarias si miramos el archivo go.mod : 


module myapp 


go 1.19


require (

github.com/golang-jwt/jwt v3.2.2+incompatible // indirect

github.com/labstack/echo/v4 v4.11.1 // indirect

github.com/labstack/gommon v0.4.0 // indirect

github.com/mattn/go-colorable v0.1.13 // indirect

github.com/mattn/go-isatty v0.0.19 // indirect

github.com/valyala/bytebufferpool v1.0.0 // indirect

github.com/valyala/fasttemplate v1.2.2 // indirect

golang.org/x/crypto v0.11.0 // indirect

golang.org/x/net v0.12.0 // indirect

golang.org/x/sys v0.10.0 // indirect

golang.org/x/text v0.11.0 // indirect

golang.org/x/time v0.3.0 // indirect

)


Ahora vamos a hacer un pequeño programa que tenga un hola mundo : 


import (

  "github.com/labstack/echo/v4"

  "github.com/labstack/echo/v4/middleware"

  "net/http"

)


func main() {

  // Echo instance

  e := echo.New()


  // Middleware

  e.Use(middleware.Logger())

  e.Use(middleware.Recover())


  // Routes

  e.GET("/", hello)


  // Start server

  e.Logger.Fatal(e.Start(":1323"))

}


// Handler

func hello(c echo.Context) error {

  return c.String(http.StatusOK, "Hola Mundo!")

}


Y Listo!!


Dejo links: 

https://echo.labstack.com/docs

https://github.com/labstack/echo

miércoles, 2 de octubre de 2019

Anonymous fields en Go


Continuamos con en go

Como podemos aplicar composiciones a un lenguaje no orientado a objeto y que no se vea forzado? Y la respuesta la tiene Go con Anonymous fields. En Go solo tenemos estructuras y funciones que trabajan con dichas estructuras. Si bien Go tiene una forma de escribir estas estructuras y su interacción con las funciones que hace imaginar a objetos, esto no es así. 

Pero Go utiliza composiciones, como lo hace? componiendo estructuras:  Go permite definir una estructura que tiene campos pero sin nombres de variables. Estos campos se llaman campos anónimos. Hagamos algunos ejemplos para descubrir cuáles son y cómo serán útiles.

En el siguiente ejemplo, hemos definido una estructura de Cocina, que solo contiene el número de platos como un campo. Definimos otro campo llamado House, que contiene una instancia de Kitchen como campo, pero es un campo anónimo, porque no le hemos dado un nombre de variable.

Los campos anónimos en las estructuras Go nos permiten atajar la notación de puntos, así como también nos permiten usar composiciones para agregar métodos a un tipo. Veamos un ejemplo : 

type A struct {
    X int
    Y int
}
 
type B struct {
    Z int
}
 
type C struct {
    AValue A
    BValue B
}

La estructura C contiene a la estructura A, por lo tanto la estructura C esta compuesta. Y podemos llamar a campos de C por medio de los campos descriptos en A o B : 

 c := C {}
c.AValue.X = 1

Podemos pasar a C de modo anónimo por lo tanto queda así : 

type C struct {
    A
    B
}

nos permite reducir el uso de la notación de puntos y acceder a X en A como si fuera un campo dentro de la estructura C en sí, es decir

c := C {}
c.X = 1

De acuerdo, pero ¿qué pasaría si B struct ahora reemplazara el nombre del campo Z con X?

type A struct {
    X int
    Y int
}
 
type B struct {
    X int
}

Ahora tenemos una situación en la que tanto A como B tienen el mismo nombre de campo, bueno, aún podemos usar campos anónimos, pero volvemos a usar más notación de puntos nuevamente para evitar el conflicto obvio de nombre de campo, es decir:

c := C {}
c.A.X = 1
c.B.X = 2

Los inicializadores no admiten accesos directos, es decir : 

c := C{ A : A{2, 4}, B : B { 12 }}
// or
c := C{ A : A{X : 2, Y : 4}, B : B { Z: 12 }}
 
Más poderoso que el azúcar sináptico de los campos anónimos, es que también podemos usar la composición para aumentar los métodos disponibles en la estructura C. Por ejemplo, ahora agreguemos un método al tipo A que nos permite mover nuestro punto X, Y

func (a *A) Move(amount int) {
    a.X += amount
    a.Y += amount
}

Ahora podemos llamar al método con C :

c.Move(10)

También podemos crear más métodos a través de un patrón de composición en el tipo C si queremos usar tipos vacíos, supongamos que tenemos el tipo D y amplia la composición del tipo C, bueno podemos : 

type D struct {}
 
type C struct {
    A
    B
    D
}

ahora podemos agregar métodos a D y, por supuesto, estarán disponibles como parte de C. Entonces, por ejemplo, tal vez D actúa como un receptor para los métodos que serializan datos a JSON, ahora nuestro tipo C también parecerá tener esos métodos.



martes, 3 de enero de 2023

Echo, Framework web de alto rendimiento, extensible y minimalista para Golang


Echo, es un framework web para golang que nos brinda : 

  • Enrutador HTTP altamente optimizado con asignación de memoria dinámica cero que prioriza rutas de manera inteligente.
  • Creación de un API RESTful robusta y escalable, fácilmente organizada en grupos.
  • Se puede instalar automáticamente certificados TLS de Let's Encrypt.
  • La compatibilidad con HTTP/2 mejora la velocidad y proporciona una mejor experiencia de usuario.
  • Muchos middleware integrados para usar o definir el suyo propio. El middleware se puede configurar a nivel de raíz, grupo o ruta.
  • Enlace de datos para la carga útil de la solicitud HTTP, incluidos JSON, XML o datos de formulario.
  • API para enviar una variedad de respuestas HTTP, incluidos JSON, XML, HTML, archivo, adjunto, en línea, flujo o blob.
  • Representación de plantillas utilizando cualquier motor de plantillas
  • Manejo de errores HTTP central personalizado. API fácilmente extensible.


Muy lindo todo pero la idea es hacer un hola mundo, veamos. 


Para instalar se requiere Echo Go v1.13 o superior. Go v1.12 tiene soporte limitado y algunos middlewares no estarán disponibles. Asegúrese de que la carpeta de su proyecto esté fuera de su $GOPATH.


$ mkdir myapp && cd myapp

$ go mod init myapp

$ go get github.com/labstack/echo/v4


Si está trabajando con Go v1.14 o anterior, use:


$ GO111MODULE=on go get github.com/labstack/echo/v4

Veamos exponer un servicio enel golang : 

package main

import (
"net/http"
"github.com/labstack/echo/v4"
)

func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}

Y lo corremos de esta manera : 

$ go run server.go

Dejo link: https://echo.labstack.com/

sábado, 28 de enero de 2017

Que lenguaje de programación fue el que más popular en el 2016?

Según el índice TIOPE : Go!

Si el lenguaje de google sigue creciendo y se lleva la distinción del lenguaje más popular.

La pagina de tiope dice lo siguiente (más o menos) :

TIOBE recompensa el lenguaje de programación que ha ganado la mayor popularidad en un año con el premio de lenguaje de programación del año. Sin prácticamente ninguna competencia Go ha ganado el premio para el año 2016. El lenguaje google Go ganó con un  2,16% en un año. Seguido de Dart (+ 0.95%) y Perl (+ 0.91%). Los principales impulsores del éxito de Go son su facilidad de aprendizaje y naturaleza pragmática. No se trata de conceptos teóricos como la herencia virtual y las mónadas, sino la experiencia práctica. Aparte de eso, Go incorpora soporte para la programación en paralelo. por lo que cada vez más clientes de nuestra empresa TIOBE están adoptando Go en un entorno industrial. Es un buen indicador.

Personalmente opino que no es bueno que un lenguaje triunfe solo por pragmático, claramente en los conceptos podemos desarrollarnos. Pero solo una opinion personal.

Bueno que más decir, felicitaciones Go!

Dejo link: http://www.tiobe.com/tiobe-index/?imm_mid=0ec6d0&cmp=em-prog-na-na-newsltr_20170121

jueves, 29 de septiembre de 2016

Codeschool nos trae un nuevo curso sobre Go!

Codeschool nos trae un nuevo curso, ahora sobre Go! 

Code School
 
On Track With Golang
Learn what makes Go a great fit for concurrent programs and how you can use it to leverage the power of modern computer architectures.
View Course
What You'll Learn
Level 1
 
Level 1: 3,2,1... Go!
Begin learning how to build and run Go programs.               
Level 2
 
Level 2: Underneath the Tracks
Explore variables and type inference, learn about data types, write functions, and work with errors.
Level 3
 
Level 3: Following the Trail
Learn how to write loops, work with collection types like arrays and slices, and loop with range.
Level 4
 
Level 4: Adding Structure to the Data
Discover how to use struct types to encapsulate code, and learn the difference between values and pointers.
Level 5
 
Level 5: Gophers & Friends
Work with interface types, create project packages, and write concurrent code with goroutines.
Why Go?
Course Instructor Carlos Souza explains the three main Go features that make it a great language to learn.
TwitterTweet This
 
Twitter IconFacebook IconYoutube IconGoogle+ Icon