Ну как, оно умеет само реконнектиться при обрыве, но ведь это TCP… учитывая огромные таймауты по дефолту, вы можете выяснить, что с той стороны клиент уже час как отключился или сменил IP. Если данных шлёте мало (как в случае с теми же пушами), это фиаско. Происходит закрытие сокета, и тут ZMQ конечно же переподключится. Причём, не сообщив вам об этом факте (у нас же крутые бесшовные сокеты!), и вы будете думать, что все сообщения ушли, но на самом-то деле нет. Потому что ZMQ не может определить, на каком месте коннект оборвался, чтобы переотправить ваши данные, да и никто это не может.
Итого, вам нужно регулярно слать пинги (пустые пакеты в своём формате), вам нужно считать пакеты, чтобы определять потерю сообщений (это поверх TCP-то, ну!) из-за таких вот невидимых реконнектов, подтверждать получение (и опять TCP поверх TCP!) и вам нужно по таймауту этих пингов пересоздавать сокет вручную, после чего отсылать неподтверждённые сообщения заново.
Замечу, что это всё было нужно для моей задачи, и скорее всего, ZMQ просто был неверным выбором. Он больше подходит для unreliable messaging, где в принципе шлётся много данных постоянно, есть много клиентов, и если кто-то что-то не получил, то не беда, пошлём попозже. В этом случае обрывы будут определяться намного раньше, но пакеты всё равно нужно нумеровать и подтверждать, т.е. делать ту работу, которую в других системах выполняет брокер.
Технология замечательная, и документации по ней мне хватило, но только со временем обнаружилось, что «стероиды» у сокетов недостаточно абстрактные, и все прелести TCP нужно всё равно расхлёбывать руками — определять таймауты, реконнектиться, гарантии доставки сообщений нет и т.д., причём, учитывая ориентацию на сообщения (а не потоки данных) было бы абсолютно логично реализовать работу через UDP, чтобы не бодаться с проблемами TCP, но её-то как раз и не сделали. Раз уж мы всё равно не можем гарантировать доставку и вынуждены реконнектиться, почему не взять протокол, в котором изначально нет ни того, ни другого?
А я и не говорю, что это каждый должен реализовывать. Просто есть ситуации, когда это оправдано, и не стоит сразу от этой идеи отказываться, потому что всё уже сделано «как надо» вендором, и все остальные гарантированно сделают хуже.
Думаю, в iOS всё фундаментально не сильно отличается, и все перечисленные недостатки к нему также применимы. Я практически не знаком с платформой, знаю только, что Apple очень не любит колхоз-решения и будет сопротивляться попыткам пропихнуть что-то не зависимое от их инфраструктуры.
Ну я на это, в частности, и намекал. И пока вся эта чепуха с блокировками наверняка затихнет из-за вируса, но потом может возобновиться с утроенной силой, и если разработчики заранее сделают запасной сервер для пушей, они это переживут лучше. Не знаю, какие тут риски и окупаемость, но по-моему, универсальность в этом плане не помешает. Благо, интерфейс такого модуля достаточно простой должен быть, реализация масштабируемого сервера, конечно, сложнее, но может уже что-то готовое есть, не искал.
Я для приложения на работе делал решение на ZMQ (очень им тогда увлекался, но сейчас понимаю, что хватило бы и обычного HTTP). Сначала всё было как у того Сергея — выключаем оптимизацию батареи и держим коннект, ожидая данных. По части батареи не помню уже точную статистику, но потребление было достаточно малым. Когда всё уже было готово и работало, пришло время выкладываться в Play, и тут гугл подкинул свинью, зарубив приложение, мол, используйте наши штатные пуши, если только не сможете обосновать, что никак иначе нельзя. Ну понятно, что это не из-за пушей заблокировали, а из-за требования отключать оптимизацию. В общем, вышел из положения так, как написал выше — шлём пустой пуш через FCM, телефон пробуждается на 5 секунд (вроде), за это время подключаемся к серверу и получаем само сообщение.
Всё это можно организовать и со своим сервером, лишь бы руки росли правильно. Смысл в том, что сразу на корню отвергать идею собственного пуш-сервера неверно, всё зависит от задач. Завязываться на гугловский сервис для нужд, скажем, гражданской обороны, наверно, не стоит. В порядке убывания субъективной важности недостатков перечислю то, что пришло в голову.
Во-первых, библиотеки для работы с FCM проприетарные, что не позволит разместиться в F-Droid, например. Во-вторых, гугловские сервисы (GMS) тоже бывают не на всех устройствах, и нелишне иметь план Б для таких случаев. В-третьих, все эти пуши проходят, логируются и анализируются гуглом, что может быть критично с точки зрения безопасности и приватности. Последнее отчасти решаемо через передачу в пуше только метаданных, а сами данные уже грузятся при пробуждении устройства (от пуша). Но, как показала история, метаданные бывают порой намного важнее самих данных. В-четвёртых, пуши устроены сильно по-разному на Android и iOS, что требует регистрации и использования двух разных сервисов вместо единой точки (отказа, хехе).
При всём при этом, в большинстве случаев, разумеется, проще и логичнее использовать, если ваше приложение не выставляет особых требований к приватности, безопасности и надёжности (да, знаю, спорный момент — что будет надёжнее, ваш собственный сервер или гигантская инфраструктура гугла, но опять же, ситуации бывают разные), и стандартный подход к пушам на платформе для вас важнее. В конце концов, в подавляющем большинстве случаев они just work.
А расскажите, пуши как-то иначе работают? По-моему, всё именно так же, только сервер не свой, а гугла/эпла. В любом случае для этого необходимо постоянно держать сетевое подключение, иначе пуш запоздает, а «включить» интернет извне при отсутствии соединения изначально — это как себя за волосы из болота вытащить, когда ты лысый.
Я как-то подобным баловался, и точность прогноза следующей свечи получилась просто невероятная, 99.99% или в районе того. Когда порадовался и распланировал, на что буду тратить миллиарды, решил всё же разобраться. Оказалось, что я нормировал N-1 значений по среднему из N значений (последнее из которых и должна была предсказывать сеть). Сеть научилась выводить это значение из получающегося отклонения от истинного среднего между N-1 значением. Но фокус занятный получился, который ещё раз напомнил, что нейросеть — это просто такой инструмент, который (как и традиционные программы) делает не то, что ты хочешь, а то, что ты ей прикажешь. В общем, будет срезать углы максимально, лишь бы достичь результата, но необязательно тем путём, который ты ожидаешь.
Сейчас WinCIH тоже можно создать, правда, он сработает не на всех машинах. Например, 4 года назад можно было сломать UEFI, удалив определённые виртуальные файлы в линуксе.
У xargs есть отличный аргумент -P, который как раз и запускает несколько процессов параллельно. Не многопоточность, но загрузить проц до упора вполне можно. Например, для кодирования больших объёмов текста с помощью Sentencepiece или преобразования FB2 ⇒ TXT.
Да, про буст и подобное я не подумал. Всё ж считаю, что если это увеличит скорость, то оно того стоит, но не ценой подобной потери совместимости и сопутствующим геморроем. Может, придумают, как сделать мост между ABI, т.е. чтобы всё линковалось нормально, но старые программы и библиотеки вызывали функции по старым соглашениям (которые будут входить в те же библиотеки), а там стояли какие-нибудь переходники на новый ABI. Это вызовет замедление работы старого софта, конечно.
Когда libstdc++.so.6 появился (а было это в далёком от нас уже сегодня 2004м году) — расколбас был конкретный. А тогда библиотек было ещё написано куда как меньше, чем сегодня.
Так это не повод вообще не делать изменений. Так можно и про systemd рассказать, тоже был расколбас, но ничего, перетащили помаленьку. Речь ведь не о полной поломке совместимости уровня «вчера всё работало, сегодня ничего не работает», а о постепенной миграции. Никто не заставляет компилировать библиотеки самым свежим компилятором, многие до сих пор на до-одиннадцатом C++ живут по разным причинам.
Это вам хорошо рассказывать такие сказки если у вас в проекте только десяток человек и всё в одной организации. А если у вас сотни компонент от десятков вендоров, то переход растягивается на годы.
Так и пускай растягивается. У кого есть возможность, тот перейдёт. В дистрибутивах библиотеки пересоберут, если получится, а где не получится, там будет старая шестёрка использоваться. Я не знаю, можно ли будет новую и старую загружать одновременно (скорее всего, нет), и тогда да, библиотеки, собранные под разные версии стандарта вместе не уживутся, и программа, нуждающаяся в обеих, не заработает.
При любом внедрении новых несовместимых вещей должен оставаться слой совместимости для старых, тогда всё будет более-менее гладко. Если такой слой не получится сделать, тогда ломать совместимость смысла нет, само собой.
А проблема ли это? Сейчас в линуксе есть libstdc++.so.6, ну будет libstdc++.so.7 для нового C++, а параллельно останется шестая версия для старого софта со старым ABI. В Windows и подавно есть WinSxS для предоставления нужных версий библиотек каждой программе (если не ошибаюсь). Да, для legacy придётся жить со «старым» стандартом, но на то он и legacy. Не самая страшная ситуация, бывает, нужно вообще виртуалку ставить полноценную, потому что из-за слишком нового ядра и слишком старой libc вообще ничего не запускается, сразу с сегфолтом падает.
Какой же это намёк, это вполне себе популярная ироничная идиома. И сама суть программы и железа отражает её — запредельная паранойя для защиты никому, в общем-то, не нужных секретов.
В Godot ещё лучше реализовано. Но в целом да, игры — они про ограничение свобод игрока (правилами мира, сюжета и т.п.), а прикладное программирование — про расширение свобод, т.к. это инструменты для пользователя, которыми он может решать задачи, о которых разработчики даже не задумывались. Поэтому подходы действительно очень разные.
Ну как, оно умеет само реконнектиться при обрыве, но ведь это TCP… учитывая огромные таймауты по дефолту, вы можете выяснить, что с той стороны клиент уже час как отключился или сменил IP. Если данных шлёте мало (как в случае с теми же пушами), это фиаско. Происходит закрытие сокета, и тут ZMQ конечно же переподключится. Причём, не сообщив вам об этом факте (у нас же крутые бесшовные сокеты!), и вы будете думать, что все сообщения ушли, но на самом-то деле нет. Потому что ZMQ не может определить, на каком месте коннект оборвался, чтобы переотправить ваши данные, да и никто это не может.
Итого, вам нужно регулярно слать пинги (пустые пакеты в своём формате), вам нужно считать пакеты, чтобы определять потерю сообщений (это поверх TCP-то, ну!) из-за таких вот невидимых реконнектов, подтверждать получение (и опять TCP поверх TCP!) и вам нужно по таймауту этих пингов пересоздавать сокет вручную, после чего отсылать неподтверждённые сообщения заново.
Замечу, что это всё было нужно для моей задачи, и скорее всего, ZMQ просто был неверным выбором. Он больше подходит для unreliable messaging, где в принципе шлётся много данных постоянно, есть много клиентов, и если кто-то что-то не получил, то не беда, пошлём попозже. В этом случае обрывы будут определяться намного раньше, но пакеты всё равно нужно нумеровать и подтверждать, т.е. делать ту работу, которую в других системах выполняет брокер.
Технология замечательная, и документации по ней мне хватило, но только со временем обнаружилось, что «стероиды» у сокетов недостаточно абстрактные, и все прелести TCP нужно всё равно расхлёбывать руками — определять таймауты, реконнектиться, гарантии доставки сообщений нет и т.д., причём, учитывая ориентацию на сообщения (а не потоки данных) было бы абсолютно логично реализовать работу через UDP, чтобы не бодаться с проблемами TCP, но её-то как раз и не сделали. Раз уж мы всё равно не можем гарантировать доставку и вынуждены реконнектиться, почему не взять протокол, в котором изначально нет ни того, ни другого?
А я и не говорю, что это каждый должен реализовывать. Просто есть ситуации, когда это оправдано, и не стоит сразу от этой идеи отказываться, потому что всё уже сделано «как надо» вендором, и все остальные гарантированно сделают хуже.
Думаю, в iOS всё фундаментально не сильно отличается, и все перечисленные недостатки к нему также применимы. Я практически не знаком с платформой, знаю только, что Apple очень не любит колхоз-решения и будет сопротивляться попыткам пропихнуть что-то не зависимое от их инфраструктуры.
Ну я на это, в частности, и намекал. И пока вся эта чепуха с блокировками наверняка затихнет из-за вируса, но потом может возобновиться с утроенной силой, и если разработчики заранее сделают запасной сервер для пушей, они это переживут лучше. Не знаю, какие тут риски и окупаемость, но по-моему, универсальность в этом плане не помешает. Благо, интерфейс такого модуля достаточно простой должен быть, реализация масштабируемого сервера, конечно, сложнее, но может уже что-то готовое есть, не искал.
Я для приложения на работе делал решение на ZMQ (очень им тогда увлекался, но сейчас понимаю, что хватило бы и обычного HTTP). Сначала всё было как у того Сергея — выключаем оптимизацию батареи и держим коннект, ожидая данных. По части батареи не помню уже точную статистику, но потребление было достаточно малым. Когда всё уже было готово и работало, пришло время выкладываться в Play, и тут гугл подкинул свинью, зарубив приложение, мол, используйте наши штатные пуши, если только не сможете обосновать, что никак иначе нельзя. Ну понятно, что это не из-за пушей заблокировали, а из-за требования отключать оптимизацию. В общем, вышел из положения так, как написал выше — шлём пустой пуш через FCM, телефон пробуждается на 5 секунд (вроде), за это время подключаемся к серверу и получаем само сообщение.
Всё это можно организовать и со своим сервером, лишь бы руки росли правильно. Смысл в том, что сразу на корню отвергать идею собственного пуш-сервера неверно, всё зависит от задач. Завязываться на гугловский сервис для нужд, скажем, гражданской обороны, наверно, не стоит. В порядке убывания субъективной важности недостатков перечислю то, что пришло в голову.
Во-первых, библиотеки для работы с FCM проприетарные, что не позволит разместиться в F-Droid, например. Во-вторых, гугловские сервисы (GMS) тоже бывают не на всех устройствах, и нелишне иметь план Б для таких случаев. В-третьих, все эти пуши проходят, логируются и анализируются гуглом, что может быть критично с точки зрения безопасности и приватности. Последнее отчасти решаемо через передачу в пуше только метаданных, а сами данные уже грузятся при пробуждении устройства (от пуша). Но, как показала история, метаданные бывают порой намного важнее самих данных. В-четвёртых, пуши устроены сильно по-разному на Android и iOS, что требует регистрации и использования двух разных сервисов вместо единой точки (отказа, хехе).
При всём при этом, в большинстве случаев, разумеется, проще и логичнее использовать, если ваше приложение не выставляет особых требований к приватности, безопасности и надёжности (да, знаю, спорный момент — что будет надёжнее, ваш собственный сервер или гигантская инфраструктура гугла, но опять же, ситуации бывают разные), и стандартный подход к пушам на платформе для вас важнее. В конце концов, в подавляющем большинстве случаев они just work.
А расскажите, пуши как-то иначе работают? По-моему, всё именно так же, только сервер не свой, а гугла/эпла. В любом случае для этого необходимо постоянно держать сетевое подключение, иначе пуш запоздает, а «включить» интернет извне при отсутствии соединения изначально — это как себя за волосы из болота вытащить, когда ты лысый.
А как надо?
Я как-то подобным баловался, и точность прогноза следующей свечи получилась просто невероятная, 99.99% или в районе того. Когда порадовался и распланировал, на что буду тратить миллиарды, решил всё же разобраться. Оказалось, что я нормировал N-1 значений по среднему из N значений (последнее из которых и должна была предсказывать сеть). Сеть научилась выводить это значение из получающегося отклонения от истинного среднего между N-1 значением. Но фокус занятный получился, который ещё раз напомнил, что нейросеть — это просто такой инструмент, который (как и традиционные программы) делает не то, что ты хочешь, а то, что ты ей прикажешь. В общем, будет срезать углы максимально, лишь бы достичь результата, но необязательно тем путём, который ты ожидаешь.
Сейчас WinCIH тоже можно создать, правда, он сработает не на всех машинах. Например, 4 года назад можно было сломать UEFI, удалив определённые виртуальные файлы в линуксе.
Можно, но
xargs
более вероятно будет установлен из коробки. Например, в дебиане он входит вfindutils
вместе сfind
(странная группировка, по-моему).У
xargs
есть отличный аргумент-P
, который как раз и запускает несколько процессов параллельно. Не многопоточность, но загрузить проц до упора вполне можно. Например, для кодирования больших объёмов текста с помощью Sentencepiece или преобразования FB2 ⇒ TXT.Да, про буст и подобное я не подумал. Всё ж считаю, что если это увеличит скорость, то оно того стоит, но не ценой подобной потери совместимости и сопутствующим геморроем. Может, придумают, как сделать мост между ABI, т.е. чтобы всё линковалось нормально, но старые программы и библиотеки вызывали функции по старым соглашениям (которые будут входить в те же библиотеки), а там стояли какие-нибудь переходники на новый ABI. Это вызовет замедление работы старого софта, конечно.
Так это не повод вообще не делать изменений. Так можно и про systemd рассказать, тоже был расколбас, но ничего, перетащили помаленьку. Речь ведь не о полной поломке совместимости уровня «вчера всё работало, сегодня ничего не работает», а о постепенной миграции. Никто не заставляет компилировать библиотеки самым свежим компилятором, многие до сих пор на до-одиннадцатом C++ живут по разным причинам.
Так и пускай растягивается. У кого есть возможность, тот перейдёт. В дистрибутивах библиотеки пересоберут, если получится, а где не получится, там будет старая шестёрка использоваться. Я не знаю, можно ли будет новую и старую загружать одновременно (скорее всего, нет), и тогда да, библиотеки, собранные под разные версии стандарта вместе не уживутся, и программа, нуждающаяся в обеих, не заработает.
При любом внедрении новых несовместимых вещей должен оставаться слой совместимости для старых, тогда всё будет более-менее гладко. Если такой слой не получится сделать, тогда ломать совместимость смысла нет, само собой.
А проблема ли это? Сейчас в линуксе есть libstdc++.so.6, ну будет libstdc++.so.7 для нового C++, а параллельно останется шестая версия для старого софта со старым ABI. В Windows и подавно есть WinSxS для предоставления нужных версий библиотек каждой программе (если не ошибаюсь). Да, для legacy придётся жить со «старым» стандартом, но на то он и legacy. Не самая страшная ситуация, бывает, нужно вообще виртуалку ставить полноценную, потому что из-за слишком нового ядра и слишком старой libc вообще ничего не запускается, сразу с сегфолтом падает.
Какой же это намёк, это вполне себе популярная ироничная идиома. И сама суть программы и железа отражает её — запредельная паранойя для защиты никому, в общем-то, не нужных секретов.
Так и про «без названия» лукавство, написано же — Tinfoil Chat.
В Godot ещё лучше реализовано. Но в целом да, игры — они про ограничение свобод игрока (правилами мира, сюжета и т.п.), а прикладное программирование — про расширение свобод, т.к. это инструменты для пользователя, которыми он может решать задачи, о которых разработчики даже не задумывались. Поэтому подходы действительно очень разные.
А в игре как раз C++
Тут не посоветую, сам пишу на Java/C++ и в качестве сервера использую Lighttpd.