Архив рубрики: Всячина

Всякое

Проталкивание stream сообщений от асинхронного grpc сервиса (c++)

Код GRPC содержит пример асинхронного сервиса с потоком сообщений от сервиса клиенту. В нем сервис отправляет сообщения клиенту по одному методом респондера Write() из массива, а когда все элементы массива оказываются отправлены, сервис вызывает метод респондера Finish().

В асинхронном сервисе GRPC использует очередь респондеров. Респондер- это объект, который может взаимодействовать с очередью- а именно, самостоятельно размещаться в очереди после завершения операций чтения/записи Read()/Write(), которые асинхронны. Поскольку RPC вызов включает в себя, как правило, и Read(), и Write(), то есть он выполняется за несколько проходов в очереди, объект из очереди должен хранить свое состояние. Когда все взаимодействие с клиентом завершается, объект нало уничтожить.

Мне нужно было реализовать RPC с потоком сообщений от сервиса клиенту, которые сначала отправлялись сразу, как в примере, а после этого, по мере возникновения событий на сервере отсылались клиенту бесконечно (пока клиент не разорвет связь). Эти события могут произойти в любое время, или вовсе не произойти. Так как события нечастые, реализовывать синхронные сервис показалось накладным. Я не нашел примеров, как это делать, поэтому пишу тут, как можно это реализовал.

Отдельный поток (thread) ждет наступления события, и, когда это происходит, нужно вызвать метод Write() респондеров. В сервисе при вызове такого «долгоиграющего» метода респондеры записываются в массив. Массив, таким образом, хранит «коннекты» клиентов.

Первая, неудачная реализация непосредственно вызывала методы Write() респондеров из отдельного потока. Это работало, но тогда, когда клиент разрывал соединение, из-за гонки при иногда объект с респондеров успевал уничтожиться между временем, когда обхект с респондером был размещен в очереди, но очередь до него не дошла, а раньше, сработало событие отключения, которое уничтожило объект респондера.

Кроме того, может произойти assert в методе респондера Write(), когда два потока одновременно его вызовут.

Вторая реализация- это использование мьютексов для защиты.

Третья реализация выглядит лучше- она не использует мьютексы, а использует саму очередь. Идея в том, что очередь выполняется последовательно, что и обеспечивает защиту. Это также предотвратит неожиданный assert в методе респондера Write(), когда два потока одновременно его вызовут.

Для этого в момент события в очередь размещается объект-«планировщик очереди». Этот объект, когда до него дойдет очередь, выполняет работу по размещению в очередь респондеров клиентов для извещения . Теперь, если какой-то клиент отвалится, очередь на уничтожение связанного респондера будет выполнена позже респондеров для извещения, и сервис не упадет.

В коде ниже показано, что в методе, отвечающим клиенту на RPC запрос, когда все накопленные ранее сообщения отправлены, вместо вызова Finish() респондера указатель на респондер записывается в массив указателей на респондеры, ждущие события вызовом preorderService->clientsListenOrders.put(this);.

void ListenOrderData::Proceed(bool successfulEvent) {
  switch (status) {
  case CREATE:
    status = LISTEN_ORDERS;
    service->Requestlistenorder(&ctx, &rq, &responder, cq, cq, this);
    break;
  case LISTEN_ORDERS:
    if (!new_responder_created) {
      new ListenOrderData(preorderService);
      new_responder_created = true;
      preorderService->clientsListenOrders.put(this);
      break;
    }

    if (!hasData) {
      status = FINISH;
      preorderService->clientsListenOrders.rm(this);
      responder.Finish(grpc::Status(), (void*) this);
      break;
    }
    responder.Write(result, (void*) this);
    hasData = false;
    status = LISTEN_ORDERS_SENT;
    break;
  case LISTEN_ORDERS_SENT:
    status = LISTEN_ORDERS;
    break;
  case FINISH:
    delete this;
    break;
  }
}

