PostgreSQL backup to Azure

С появлением облачных хранилищ стало грешным не использовать их возможности по хранению террабайтов данных за копейки, поэтому будем сохранять туда Continuous Archive данных из PostgreSQL.

В нашем случае действие происходит на базе Ubuntu 14, PostgreSQL 9.5 установлен локально.
Первым шагом нам необходимо установить сам pghoard и supervisor, т.к. systemd нет, а запускать демона с системой нужно.

Текущая версия pghoard 1.4 в pypi нам не подходит (в ней нету поддержки новых модулей azure-storage), поэтому инсталлировать её нужно из репозитория, а поскольку pghoard работает только с третьим питоном, то делаем это с помощью pip3
UPDATE:
предварительно нужно установить модули:

azure
azure-storage==0.33

и проапгрейдить requests до версии 2.10+
END UPDATE

pip3 install git+https://github.com/ohmu/pghoard
apt-get install supervisor

Для автозапуска демона создаём конфигурационный файл pghoard.conf с минимально необходимым контентом и кладём его в /etc/supervisor/conf.d/

[program:pghoard]
user = postgres  # Запускать нужно от имени postgres, иначе не удастся подключиться к СУБД
group = postgres
directory = /var/lib/pghoard
command = /usr/local/bin/pghoard /var/lib/pghoard/pghoard.json
autostart=true
autorestart=true
environment=HOME="/var/lib/postgresql"  # Должен быть HOME пользователя postgres (туда записывается пароль и потом оттуда считывается)

Создаём пользователя в postgresql для выполнения репликации:
psql -c "CREATE USER pghoard PASSWORD 'hoardpassword' REPLICATION"

И вносим в /etc/postgresql/9.5/main/pg_hba.conf запись, разрешающую выполнять репликацию:
host replication pghoard 127.0.0.1/32 md5

В конфигурационный файл postgresql.conf нужно внести изменения, разрешающие выполнять репликацию:

max_wal_senders = 2
wal_level = archive  # 'hot_standby' or 'logical' are also ok

Перезапускаем postgresql и настраиваем pghoard на работу с Azure:

{
        "backup_location": "/var/lib/pghoard",
        "backup_sites": {
                "mysite": {
                        "nodes": [
                        {
                                "host": "127.0.0.1",
                                "password": "hoardpassword",
                                "port": 5432,
                                "user": "pghoard"
                        }
                        ],
                        "object_storage": {
                                "storage_type": "azure",
                                "account_name": "<storage-account>",
                                "account_key": "<storage-account-key>",
                                "bucket_name": "<bucket-name>"
                        }
                }
        }
}

После этого выполняем service supervisor restart и наблюдаем, как бекапы заливаются в azure blob storage.

Home Automation Framework

ESP-12F

Умный дом, или как программисту (и не только) добавить автоматики в своё жильё. Начну делиться своим опытом начального внедрения Z-Wave, а потом и самодельных девайсов в квартире.

В настоящее время для создания умного дома есть огромное количество различных решений. Если вы любитель DIY, или хотите сэкономить, а может и то, и другое – рекомендую обратить внимание на микросхемы ESP8266, или Arduino + nRF24. На базе ESP можно построить систему используя существующую домашнюю сеть Wi-Fi, на базе nRF можно построить систему по своей беспроводной сети, тоже работающией 2.4 ГГц, но не Wi-Fi, зато с преимуществом в виде возможности ретрансляции сигнала, т.е. каждая единица сети (нода) может общаться не только с контроллером, но и с другими нодами. Фактически mesh-сеть.

ESP-12F

Это “ядро” умного устройства на базе ESP-12F (8266)

С экономической точки зрения ESP-12F стоит на алиэкспрессе 1.80USD за штуку, ардуино стоит 1.60USD, но к ней ещё надо дополнительно покупать трансмиттер NRF24L01+, который стоит порядка 0.9USD.

