tree .
.
├── Dockerfile
├── Makefile
├── README.md
├── api
├── dbconfig.yml
├── docker-compose.override.yml
├── docker-compose.yml
├── env
│ ├── postgres.ci.env
│ ├── postgres.env
│ ├── postgres.example.env
│ ├── testing.ci.env
│ ├── testing.env
│ └── testing.example.env
├── examples
│ └── config.user.add.yaml
├── go.mod
├── go.sum
├── internal
│ ├── commands
│ │ ├── cli
│ │ │ ├── command.go
│ │ │ └── users
│ │ │ └── command.go
│ │ └── server
│ │ └── command.go
│ ├── constant
│ ├── service
│ │ └── service.go
│ ├── services
│ │ └── grpc
│ │ └── users
│ │ └── service.go
│ └── storages
│ ├── storages.go
│ └── users
│ ├── interface.go
│ ├── postgres
│ │ ├── add.go
│ │ ├── storage.go
│ │ └── storage_test.go
│ ├── redis
│ │ ├── add.go
│ │ ├── storage.go
│ │ └── storage_test.go
│ ├── tests
│ │ ├── add.go
│ │ ├── delete.go
│ │ └── generage.go
│ └── user.go
├── main.go
└── migrations
├── 20231217192045-schema.sql.sql
└── 20231217192051-other.sql.sql
19 directories, 35 files
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
package handlers
import (
"project/context"
)
type AddItemsRequestData struct {
Name string `json:"name"`
}
type AddItems {
ctx *context.Context
}
func NewAddItems(ctx *context.Context) (*AddItems, error) {
return &AddItems{
ctx: ctx,
}, nil
}
func (h *AddItems) ServeHTTP(res http.ResponseWriter, req *http.Request) {
...
h.ctx.Profiler.Get("name") <-- здесь для каждого запроса пользователя вызывается метод Get() заранее инициализированного объекта
...
}
package main
import (
"log"
"project/context"
"project/handlers"
)
func main() {
...
ctx, err := context.New()
if err != nil {
log.Fatalf(err)
}
...
http.Handle("/profiler/", CheckHandler(handlers.NewAddItem(ctx)))
...
err := http.ListenAndServe(":80", nil)
log.Fatalf(err)
}
// CheckHandler проверяет создание хандлера
func CheckHandler(handler http.Handler, err error) http.Handler {
if err != nil {
log.Fatalf("handler error: %v", err)
}
if handler == nil {
log.Fatalf("empty handler")
}
return handler
}
package handlers
import (
"project/context"
"project/profiler"
)
type AddItemsRequestData struct {
Name string `json:"name"`
}
type AddItems {
ctx *context.Context
}
func NewAddItems(ctx *context.Context) (*AddItems, error) {
return &AddItems{
ctx: ctx,
}, nil
}
func (h *AddItems) ServeHTTP(res http.ResponseWriter, req *http.Request) {
...
pr := profiler.New() <-- здесь для каждого запроса пользователя создаётся новый экземпляр
pr.SetName("name")
...
}
package context
import (
"project/profiler"
)
// Context содержит необходимые библиотеки, такие как хранилища например
type Context struct {
Profiler *profiler.Profiler
}
// New возвращает новый Context
func New(
profiler *profiler.Profiler
) (
*Context,
) {
context := &Context{
Profiler: profiler,
}
return context
}
package main
import (
"fmt"
"strings"
"errors"
)
func main() {
fmt.Println("Hello, playground")
d := New()
d.Parse("1/4")
fmt.Println(d)
}
type Shot struct {
i string // number
f string // fraction
}
func New() (s *Shot) {
s = new(Shot)
return
}
func (s *Shot) Parse(text string) (err error) {
v := strings.Split(text, "/")
if len(v) != 2 {
err = errors.New("Error parse shot")
return
}
s.i = v[0]
s.f = v[1]
return
}
package main
import (
"github.com/mantyr/newtime"
"fmt"
)
func main() {
date := newtime.NewTime()
date.Parse("16-08-2016 15:11:06", "dd-mm-yyyy HH:ii:ss")
fmt.Println(date.Format("YYYY-mm-dd HH:ii:ss")) // "2016-08-16 15:11:06"
}
package tmpl
import (
"net/http"
)
func Redirect(w http.ResponseWriter, address string) {
if address == "" {
address = "/"
}
w.Header().Set("Location", address)
w.Header().Set("Cache-Control", "private, no-store, max-age=0, must-revalidate")
w.WriteHeader(303) // see https://ru.wikipedia.org/wiki/Список_кодов_состояния_HTTP#303
}
package main
import (
"fmt"
"sync"
)
type Map struct {
sync.RWMutex
ch chan string
d map[string]string
}
func NewMap() (m *Map) {
m = new(Map)
m.ch = make(chan string, 10000)
m.d = make(map[string]string)
return
}
func (m *Map) Add(key, value string) {
m.Lock()
defer m.Unlock()
m.check(50, true)
m.d[key] = value
m.ch <- key
}
func (m *Map) Get(key string) string {
m.RLock()
defer m.RUnlock()
if v, ok := m.d[key]; ok {
return v
}
return ""
}
func (m *Map) Check() {
m.check(50, false)
}
func (m *Map) check(len_max int, is_lock bool) {
ch_len := len(m.ch)
if ch_len > len_max {
if !is_lock {
m.Lock()
defer m.Unlock()
}
ch_len = len(m.ch)
for i := 0; i < ch_len - len_max; i++ {
delete(m.d, <- m.ch)
}
}
}
func (m *Map) Len() int {
return len(m.ch)
}
func main() {
m := NewMap()
for i := 0; i < 1000; i++ {
m.Add(fmt.Sprintf("key_%s", i), fmt.Sprintf("value_%s", i))
}
fmt.Println(m.Len())
}
package conf // <-- здесь название библиотеки для которой предназначены бенчмарки
import (
"testing"
)
func BenchmarkLoadGo(b *testing.B) {
conf := NewConfig()
conf.SetDefaultFile("properties")
conf.SetDefaultCatalog("./testdata") // default "./configs"
b.ResetTimer() // <-- обнуляем таймер что бы вся "сложная" и "единомоментная" работа не попала в подсчёт
for i := 0; i < b.N; i++ {
go conf.GetSection("server_1", "storage") // <-- в данном случае тестируется сценарий в конкурентном виде, но чаще всего этого не требуется и конкретно в том коде откуда взят бенчмарк есть отдельный бенч для не конкурентного доступа и сравнивая их можно иметь представление о том как оно себя поведёт в обоих сценариях.
}
}
len([]byte("string")) // <-- количество байт
package main
import (
"github.com/gorilla/websocket"
"net/http"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 4096,
WriteBufferSize: 4096,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
// вот тут вы можете проверить login/password и прочее или же сделать для этого отдельный метод /login, а тут проверять лишь есть ли у него сессия
ws, err := upgrader.Upgrade(w, r, nil)
if _, ok := err.(websocket.HandshakeError); ok {
http.Error(w, "Not a websocket handshake", 400)
return
} else if err != nil {
return
}
ws_list.Append(ws, r) // вот тут вы уже знаете что сокет вам подходит и от какого он пользователя и дальше заносите его в какое-то хранилище которое их хранит и по которому потом рассылаете данные.
}
package events
import (
"sync"
)
var events *Events
type Events struct {
sync.RWMutex
list map[string]func(ps []string)
}
func NewEventsList() (list *Events) {
list = new(Events)
list.list = make(map[string]func(ps []string))
return list
}
func init() {
events = NewEventsList()
}
func Add(name string, callback func(ps []string)) {
events.Add(name, callback)
}
func Call(name string, ps []string) bool {
return events.Call(name, ps)
}
// Подписка на событие
func (l *Events) Add(name string, callback func(ps []string)) {
l.Lock()
defer l.Unlock()
l.list[name] = callback
}
// Вызов события
func (l *Events) Call(name string, ps []string) bool {
l.RLock()
defer l.RUnlock()
if f, ok := l.list[name]; ok {
go f(ps)
return true
}
return false
}
package main
import (
"fmt"
"github.com/mantyr/rjson"
)
func main() {
data := []byte(`{
middle : {
src: "pictures/product/123.jpg",
place : '#preview-img', // Added support for JavaScript object parsing
title: "title"
}
}`)
var v struct {
Middle struct {
Src string
Place string
Title string
}
}
err := rjson.Unmarshal(data, &v)
fmt.Println(v) // print {{pictures/product/123.jpg #preview-img title}}
fmt.Println(err) // print <nil>
}
package main
import (
"testing"
"github.com/robertkrimen/otto"
)
func BenchmarkVMGet(b *testing.B) {
vm := otto.New()
b.ResetTimer()
for i := 0; i < b.N; i++ {
st := `
{
middle : {
src: 'pictures/product/middle/14906_middle.jpg',
place : '#preview-img',
title: '343880-090-slantsy-nike-benassi-just-do-it'
}
}
`
vm.Run(`
obj = `+st+`
src = obj.middle.src;
`)
src, err := vm.Get("src") // <-----
_ = src
_ = err
}
}
# go test -bench=".*" ottotest
testing: warning: no tests to run
PASS
BenchmarkVMGet 30000 58103 ns/op
ok ottotest 2.367s
type Animal struct {
Name string
}
type Rabbit struct {
Ani Animal
}
func (this *Rabbit) Walk() *Rabbit{
this.Ani.Walk()
fmt.Println("...and Jump")
return this
}
func (this *Rabbit) Say() *Rabbit{
this.Ani.Say()
return this
}
rabbit := Rabbit{ }
rabbit.Ani.Name = "Кроль"
rabbit.Ani.Walk()
rabbit.Ani.Say()
rabbit.Ani.Walk()
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
func (rs *Rows) Close() error
func (s *Stmt) Close() error