Член hasData нужен, чтобы различать «нормальное» событие от события отсоединения клиента.

Чтобы ловить событие отсоединения, нужно указать GRPC (например, в конструкторе объекта с респондером ListenOrderData), что нужно эти события отлавливать:

ctx.AsyncNotifyWhenDone(this);

Когда уничтожается респондер (объект, его содержащий), нужно удалить из массива ссылку на респондер (или его содержащий объект), это можно сделать в деструкторе, или в Proceed(successful)

Замечание 1: Параметр successful = false указывает на то, что не было чтения или записи, или они завершились ошибкой.

Замечание 2: метод ctx.IsCancelled() указывает, было ли разорвано соединение. Вызвать его можно только после ctx.AsyncNotifyWhenDone(), иначе сервис упадет.

Все хорошо, но, оказывается нельзя просто так взять и добавить в очередь объект.

К счастью есть способ обойти это. используя grpc::Alarm:

alarm.Set(cq, gpr_now(gpr_clock_type::GPR_CLOCK_REALTIME), this);

С помощью этого трюка можно выполнить вставку в очередь объекта, который вставит другие объекты в очередь.

rtl8811ac WiFi USB stick

I got Wi-Fi USB stick (from Aliexpress) with Realtek 8811 chip.

In Linux (Ubuntu 16.04) I turn USB mode from the CD-ROM with Windows setup program to Wi-Fi network card mode using usb_modeswitch.

And, of course I need to install driver itself.

1. Install driver rtl8821/8811:

  • git clone https://github.com/brektrou/rtl8821CU.git
  • cd rtl8821CU
  • make
  • sudo make install

2. Install sub_modewitch with patch:

  • git clone https://gitlab.com/mikhailnov/usb_modeswitch.git
  • cd usb_modeswitch
  • cd usb-modeswitch-data
  • sudo make install
  • cd ..
  • cd usb-modeswitch
  • make
  • sudo ./usb_modeswitch -W -v 0bda -p 1a2b

3. Restart desktop:

  • sudo shutdown -r now

After the system kernel is updated, you need to reinstall the rtl8821CU driver.

  • cd rtl8821CU
  • make clean; make
  • sudo make install

Параллакс-эффект на изображениях и видео с картой глубины в зависимости от положения зрителя относительно двумерной картинки

11 июля 2019 г.

Камеры глубины (Microsoft Kinect, iPhone X, Huawei P30 [“3D фото”], линейка камер Intel) позволяют создавать видео с картой глубины [habr] с небольшим потреблением вычислительных ресурсов, в сравнении с алгоритмами получения карты глубины со стереопары (opencv).

Поэтому возможен рост контента с псевдо-стерео изображением.

Отображение 3D контента без очков существует, но пока не массово [обзор] и требует специальных мониторов с разделением изображения на два глаза, к тому же желательно знать расположение зрителя относительно экрана, что требует датчиков положения зрителя.

Все больше медиа потребляется на мобильных  устройствах, на которых нельзя ожидать появления экранов для стереоизображений в ближайшее время. Мобильные устройства можно наклонять (гиросокопы, акселерометры), примеры 3D parallax wallpaper на мобильных можно видеть здесь [youtube].

Предположительно, не все люди видят стереоскопически, особенно вдали- трехмерная картинка на большой глубине создается не оптически, а на основе опыта. Также большая часть людей лучше замечают движущиеся объекты. Поэтому динамическое изменение положения или угла зрения зрителя относительно видимой картинки создает иллюзию трехмерного изображения с эффектом параллакса. Это называется 2d-3d преобразованием или псевдостерео [технология] и применяется, например, для создания стерео календариков. Во всяком случае вау эффект какое время возможен.

Что можно сделать?

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

Это не полноценное 3d (псевдо-стерео), углы обзора будут ограничены и заглянуть за экран очень силно не получится.

Но этого достаточно для создания эффекта параллакса наклонами и применения эффектов, как размытие фона, и может быть в ближайшем будущем массово генерироваться новыми мобильными камерами.

