• Как правильно установить несколько версий го на одной системе?

    @falconandy
    Есть простой официальный способ, если он вам подходит. Бинарники будут называться типа go1.10.7
    Ответ написан
    Комментировать
  • Как узнать когда горутины закончили запись, чтобы закрыть канал?

    @falconandy
    Примерно так: https://goplay.tools/snippet/TciyGAE8dyn
    Ответ написан
    Комментировать
  • Как сделать вывод массива со сдвигом?

    @falconandy
    1. Строка text = '' * maximum + text выглядит бесполезной - для чего пустую строку пытаться реплицировать?
    2. Выхлоп вашего скрипта (на Python 3, но это не должно вроде влиять) отличается от вами приведенного. Не хватает укорачивания строк:
    ...
    wxxyyzz0011223344556677889900
    xxyyzz0011223344556677889900
    xyyzz0011223344556677889900
    yyzz0011223344556677889900
    yzz0011223344556677889900
    zz0011223344556677889900
    z0011223344556677889900
    0011223344556677889900
    011223344556677889900
    11223344556677889900
    1223344556677889900
    223344556677889900
    23344556677889900
    3344556677889900
    344556677889900
    44556677889900
    4556677889900
    556677889900
    56677889900
    6677889900
    677889900
    77889900
    7889900
    889900
    89900
    9900
    900
    00
    0

    3. Для текущей версии аналог на Go:
    package main
    
    func main() {
    	text := "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz0011223344556677889900"
    	show(text, 30)
    }
    
    func show(text string, maximum int) {
    	for i := range text {
    		if i+maximum < len(text) {
    			println(text[i : i+maximum])
    		} else {
    			println(text[i:])
    		}
    	}
    }
    Ответ написан
    1 комментарий
  • Проблема с range. Как решить?

    @falconandy
    Поменяйте имена полей структуры - начните их с заглавной буквы, чтобы сделать публичными (например, Name string).
    Ответ написан
    Комментировать
  • Не будет гонки и повреждения данных в памяти?

    @falconandy
    По-моему вы переусложняете без необходимости. Если значения из конфига только читаются, то потокобезопасность не нужна. Если же у вас предполагается еще и изменение, то в пул возвращаются указатели на "порченные" объекты, что тоже неправильно.
    Если возможно, конфиг лучше прочитать в начале выполнения, а также паниковать на уровне main.
    В результате и код проще, и тормозить нечему:
    package config
    
    import (
    	"encoding/json"
    	"fmt"
    	"os"
    )
    
    type Cfg struct {
    	// Fields
    }
    
    var (
    	cfg *Cfg
    )
    
    func Config() *Cfg {
    	return cfg
    }
    
    func LoadConfig() error {
    	f, err := os.Open("./config/config.json")
    	if err != nil {
    		return fmt.Errorf("can't open config file: %w", err)
    	}
    	defer f.Close()
    
    	dec := json.NewDecoder(f)
    	var c *Cfg
    	if err := dec.Decode(c); err != nil {
    		return fmt.Errorf("can't decode config file: %w", err)
    	}
    
    	if err := validate(c); err != nil {
    		return fmt.Errorf("can't validate config file: %w", err)
    	}
    	
    	cfg = c
    
    	return nil
    }
    
    func validate(cfg *Cfg) error {
    	// Logic
    	return nil
    }
    Ответ написан
    Комментировать
  • Горутино-безопасное обоащение к sqlite3?

    @falconandy
    Можно ограничить максимальное кол-во соединений до 1:
    db.SetMaxOpenConns(1)
    Это приведет к тому, что и запросы на чтение перестанут выполняться параллельно - так что может подойти, если у вас запросы "шустрые".
    Плюс в том, что в коде не надо будет ничего менять, никаких мьютексов.
    Но так как у вас мест записи в БД немного, то можно использовать и мьютексы - вряд ли вы что-то упустите.
    Если бы мест изменения БД было много, то еще можно рассмотреть вариант обертки над *sql.DB, в которой автоматически использовать мьютекс для всех "подозрительных" методов - например Exec методов (из предположения что в них как правило идет изменение БД) или Query методов, если в запросе есть insert, update или delete.

    Вот еще ссылка по теме: https://stackoverflow.com/questions/35804884/sqlit...
    Ответ написан
    Комментировать
  • Нужна помощь с кросс компиляцией бинарника под разные системы Linux?

    @falconandy
    Можно переписать на Go и скомпилировать статический бинарник без зависимостей.
    https://www.arp242.net/static-go.html
    В только что зарелизенном Go 1.15 размер бинарника будет поменьше чем на предыдущих версиях.

    Для компиляции 32-битной версии просто устанавливайте пару переменных:
    GOOS=linux GOARCH=386 go build
    Ответ написан
  • Порядок действий для оформления самозанятого, для иностраных платежей и выбор банка?

    @falconandy
    Мой недавний опыт
    1. На сайте Альфа-банка заказал бесплатную дебетовую карту с выдачей в отделении (отделение выбрал центральное с "моментальной" выдачей). Альфа-банк, потому что в моем регионе у них есть банкоматы с приемом/выдачей валюты. Заранее установил мобильное приложение Альфа-банка. Через пару часов туда подъехал, по-моему по моей заявке еще никто ничего не делал. Поинтересовались, для чего мне их карта и выдали мне именную рублевую дебетовую карту (в заявке указывал MasterCard, но принесли Visa - мне было непринципиально), и дополнительно я попросил долларовую (собственно для этого я и забирал лично, хотя можно было заказать доставку) - выдали неименную. Мобильное приложение Альфы понадобилось, чтоб тут же активировать карты. Всё заняло минут 20-25, но мои данные у них уже были, несколько лет назад я получал через них зарплату.
    2. Зарегистрировался как самозанятый через веб-доступ налоговой (в моем регионе доступно с июля 2020 г.).
    3. Установил мобильное приложение Мой Налог. В мобильном приложении Альфа-банка зарегистрировался как уже зарегистрированный самозанятый.
    4. Добавил 2 новых счета (рублевый и долларовый), назвал их, чтоб было понятно что они для учета доходов от самозанятости.
    5. Добавил эти счета в Upwork (рублевый "Direct to Local Bank" и долларовый "Wire Transfer")
    6. С рублевым счетом проблем не было, а в долларовом не совпало моё имя (в Альфе было еще отчество и транслитерация одной буквы не совпадала) - отправил запрос в поддержку Upwork и счет в течение нескольких часов одобрили.
    7. Добавленные счета становятся доступными для вывода через 3 дня.
    8. Через 3 дня вывел в долларах через "Wire Transfer", на счет Альфы пришло на следующий день. Никакого явного валютного контоля не было, документы не просили, комиссий не снялось (только $30 снял Upwork как и положено).
    9. Самостоятельно посчитал пришедшую сумму в рублях по курсу ЦБ на дату получения денег на счет.
    10. В мобильном приложении Альфы создал новый чек от иностранной организции (Upwork Global Inc.), указал сумму в рублях. Проверил в приложении Мой Налог, что чек нормально ушел и начислился налог (по факту реального налога пока нет, т.к. действует налоговый бонус около 22000 руб. = 10000 руб + чуть больше 12000 руб.)
    11. На всякий пожарный случай: скачал шаблон Confirmation of Service, заполнил и отправил в поддержку Upwork. Полученный от них подписанный экземпляр сохранил.
    Ответ написан
  • Аналог electron только на GO?

    @falconandy
    Гляньте на

    A tiny cross-platform webview library for C/C++/Go... It uses Cocoa/WebKit on macOS, gtk-webkit2 on Linux and Edge on Windows 10.

    A very small library to build modern HTML5 desktop... It uses Chrome browser as a UI layer. Unlike Electron it doesn't bundle Chrome into the app package, but rather reuses the one that is already installed.
    Ответ написан
    Комментировать
  • Как зафиксировать разрыв подключения (НЕ отключения) клиента по HTTP?

    @falconandy
    Посмотрите https://stackoverflow.com/questions/36781707/what-... (ответ, помеченный как лучший). Суть в установке явных таймаутов на чтение/запись на уровне tcp-соединения.
    Ответ написан
    Комментировать
  • Как послать в пул - воркер команду ожидания?

    @falconandy
    Как грубый вариант:

    1. пул воркеров, которые тянут информацию, передавая данные о сессии, но сами (пере)авторизацией не занимаются
    2. отдельная горутина, которая занимается (пере)авторизацией
    3. текущая сессия (токен, куки)
    4. Condition Variable (https://golang.org/pkg/sync/#Cond), с помощью которой синхронизируется доступ у текущей сессии

    Изначально:
    текущей сессии нет, воркеры ждут сигнала от Condition Variable
    Горутина авторизации видит что текущей сессии нет, авторизуется, устанавливает текщую сессию и broadcast-ит событие с помощью Condition Variable. После чего засыпает до сигнала от Condition Variable.
    Воркеры просыпаются и начинают работу.

    Сессия протухла:
    Воркер получает статус необходимости авторизации (например статус 401), сбрасывает текущую сессию (если она установлена и равна той про которую он знал), и broadcast-ит событие с помощью Condition Variable.
    Горутина авторизации просыпается, видит что текущей сессии нет, снова начинает процесс авторизации.
    В это время другие воркеры получают 401, они проверяют, что текущая сессия пуста и засыпают до сигнала от Condition Variable
    Горутина авторизации, закончив процесс авторизации, устанавливает текщую сессию и broadcast-ит событие с помощью Condition Variable. После чего вновь засыпает до сигнала от Condition Variable.
    Приостановленные воркеры просыпаются и переповторяют запросы.
    Воркеры, которые не успели заснуть, просто переповторяют запрос с новым значением сессии.
    Ответ написан
    Комментировать
  • Как в goquery правильно выбрать tr and td?

    @falconandy
    Заработает, если вы обернете в тег table.
    Ответ написан
    2 комментария
  • Есть ли в golang альтернатива сравнения строк json?

    @falconandy
    Может подойдет github.com/tidwall/gjson (query an array)
    Ответ написан
    Комментировать
  • Как правильно написать из PHP hex2bin и openssl_decode на Go?

    @falconandy
    package main
    
    import (
    	"encoding/hex"
    	"fmt"
    
    	"golang.org/x/crypto/blowfish"
    )
    
    func main() {
    	encryptedText, _ := hex.DecodeString("c01d7c2768ba633990d458a78e0e4ce50627c20cffe54c8c")
    	key := []byte("j0klBHYlVQOkc1LCE6ECZwBf1Siyvt5l")
    
    	cipher, _ := blowfish.NewCipher(key)
    	plainText := make([]byte, len(encryptedText))
    	size := blowfish.BlockSize
    
    	for bs, be := 0, size; bs < len(encryptedText); bs, be = bs+size, be+size {
    		cipher.Decrypt(plainText[bs:be], encryptedText[bs:be])
    	}
    	fmt.Println(string(plainText))
    }
    Ответ написан
  • Можно ли скомпилировать Powershell скрипт в исполняемый файл включая используемые DLL?

    @falconandy
    Напишите небольшую программу на Go, например. С помощью библиотеки типа https://github.com/rakyll/statik вшейте в бинарник нужные dll-ки и сам powershell-скрипт. Go-бинарник при первом запуске скопирует dll-ки и скрипт во временную папку, а затем запустит powershell-скрипт. При следующих запусках Go-бинарник будет просто запускать скрипт. Дополнительно можно добавить сравнение хэшей вшитых и уже имеющихся файлов, чтобы при выпуске новой версии заменять устаревшие файлы (dll-ки и скрипт).

    Альтернатива: если powershell-скрипт действительно простой (вставить запись в БД) и dll-ки используются для связи с БД или еще какой-то стандартной логики, просто перепишите его на Go безо всяких dll-ок и рантайм-зависимостей.
    Ответ написан
    Комментировать
  • Go-micro. Проблема с обнаружением сервиса из примера в документации. Что делаю не так?

    @falconandy
    Посмотрите https://github.com/micro/examples/issues/98 - советуют разобраться с firewall и собирать/запускать в режиме "go module". На Ubuntu 18.04 с go 1.14.2 всё ок.
    Ответ написан
    1 комментарий
  • Опечатка в книге?

    @falconandy
    Вас вводит в заблуждение %b - для отрицательных чисел отбражается не "настоящее" двоичное представление (вместо 11111111 выводится -1).
    https://stackoverflow.com/questions/49573389/forma...
    https://stackoverflow.com/questions/37582550/golan...
    Конечно же -1 это 11111111 для int8, но чтобы получить такой вывод для %b, надо сконвертировать явно в uint8.
    Ответ написан
    1 комментарий
  • Какой самый хороший роутер для Golang сервера?

    @falconandy
    Ответ написан
    Комментировать