При этом у ардуины 16-32КБ памяти и слабенький 16MHz Atmel процессор, в то время, как у ESP до 4 мегабайт флеша, аппаратный Wi-Fi с шифрованием и довольно мощный 32 битный RISC процессор, работающий на 80MHz. Выливается это всё в то, что по факту в ESP можно, не сильно напрягаясь, прикрутить OTA обновления и накрутить много всякой автономной логики, например целый веб-сервер, с помощью которого управлять нодой (т.е. обходиться вообще без контроллера). Тут можно посмотреть в сторону проекта NodeMCU, ребята запилили в прошивку интерпретатор LUA с помощью которого можно накручивать весьма сложную логику прямо на устройстве, не задействуя центральный сервер – т.е. создавать автономные системы.

esp-nrf-arduino

nRF24 + Arduino Pro Mini на фоне ESP-12

Z-Wave

В случае же, если есть много денег, или неохота заморачиваться с паяльником, прошивками и разного рода экспериментами – можно посмотреть на Z-Wave:
это уже вполне mature, production решение. В наличии обилие устройств самого разного назначения – и выключатели, и реле, и термостаты с датчиками – бери и образумливай дом хоть сейчас. Стоимость, при этом, немаленькая. Самое простое реле будет стоить порядка 25-30 евро, а контроллер вообще под две сотни тянет.

z-wave promo

После нескольких лет использования Z-Wave оказалось, что я вообще сторонник гибридных решений. В части дома используется Z-Wave, в другой части появляются новые модули на базе ESP.

Чтобы всё это разнообразие взлетело, я использую в качестве контроллера Raspberry PI, к которой добавлена плата расширения RaZberry, позволяющая связываться с Z-Wave устройствами. Рядом с ней добавлена плата для связи с nRF24 устройствами, а связь с ESP осуществляется через локальную сеть.

До тех пор, пока я использовал только Z-Wave – в качестве контроллера мне хватало софта от RaZBerry, под названием Z-Way, но после того, как началась экспансия на DIY устройства – пришлось искать систему, которая сможет общаться со всем этим “зоопарком”. Мой выбор пал на Domoticz. Он умеет работать и с z-wave посредством OpenZWave, и с Arduino + nRF при помощи MySensors сборки для RPi, и с ESP через MQTT, который оказался настолько мощным и удобным протоколом, что появились даже мысли попробовать, когда-то адаптировать MySensors (или как-то написать свою прошивку) на работу через него.

OpenVPN DNS order

Иногда, при подключении к VPN оказывается, что тамошний DNS не резолвит местные имена. Это не потому что он плохой, а потому что винда странная (7). Есть два пункта, которые помогают этот вопрос урегулировать.
Для начала нужно в настройках сети поднять приоритет VPN сети повыше:

control panel -> network and sharing -> change adapter settings -> -n -> advanced settings
Make sure that your tap adapter is at the top of your connections list.

Перед подключением выполнить:
net stop dnscache

Должно помочь.
Можно пойти дальше и запихнуть net stop в батничек, который вызывать при подымании openvpn соединения.

espresso test failure

Если внезапно вы решили подключить espresso и начать писать тесты, а потом после очередных манипуляций вдруг тесты приложения перестали запускаться и начали бросать исключение NoClassDefFoundError YourActivity, то вполне вероятно, что может спасти совершенно нелогичное действие:
Добавить исключения суппорт либы в gradle для компиляции espresso (в моём случае espresso-contrib)

androidTestCompile ('com.android.support.test.espresso:espresso-contrib:2.2') {
    exclude group: 'com.android.support'
    exclude module: 'support-v4'
}

Android x86 emulator и google maps/play services

Google и intel сделали крутую штуку – образы андроида для x86 atom, которые работают весьма шустро на x86 платформе, в отличие от тормозных armv7. Но счастье резко заканчивается, когда нужно делать приложение, использующее google apis (maps, play services) – x86 образы есть только для чистого андроида.

Тем не менее, гугол (который поиск) помогает решить эту проблему – мы модифицируем образ в эмуляторе.

Read more »

Jenkins, MSBuild и Includes