Возможное применение- видео контент (фильмы, ролики), видеочаты, IM, пользовательский интерфейс с “3D” кнопками и другими элементами управления.

Форматы картинок можно дополнить слоем глубины, можно делать баннеры с эффектом параллакса в формате png, например, при поддержке браузером или плагином браузера.

Форматы видео можно, например, дополнить отдельными картами глубины (в отдельных файлах gray scale, как субтитры).

Программное обеспечение с датчиков или вручную пересчитывает картинку, создавая эффект параллакса, меняет фокус камеры (размывает изображение не в фокусе).

GUI использует Z индекс для отрисовки преркоывающихся областей. Виджеты (элементы интерфейса) могут иметь разную высоту, что может быть задано в guideline, как, например, в material design все виджеты имеют высоту 1dp.

Модификация GUI библиотек, тулкитов, и высоту виджетов с добавлением высоты виджетов может быть сделана для получения параллакс эффекта и теней пир изменении положения зрителя.

Facebook 3d photo [видео] [как сделать]


wacs: wireless access control system

Даже при выключенном WiFi многие iPhone и часть Android смартфонов обнаруживаются точками доступа, в том числе Soft AP, поскольку смартфоны активно сканируют точки доступа, посылая пакеты Probe Request, независимо от того, включен или выключен Wi-Fi на телефоне.

Это делается, в частности, для того, чтобы делать быстрое подключение к точке доступа при включении Wi-Fi, так как отправка Probe Request и получение ответов от точек доступа не потребляет много энергии, но делает включение Wi-Fi быстрым и приятным.

wacs — wireless access control system. Wire man (c) 2018 Алексей Егоров, проволока.

Программная точка доступа hostapd очень популярна, установлена она и в Android телефонах, чтобы раздавать Интернет по Wi-Fi.

WiFi USB stick (on the left)

Вставляем в USB порт Wi-Fi свисток, устанавливаем и настраиваем hostapd и начинаем смотреть журнал hostapd.

В журнале hostapd фиксируются пакеты Probe Request- видны MAC адрес устройства и уровень сигнала.

В результате набирается довольно много статистики по производителям, помимо телефонов, есть какие-то изделия Ford Motors Company, и очень экзотичные устройства, для чего они предназначены, трудно догадаться.

По реестру IEEE с помощью скрипта определяется производитель телефона, но не всегда. Лучше всего с этим у Samsung.


Небольшое изменение в hostapd (его придется собрать из исходов) позволяет передать событие, когда мобильное устройство отправляет пакет discovery, в другую программу.

В небольшом open source проекте https://gitlab.com/commandus/wacs событие передается другим процессам по TCP или через shared memory с использованием библиотеки nanomsg, чтобы сделать какую-нибудь полезную его обработку.

Очевидное применение, это отслеживать присутствие людей в радиусе действия точки доступа.

Видны два пика активности- начало рабочего дня его окончание

Присоединяйтесь к open source проекту.

Android NotificationListener service cache bug

В новом приложении Уведомления для PC я столкнулся с такой проблемой- сервис, который должен получать уведомления из статусбара, их не получал.

Причина оказалась в том, что Андроид не отслеживает завершение работы сервиса, и при повторном запуске не делает bind сервиса, поэтому, по идее, могли бы помочь перезагрузка телефона, удаление и повторная установка из магазина придожения.

Мне помогло только переименовывание имени класса сервиса ;(

Что будет происходить, если система будет останавливать сервис приложения, или приложение будет крэшиться?

Ошибки «numpad» хеша

Ошибки «numpad» хеша (http://uri2dec.sourceforge.net/) — 6% по списку доменов в зоне .com на 2015 год.

На графике по оси абсцисс- число попадания имен в зоне .com в хеш, по оси ординат- число доменных имен. Для 94% доменных имен хеш не дает ошибок.

distribution