• Что выбрать с++, с или go для алгоритма?

    mirrr
    @mirrr
    Программист и просто хороший человек
    В С и С++ я начинающий, буду учиться по-ходу. Но 12 лет в Php+JS.

    Нет времени объяснять, используйте Go!
    Ответ написан
    1 комментарий
  • Что быстрее- хранить значения в памяти Golang или Redis?

    mirrr
    @mirrr
    Программист и просто хороший человек
    В какой ситуации Redis или похожие инструменты стоит использовать.

    Допустим, оперативные данные - цифра открытых соединений в определенный момент времени. Решается на уровне приложения просто, создаем переменную-счетчик, при открытии соединения увеличиваем, при закрытии - уменьшаем. Но с ростом нагрузки, приходится запустить несколько экземпляров приложения на нескольких серверах. Теперь в каждом экземпляре - разные счетчики и разные значения. Но если использовать внешнее хранилище - счетчик будет содержать общую цифру соединений.
    Второй случай - нужна сохранность данных в кеше при перезапуске/падении приложения. Например, тот-же счетчик, но уже не открытых соединений, а посетителей за сегодня. После каждого перезапуска терять данные нельзя.
    Третий случай - использование специфичных хранилищ, типа HyperLogLog в редисе.
    Ответ написан
    Комментировать
  • Какой Golang шаблонизатор выбрать и как подключить файлы динамически?

    mirrr
    @mirrr
    Программист и просто хороший человек
    В родных шаблонизаторах (text/template и html/template) нет функций подключения файлов, но есть возможность подключать другие шаблоны, добавленные, например, через template.ParseFiles или template.ParseGlob.

    Для начала парсим все шаблоны из каталога templates/ :
    funcs := template.FuncMap{
    	"SayHello": func(s string) string {
    		return "Hello"
    	},
    }
    
    t := template.Must(template.New("").Funcs(funcs).ParseGlob("templates/*.html"))


    Дальше используем:
    t.ExecuteTemplate(os.Stdout, "index.html", map[string]string{"title": "My site"})


    А внутри index.html пишем:
    {{template "login-form.html" .}}

    В FuncMap так-же можно добавить еще какую-нибудь функцию GetFile, которая будет читать файл и отдавать его содержимое в шаблон без обработки шаблонизатором.

    Но если использовать какой-нибудь gin-gonic, то все так:
    r := gin.New()
    r.LoadHTMLGlob("templates/*.html")
    
    r.GET("/", func(c *gin.Context) {
    	c.HTML(200, "index.html", map[string]string{"title": "My site"})
    })
    Ответ написан
    Комментировать
  • Как реализовать нормальные отношения между доками в mgo golang??

    mirrr
    @mirrr
    Программист и просто хороший человек
    В агрегациях монги, начиная с 3.2 есть аналог LEFT JOIN - $lookup. В mgo агрегации реализуются через Pipe. Маленький пример на коленке, в поле news при выборке попадают все новости автора:

    package main
    
    import (
    	"encoding/json"
    	"fmt"
    	"gopkg.in/mgo.v2"
    )
    
    type (
    	obj map[string]interface{}
    	arr []interface{}
    )
    
    func main() {
    	mongo, err := mgo.Dial("localhost")
    	if err != nil {
    		panic(err)
    	}
    
    	info := []obj{}
    
    	if err := mongo.DB("myDB").C("authors").Pipe(arr{
    		obj{"$match": obj{"banned": false}},
    		obj{"$lookup": obj{"from": "news", "localField": "_id", "foreignField": "authorID", "as": "news"}},
    	}).All(&info); err != nil {
    		fmt.Println("Error:", err)
    	}
    
    	printJSON(info)
    }
    
    func printJSON(t interface{}) {
    	j, _ := json.MarshalIndent(t, "", "\t")
    	fmt.Println(string(j))
    }
    Ответ написан
    Комментировать
  • Создание не используемой переменной, зачем?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Я так поступаю, когда планирую в дальнейшем использовать переменную. Но после того как уже использовал изредка, но бывает, что забываю удалить "заглушку". Может здесь подобный случай?)
    Ответ написан
  • Почему mogolab не сохраняет объекты (golang, драйвер "gopkg.in/mgo.v2", )?

    mirrr
    @mirrr
    Программист и просто хороший человек
    package main
    
    import (
    	"fmt"
    	"gopkg.in/mgo.v2"
    )
    
    type (
    	person struct {
    		Name  string
    		Phone string
    	}
    )
    
    func main() {
    	session, err := mgo.Dial("localhost")
    	if err != nil {
    		panic(err)
    	}
    
    	session.SetMode(mgo.Monotonic, true)
    	col := session.DB("database").C("collection")
    
    	count, _ := col.Count()
    	fmt.Println(fmt.Sprintf("Messages count: %d", count))
    
    	err = col.Insert(&person{Name: "TestName", Phone: "+365756765"})
    }


    Результат:

    > use database
    switched to db database
    > db.collection.find()
    { "_id" : ObjectId("56bf67529ac5b6a0afcbe7b4"), "name" : "TestName", "phone" : "+365756765" }
    { "_id" : ObjectId("56bf67569ac5b6a0afcbe7b5"), "name" : "TestName", "phone" : "+365756765" }
    { "_id" : ObjectId("56bf67589ac5b6a0afcbe7b6"), "name" : "TestName", "phone" : "+365756765" }
    { "_id" : ObjectId("56bf675a9ac5b6a0afcbe7b7"), "name" : "TestName", "phone" : "+365756765" }


    В моем коде все работает. Что у вас не так, сложно понять, так-как код приведен не полностью. Но могу предположить, что в структуре Person названия полей не с заглавных букв начинаются и потому поля приватны.
    Ответ написан
  • Golang: пакет time. Возможно ли штатным образом проверить дату на корректность?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Проблема (или нет) в том, что голанг распаршивает дату 30.02.2016 как 01.03.2016. И ошибку не выдает. Потому самый простой вариант - сравнить полученную дату с введенной.
    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    func Check(format, date string) bool {
    	t, err := time.Parse(format, date)
    	if err != nil {
    		return false
    	}
    	return t.Format(format) == date
    }
    
    func main() {
    	fmt.Println(Check("02.01.2006", "29.02.2015")) // false
    	fmt.Println(Check("02.01.2006", "30.02.2016")) // false
    	fmt.Println(Check("02.01.2006", "31.04.2015")) // false
    	fmt.Println(Check("02.01.2006", "32.04.2015")) // false
    }
    Ответ написан
  • Правильно ли я делаю таблицу с правами?

    mirrr
    @mirrr
    Программист и просто хороший человек
    А я бы использовал битовую маску, тем более go прекрасно умеет с ними работать)
    type Rights int64
    
    const (
    	RightsAuth             = 1 << iota // 1 << 0 which is 0000000000000001
    	RightsRegs                         // 1 << 1 which is 0000000000000010
    	RightsBattlesInvasion              // 1 << 2 which is 0000000000000100
    	RightsBattlesSanctions             // 1 << 3 which is 0000000000001000
    	RightsBattlesGround                // 1 << 4 which is 0000000000010000
    	RightsMissionsLocation             // 1 << 5 which is 0000000000100000
    	// ...
    )


    Вот здесь более подробный пример: pastebin.com/jz6TZevq
    Ответ написан
    Комментировать
  • На чем написать высоконагруженный api сервер?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Для golang даже код готовый дать могу )
    pastebin.com/qwXgUXdJ

    Но рекомендовать не буду) Просто для оценки поля боя)
    Ответ написан
    Комментировать
  • Развертывание web приложения на Go?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Опишу свой способ, который перекликается со способом Алексей . Все это делается одним bash-скриптом, но распишу примерный алгоритм.

    1) Создаем юзера под которым будет работать приложение и переключаемся на него:
    useradd -s /bin/bash <имя_пользователя>
    su <имя_пользователя>


    2) Генерируем новый ключ для деплоя
    ssh-keygen -t rsa -C "<имя_пользователя>@<домен_сервиса>"
    cat ~/.ssh/id_rsa.pub

    Например, в gitlab добавляем этот ключ Project>Settings>Deploy Key

    3) Клонируем приложение и собираем приложение
    cd ~
    git clone ssh://______.git app 
    # здесь не буду расписывать, можно устанавливать через go get и т.д. способы отличаются
    # для go get нужно прописать $GOPATH в .bash_profile


    4) Создаем systemd service
    exit #выходим из-под юзера
    nano /etc/systemd/system/<service_name>.service

    Вписываем:
    [Unit]
    Description=<description>
    
    [Service]
    Restart=always
    RestartSec=10
    EnvironmentFile=-/<service_path>/env
    WorkingDirectory=/<service_path>/appDir
    ExecStart=/<service_path>/appDir/appName
    LimitNOFILE=524576
    LimitNPROC=524576
    User=<user>
    Group=<userGroup>
    StandardOutput=syslog
    StandardError=syslog
    SyslogIdentifier=<service_name>
    
    
    [Install]
    WantedBy=multi-user.target


    5) Запускаем сервис и ставим в автозагрузку:

    systemctl start <имя_сервиса>
    systemctl enable <имя_сервиса>


    Посмотреть статус:

    systemctl status <имя_сервиса>

    6) Разрешаем просмотр логов и перезапуск сервиса под созданным пользователем
    Добавляем в /etc/sudoers строчки:

    Defaults:<имя_пользователя> !authenticate
    <имя_пользователя> ALL=/usr/bin/systemctl restart <имя_сервиса>, /usr/bin/systemctl stop <имя_сервиса>, /usr/bin/systemctl start <имя_сервиса>, /usr/bin/journalctl


    Теперь эти операции не будут требовать пароля:
    sudo journalctl -f  -u <имя_сервиса> 
    sudo systemctl stop <имя_сервиса>
    sudo systemctl start <имя_сервиса>
    sudo systemctl restart <имя_сервиса>


    7) настраиваем виртуальный хост nginx для проксирования на порт приложения, если требуется:
    server {
        listen 80;
        server_name site.ru;
    
        client_max_body_size 256m;
        access_log  /var/log/nginx-site-acc;
        error_log /var/log/nginx-site-err;
        log_not_found off;
    
        location ^~ / {
            proxy_pass http://localhost:<порт_приложения>;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_buffer_size 16k;
            proxy_buffers 32 16k;
            proxy_connect_timeout 300;
            proxy_send_timeout 300;
            proxy_read_timeout 300;
        }
    
        location ^~ /files {
            alias /home/<имя_пользователя>/app/some_files;
        }
    }
    Ответ написан
    Комментировать
  • Есть ли альтернативные пакеты для html шаблонов(написал свой)?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Я бы отдавал html как статику, а рендер вынес на сторону клиента, используя микро-темплейтер типа doT.js или swig
    Ответ написан
  • Как сделать эту функцию не такой страшной?

    mirrr
    @mirrr
    Программист и просто хороший человек
    func dataValid(result []string) bool {
    	return v.IsLogin(result[0]) && isLoginAvailable(result[0]) &&
    		v.IsEmail(result[1]) && isEmailAvailable(result[1]) &&
    		v.IsPass(result[2])
    }
    Ответ написан
    3 комментария
  • Сидячий образ жизни кодера на самом деле ухудшает здоровье?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Думаю, вредит. Потому под столом у меня валяются гантели, а на таймере стоит разминка)
    Ответ написан
    Комментировать
  • В чем преимущество динамически типизированных языков?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Как по мне, преимущество интерпретируемых перед C вот в чем (js, питона не знаю):

    var obj = {
        a: 10,
        b: "Hello",
        c: true,
        d: {
            e: {
                f: 10000
            }
        }
    }
    
    obj.a = "user";
    obj.b += " world";
    obj.b.x = obj.d.e.f;
    obj.b.x++;
    console.log(obj.b, obj);


    Собсно пишется программа очень быстро по сравнению с си, да и код будет короче и проще.
    Ответ написан
    Комментировать
  • Почему закрывается приложение на NodeJS после выхода из консоли?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Запускайте через forever или как сервис systemd и будет вам счастье)
    Ответ написан
    Комментировать
  • Возможно достать Юзера из сессии без обекта req?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Непонятна суть вопроса. Если есть входящее соединение, есть req. Зачем что-то вытягивать без него?
    Ответ написан
    Комментировать
  • Можно ли подвинуть background с repeat?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Вариант через прозрачный border, но придется установить background-clip: padding-box:

    jsfiddle.net/gjcbzwz5
    Ответ написан
    3 комментария
  • Когда лучше хранить изображения в файловой системе а когда в БД?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Немного припозднился с ответом. Но все же.
    Лучше организовать приложение на ноде так, чтобы можно было перебросить большую часть работы хоть на тот же nginx. На машине девелопера пусть себе файлы отправляет нода. На продакшине отдачу статики лучше возложить на nginx. В идеале - шаблоны сайтов тоже пусть он шлет, а взаимодействие nodejs-клиент пусть происходит в формате легких json запросов, которые уже на клиенте оборачиваются в шаблоны с помощью doT.js или swig.
    Если же файлы будут лежать в БД, то выковырять их оттуда чем-либо, кроме вашего приложения будет проблематично.
    Ответ написан
    Комментировать
  • Умер GNOME в ArchLinux?

    mirrr
    @mirrr
    Программист и просто хороший человек
    Я просто оставлю это здесь
    Ответ написан
    Комментировать
  • Как изменить размер боковой панели в наутилусе в папке корзина?

    mirrr
    @mirrr
    Программист и просто хороший человек
    А какая версия?
    Nautilus 3.4.2 — не наблюдаю такого глюка.
    Ответ написан