Однажды оказалось, что Jenkins фейлит билды MSVS 2012 (которые выполняются посредством консольного msbuild), с сообщениями о том, что не найдены всякие заголовочные файлы (например al.h). Как известно, в студии начиная с 2010 “глобальные” настройки путей к инклюдам, либам и прочему перенесены в странное место – Property Manager->$Project|$Configuration -> Microsoft.Cpp.$Platform.user. Ну и ладно, казалось бы, зашли, прописали и всё хорошо. Студия компилит, в консоли msbuild тоже нормально всё делает… Вот только Jenkins запускает своего slave windows сборщика от системного пользователя, а настройки путей, они не глобальные, а per-user оказывается, поэтому он и не подхватывает эти пути.

Самым простым решением оказалось, как ни странно, создать каталог, скопировать туда “свой” файлик C:\Users\konst\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props и добавить в командную строку запуска /p:UserRootDir=d:\msbuild_home

Про строки

В процессе портирования одной игры на Sony PSP возникла “классическая” проблема с нехваткой памяти. Впихнуть в N/10 мегабайт памяти игрушку – ещё то развлечение.

Игра была написана, можно сказать по книжке про C++ и STL, но, к счастью, без книжки Александреску. Код довольно чистый и аккуратный, но, поскольку товарищи считают, что памяти много, то аллокации считать не надо, и можно смело делать, например, new ButtonPressedEvent() внутри кадра (это обеспечило дикое, по моему мнению, количество выделений памяти).

Здесь я расскажу ещё и о том, что в проекте всюду использовался std::string (и wstring) (на самом деле был самодельный клон, который по своей сути работал точно также, но позволял делать гадкую вещь – присваивать юникодным контейнерам неюникодные строки и наоборот, в остальном – тоже самое).

При старте игры зачитываются xml конфиги, из которых вычитываются пути к почти всем ресурсам и загружаются сразу в память. После этого вступительные ролики и главное меню.

В общем в результате при входе в главное меню у нас наблюдалась картина:

nAllocatedBlocks 47089
nAllocatedSize 14563733
peakAllocationSize 17645007

Как мы видим – 47 тыс аллокаций, дающих в результате 14,5 МБ.

Решено было перевести такую безобидную вещь, как Filename (т.е. имя файла с ресурсами, которые загружаются и по которым потом работают ещё всякие мапы и прочие поиски – тоже зло, конечно) с std::wstring (а иногда std::string) на фиксированую строку rk::String<1024> (в зависимости от настроек компилятора она внутри или char, или wchar_t, в нашем случае wchar_t).

Возни при переделке было очень много. Из злобных вещей, которые сразу всплывали – были “неявные” конверсии между ANSI – Unicode – т.е. выражение вида std::wstring filename = “texture.png” на самом деле вызывало бурю эмоций у системы, т.к. нужно было сначала создать строку ansi, создать буфер в памяти, сконвертить её в юникод и потом записать в целевой контейнер. И это только потому что автор забыл написать перед строчкой букву L (L”text”). Ну а поскольку встречались эпические куски кода, где разные строки конкатенировались  из фрагментов, где часть была анси, а часть юникод, чтобы получить полный путь к ресурсу – то получаемый оверхед представляется значительным.

После того, как весь код, связанный с именами файлов был переведён на фиксированые строки и использование только юникодных строк у нас получилась следующая картинка в главном меню:

nAllocatedBlocks 16978
nAllocatedSize 10259790
peakAllocationSize 12734865

Как мы видим – количество произведённых аллокаций уменьшилось почти в 3 раза, это в основном заслуга того, что исчезли неявные конверсии кодировок.

А вот выигрыш по памяти – почти 5МБ (30%) – это уже серьёзная заявка на успех, при том, что rk::String<1024> явный оверкилл и перерасход для имён файлов, длина которых врядле превысит 128 символов (хотя скорее всего здесь была или жуткая ошибка в логике игры, и строки плодились, как кролики, или странная странность в измерениях, но это поведение я буду и дальше изучать, вместе с дальнейшим выпиливанием динамических строк).

Собсно что я хотел рассказать в этом посте:

