package main
import (
"fmt"
"reflect"
)
var funcMap = map[string]interface{}{
"Hello": Hello,
}
func Hello(name string) {
fmt.Printf("Hello, %s!\n", name)
}
func main() {
nameFunc := "Hello"
if fn, ok := funcMap[nameFunc]; ok {
funcValue := reflect.ValueOf(fn)
args := []reflect.Value{reflect.ValueOf("Gopher")}
funcValue.Call(args)
} else {
fmt.Println("Function not found!")
}
}
vscode Fix 100% CPU
https://www.youtube.com/watch?v=36Hm1DEl82M
hexagonal architecture
gracefully shutdown HTTP server
// listen to OS signals and gracefully shutdown HTTP server
stopped := make(chan struct{})
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
<-sigint
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Printf("HTTP Server Shutdown Error: %v", err)
}
close(stopped)
}()
log.Printf("Starting HTTP server on %s", cfg.HTTPAddr)
// start HTTP server
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatalf("HTTP server ListenAndServe Error: %v", err)
}
<-stopped
Introducing basic CQRS by refactoring a Go project
https://threedots.tech/post/basic-cqrs-in-go/
Isn’t CQRS a complex technique?
Isn’t CQRS one of these C#/Java/über enterprise patterns that are hard to implement, and make a big mess in the code? A lot of books, presentations, and articles describe CQRS as a very complicated pattern. But it is not the case.
Conventional Commits
https://www.conventionalcommits.org/en/v1.0.0/#summary
The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of. This convention dovetails with SemVer, by describing the features, fixes, and breaking changes made in commit messages
gping google.com yandex.ru
ping
brew install gping
https://github.com/orf/gping
шпаргалка backend
Данный репозиторий представляет собой наглядную шпаргалку по основным темам в области Backend-разработки. Весь материал разбит на темы и подтемы. Структура материала состоит из трех частей:
- Визуальная часть — различные изображения/таблицы/шпаргалки для лучшего понимания (может отсутствовать). Все рисунки и таблицы сделаны с нуля, специально для этого репозитория.
- Краткое описание — очень краткая выжимка информации с перечнем основных терминов и понятий. На термины навешиваются гиперссылки ведущие на соответсвующий раздел в Википедии или подобном справочном ресурсе.
- Ссылки на источники — ресурсы, где можно найти полную информацию по конкретному вопросу. По возможности, указываются максимально авторитетные источники, либо же те, которые предоставляют информацию максимально простым и понятным языком.
https://github.com/cheatsnake/backend-cheats
How to Use go:embed in Go
package main
import (
"embed"
"html/template"
"log"
"net/http"
)
var (
//go:embed resources
res embed.FS
pages = map[string]string{
"/": "resources/index.gohtml",
}
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
page, ok := pages[r.URL.Path]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
tpl, err := template.ParseFS(res, page)
if err != nil {
log.Printf("page %s not found in pages cache...", r.RequestURI)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusOK)
data := map[string]interface{}{
"userAgent": r.UserAgent(),
}
if err := tpl.Execute(w, data); err != nil {
return
}
})
http.FileServer(http.FS(res))
log.Println("server started...")
err := http.ListenAndServe(":8088", nil)
if err != nil {
panic(err)
}
}
index.gohtml
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>go:embed demo</title>
</head>
<body>
<div>
<h1>Hello, {{ .userAgent }}!</h1>
<p>If you see this, then go:embed worked!</p>
</div>
</body>
</html>
nginx allowed country
https://devcoops.com/block-visitors-by-country-in-nginx/
https://mailfud.org/geoip-legacy/
https://ru.stackoverflow.com/questions/1378257/%D0%9A%D0%B0%D0%BA-%D0%BF%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C-geoip-%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8C-%D0%B2-docker-%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%B9%D0%BD%D0%B5%D1%80%D0%B5-nginx
http {
...
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default no;
US yes;
}
}
server {
...
if $(allowed_country = no) {
return 403;
}
}