Старайтесь использовать фиксированые строки. Как правило, в игровом коде нету необходимости динамически менять строки и делать с ними всякие гадкие вещи. Если же вы видите, что ну никак без этого не обойтись – то это скорее всего из-за того, что, либо у вас очень высокая квалификация и вы точно знаете, что делаете и как оно будет работать, либо у вас наоборот – не очень высокая квалификация – и тогда стоит подумать ещё над проектом – может всё-таки найдётся возможность обойтись?

Не смешивайте в рамках одного проекта разные кодировки, особенно с неявными преобразованиями (их вообще лучше запретить под страхом луча поноса в сторону автора). Изначально определитесь, ANSI, UTF-8, UTF-16 или ещё что-то и пользуйтесь чем-то одним. Идеально – все статические строки оборачивать макросом типа _T(), который на основании настроек компиляции будет выбирать кодировку. Этим вы облегчите жизнь не только себе, когда внезапно окажется, что нужно делать японскую локализацию, но и тем людям, которые в будущем будут поддерживать ваш код. Ну и избежите ненужного оверхеда 🙂

ЕДАПС и люди

Побывал я сегодня в таком замечательном месте, как “межрегиональный центр бла-бла-бла по оформлению загранпаспортов”, который находится на территории концерна ЕДАПС – крутых производителей всяческих защищённых бланков, даже для интерпола документы изготавливают.

Ездил я туда оформлять новый загранпаспорт, потому что старому осталось полгода жизни и всего 3 чистых странички.

По древней советской традиции занимать очереди задолго до открытия – я туда поехал совсем рано и прибыл к ним где-то в 7:30 утра. Возле домика охраны нашёлся листик со списком фамилий, я туда дописался третьим и пошёл в машину спать.

Где-то в 8:50 отправился я вовнутрь, а там оказалось, что листик наш никому не нужен – там поставили автомат для выдачи талонов в электрическую очередь. Подходишь, набираешь фамилию, получаешь талон с номером, садишься ждёшь. В общем стал я одинадцатым.

Моя очередь подошла где-то к 10 часам, оказалось, что кроме той макулатуры, которую я принёс по списку с веб-сайта, для действующего заграна ещё нужна была копия первой странички – 60 копеек и мне её сделали по месту.

Оформили мои документы и отправили платить в кассу. Тут начинается самое интересное 🙂

Оплатить надо 4 разных платежа, поэтому хитрый банк берёт 4 раза комиссию – по 10 грн. Госсбор 8.5, а комиссия банку 10 – прелестная прелесть.

Ещё они принимают карточки, но при этом будет ещё +2% комиссии.

Вапще в зале я заметил хитрый аппарат, который вроде как тоже принимает деньги к оплате, но на нём большими буквами написано, что он сдачу не возвращает, поэтому я побоялся к нему идти, а зря – т.к. на самом деле у меня платежей была довольно круглая сумма – 398 грн. Надо, чтобы кто-то проверил – можно ли там сэкономить 30-40 грн? 🙂

Дальше я попал в новую очередь – уже на получение моих “персональных данных” в виде фото и подписи. Когда настал мой черёд – меня посадили на стульчик перед которым прикреплён жёстко фотик и в лицо смотрит монитор, на котором дублируется информация, которую вводит тётенька – прикольно так.

В общем-то минут 5 заняла вся процедура и мне сказали, что через месяц я могу приходить за своим новым блестящим паспортом.

Чтобы сохранить старый документ – надо оплатить госсбор около 60 грн и, как мне показалось, они не очень приветствуют такое, т.е. нужно придумывать обоснование вида “у меня там действующая виза”, что в моём случае даже правда 🙂

Ещё, как я понял по соседям в очереди – если паспорт заменять, то старый не возвращают с пометками “анулирован” или как-то ещё – можно только получить выдранные странички с визами.

В сухом итоге – можно отходить от советских традиций сидеть под зданием до открытия, а сама процедура занимает около часа-двух. Но подходить лучше пораньше, т.к. если я записался 10м, то на момент, когда я уходил – очередь была длиною в 22 человека, что может вылиться в несколько часов ожидания.

Новый сайтец

Похвастаюсь, вот сделали новый дизайн нашего сайта 🙂

Политота псто

Ну это просто прелесть какая 🙂

спасибо жителям днепра

двадцать гривен