Меня зовут Артур Валиев. За последнее время я сделал несколько проектов на Rust + Iced, которые со стороны действительно можно принять за отдельные программы. EvertyDesk Next — удалённый доступ. EvertyDisplay — виртуальные мониторы. EvertyCloud — облачные и сетевые диски.
Но я всё меньше воспринимаю их как три разных продукта.
На самом деле это одна система.
И сегодня я хочу наконец объяснить, что именно я пытаюсь построить.
Моя мысль довольно простая: компьютер не обязан заканчиваться там, где заканчивается его корпус.
EvertyDesk Next: сначала я убрал расстояние
EvertyDesk начинался с обычной задачи удалённого доступа. Есть компьютер здесь, есть компьютер где‑то ещё, и между ними нужно построить соединение.
На уровне пользователя всё выглядит просто: ID, пароль, подключение.
Но под этой кнопкой находится всё то, о чём мы так любим спорить как разработчики: TCP, UDP, NAT, relay, проброс соединений, потери пакетов, задержки, кодеки, восстановление состояния, управление качеством, безопасность.
Я довольно долго занимался именно этой частью.
Появился EVRTCK, потом эксперименты с транспортом, предсказанием изображения, dirty regions, приоритетами областей экрана. Потому что удалённый рабочий стол на самом деле — это не «показать картинку».
Нужно сделать так, чтобы человек перестал замечать расстояние.
Пока пользователь двигает курсор и ждёт две секунды, никакой магии нет.
Когда он перестаёт думать о том, где физически находится компьютер, начинается уже что‑то интересное.
Но одна вещь продолжала меня раздражать.
Почему удалённый компьютер вообще должен находиться в окне?
EvertyDisplay: потом я убрал границу монитора
Так появился EvertyDisplay.
Когда я впервые рассказывал о нём, саму концепцию приняли довольно холодно. Зато произошло куда более важное: люди начали пользоваться функциональностью и писать мне, что она им реально пригодилась.
Для разработчика это, пожалуй, лучший возможный ответ.
EvertyDisplay создаёт виртуальные дисплеи, которые Windows воспринимает как настоящие мониторы.
У меня, например, стоят два физических монитора.
Я могу создать третий виртуальный экран слева.
Windows видит:
[ Virtual Display ] [ Monitor 1 ] [ Monitor 2 ]
Я двигаю курсор за левую границу физического экрана — он уходит туда.
Перетаскиваю окно — оно уходит следом.
Можно задать разрешение, положение, ориентацию, расположить виртуальный дисплей сверху, снизу, справа, слева.
И если смотреть только на этот функционал, EvertyDisplay действительно можно принять за отдельную программу для виртуальных мониторов.
Но это не вся идея.
EvertyDisplay — часть системы EvertyDesk Next.
Самое интересное находится в том месте, где виртуальный дисплей начинает получать изображение не от локального приложения, а от удалённой машины через EvertyDesk и EVRTCK.
И тогда происходит довольно странная вещь.
Удалённый рабочий стол перестаёт быть окном.
Представим:
[ Remote PC ] [ Local Monitor 1 ] [ Local Monitor 2 ]
Слева физического монитора у меня расположен экран удалённого компьютера.
Я двигаю мышь влево.
И вместо того чтобы упереться в границу монитора или переключиться в окно клиента удалённого доступа, я просто оказываюсь на другом компьютере.
Для Windows это монитор.
Для EvertyDesk — удалённая сессия.
Для EVRTCK — поток изображения и событий ввода.
А для человека это просто продолжение рабочего пространства.
Вот здесь EvertyDesk Next и EvertyDisplay перестают быть двумя программами.
EvertyDesk убирает расстояние до компьютера.
EvertyDisplay убирает границу между его рабочим столом и моим.
И мне кажется, именно в этой точке становится понятно, куда всё это идёт.
Но оставалась ещё одна граница.
Файлы.
EvertyCloud: теперь я хочу убрать понятие «где лежит файл»
Сегодня я рассказываю о третьем проекте.
EvertyCloud.
Формально EvertyCloud — нативный кроссплатформенный клиент для облачных хранилищ и сетевых дисков, написанный на Rust с интерфейсом на Iced.
В качестве протокольного движка внутри используется rclone.
Это важно.
Я не хочу писать заново клиенты для S3, WebDAV, FTP, SFTP, SMB, Google Drive, Dropbox и ещё нескольких десятков систем. Эту задачу rclone уже решает прекрасно.
Поэтому EvertyCloud находится уровнем выше.
Он собирает разные хранилища в одну рабочую среду.
Яндекс.Диск.
Mail.ru Cloud.
S3.
WebDAV.
FTP.
SFTP.
SMB.
Локальные каталоги.
Подключённые через rclone Google Drive, Dropbox, OneDrive, Box, MEGA, pCloud, Azure Blob, Backblaze B2.
Для пользователя всё это становится дисками и папками.
Можно просматривать файлы, создавать каталоги, загружать и скачивать данные, копировать пути, использовать избранное, работать с несколькими представлениями, искать, сортировать, монтировать remote как диск операционной системы.
Но мне особенно нравится одна операция.
Копирование между двумя облаками без локального промежуточного файла.
Допустим, файл лежит в S3.
Я хочу перенести его на WebDAV.
Обычная бытовая логика говорит:
S3 -> мой компьютер -> WebDAV
Но зачем?
Почему мой компьютер должен физически становиться промежуточным складом?
Я хочу сказать:
S3 -> WebDAV
А моя машина должна только управлять операцией.
И здесь EvertyCloud продолжает ту же идею, которая была в EvertyDesk и EvertyDisplay.
Мы слишком часто показываем человеку физическую архитектуру системы как часть интерфейса.
Файл находится далеко — значит его надо сначала скачать.
Компьютер находится далеко — значит его надо открыть в отдельном окне.
Монитора физически нет — значит туда нельзя перенести окно.
А почему?
Это не законы вычислительной техники.
Это просто привычки интерфейсов.
EvertyCloud + EvertyDesk Next
Но подключение Яндекс.Диска или S3 — это даже не самая интересная часть EvertyCloud.
Самое интересное начинается, когда EvertyCloud встречается с EvertyDesk Next.
Представим компьютер, на котором уже работает EvertyDesk Next.
У него есть ID.
Есть постоянный пароль.
Через этот ID я могу открыть удалённый рабочий стол.
Но почему тем же способом нельзя открыть его файлы?
Так появился прямой EvertyDesk remote внутри EvertyCloud.
Пользователь добавляет новое подключение, вводит ID удалённого компьютера и пароль.
EvertyCloud использует транспортный клиент из ядра EvertyDesk Next, устанавливает защищённую сессию и поднимает туннель к небольшому WebDAV‑серверу на удалённой машине.
После этого локальный rclone получает адрес вроде:
127.0.0.1:45831
И для него это обычный WebDAV.
Он вообще не обязан знать, что за этим адресом находится NAT traversal, relay, защищённая сессия EvertyDesk и другой компьютер где‑то в интернете.
Получается довольно красивая архитектура.
EvertyDesk отвечает за соединение.
EvertyCloud отвечает за файлы.
rclone отвечает за файловый протокол.
И ни один слой не обязан знать слишком много о другом.
Пользователь же видит просто диск.
И вот теперь можно сделать следующий шаг
Представим маленький офис.
Двадцать компьютеров.
На каждом установлен EvertyDesk Next.
Обычные рабочие машины.
Бухгалтерия.
Менеджеры.
Администратор.
Ноутбуки.
Компьютер директора.
И теперь в настройках EvertyDesk появляется переключатель:
Выделить для EvertyCloud: 10 ГБ
Двадцать компьютеров.
По десять гигабайт.
Получается 200 ГБ сырого пространства.
И вот тут начинается уже совсем другая история.
Я не хочу просто взять и склеить эти двадцать дисков.
Если один компьютер выключится, классический подход довольно быстро станет неприятным.
Здесь узлы ненадёжны по определению.
Ноутбук могут закрыть.
Компьютер могут перезагрузить.
Кто‑то уйдёт домой.
У кого‑то пропадёт интернет.
Один узел доступен напрямую.
Другой только через relay.
У третьего гигабитная сеть.
У четвёртого старый Wi‑Fi.
Это не RAID в классическом понимании.
Но зеркальный RAID — хорошая аналогия, чтобы объяснить идею.
Файл разбивается на блоки.
Блоки шифруются.
И затем раскладываются с избыточностью между компьютерами.
Например:
FILE A
├── block 01 -> PC-03 / PC-11 / PC-18
├── block 02 -> PC-01 / PC-06 / PC-14
├── block 03 -> PC-05 / PC-09 / PC-17
└── block 04 -> PC-02 / PC-12 / PC-20
Один компьютер выключили.
Файл существует.
На другом умер диск.
Файл существует.
Третий ноутбук уехал домой.
Файл всё ещё существует.
Каждый узел хранит только зашифрованные блоки.
Не документ.
Не фотографию.
Не базу.
Просто бинарные куски, которые без метаданных, ключей и остальных частей не имеют смысла.
А EvertyCloud знает, как собрать их обратно.
И вот здесь слово «облако» внезапно начинает нравиться мне намного больше.
Потому что это действительно облако.
Не сервер компании X.
Не конкретный жёсткий диск.
Не IP‑адрес.
Это ресурс, физическое расположение которого перестаёт иметь значение.
И снова TCP
Здесь обычно заканчивается презентация продукта и начинается разработка. Нарисовать 20 PC → Distributed Storage можно за пять минут. А потом выясняется, что один из двадцати компьютеров доступен с RTT 8 мс, второй — 70 мс, третий сидит за CGNAT, четвёртый ушёл через relay, а пятый начал терять пакеты. И внезапно простой вопрос «где хранить следующий блок?» становится совсем не простым.
Если отправлять всё через TCP, мы получаем надёжность, контроль порядка и прекрасную абстракцию потока. Одновременно получаем и все свойства TCP, которые особенно хорошо становятся заметны на плохой сети: потерялся сегмент — следующие данные уже могли физически прийти, но приложение ждёт восстановления последовательности. Для копирования большого архива это зачастую нормально. Для интерактивной системы и распределённого планировщика — уже не всегда.
И я снова оказываюсь примерно там же, где когда‑то оказался с EvertyDesk. TCP или UDP? Когда надёжность важнее задержки? Как распределять параллельные потоки? Нужен ли собственный transport scheduler? В какой момент реплика считается записанной? Что делать, если узел исчез посередине операции? Имеет ли смысл банальное зеркалирование или пора смотреть в сторону Reed‑Solomon и erasure coding? Как выбирать машину для следующего блока: по свободному месту, latency, uptime, доступности, типу соединения, стоимости relay или даже по вероятности того, что два компьютера физически находятся в одном помещении и однажды одновременно пропадут из сети?
Вот за это я и люблю разработку. Идея продукта обычно заканчивается довольно быстро. Потом начинается компьютерная наука.
Облако не должно доверять клиенту
Рядом с распределением данных сразу возникает второй вопрос — безопасность. Уже сейчас EvertyCloud построен так, чтобы по возможности вообще не становиться владельцем лишних секретов. Конфигурацией провайдеров владеет rclone. EvertyCloud не читает и не сериализует содержимое rclone.conf, пароли и OAuth‑токены не складываются в profiles.json, а проверка нового подключения выполняется через временную изолированную конфигурацию, которая удаляется после теста. Текст ошибок очищается от введённых секретов, удаление remote не означает удаление файлов, а пароль от EvertyDesk‑подключения намеренно не сохраняется.
Мне нравится простой принцип: если компоненту не нужен секрет — компонент не должен его знать.
В распределённом хранилище этот принцип становится ещё важнее. Компьютер, который выделил EvertyCloud свои 10 ГБ, вообще не обязан понимать, что хранится на его диске. В идеальной архитектуре он даже не должен знать, какие блоки относятся к одному файлу. Для него интерфейс может быть почти примитивным: blob_id → bytes. Получил идентификатор, сохранил массив байтов, отдал его обратно по запросу.
Потому что лучший способ защитить данные от участника системы — не требовать от него честности. Лучше спроектировать систему так, чтобы ему просто нечего было интерпретировать.
В EvertyCloud уже пришлось встретиться с реальностью Windows
Особенно забавно, когда строишь облачную систему, а проблема в итоге оказывается вообще не в облаке. Один такой случай у меня уже был.
В EvertyCloud можно добавить локальный remote через rclone alias. Если этот alias указывал на UNC‑путь вроде \servershare, в определённых условиях приложение могло зависнуть. Первая реакция очевидная: сеть подвисла, значит поставим timeout. Ставишь timeout rclone — не помогает. Потому что завис rclone вообще не на сетевом запросе. Поток сидит внутри Windows, например в GetFileAttributesExW, а дальше начинаются DFS, MUP и резолвер сетевой файловой системы. Если управление уже ушло туда, красивый таймаут, который ты передал rclone, ситуацию не спасёт.
В итоге вокруг процесса пришлось строить нормальную защиту: сериализацию метаданных для одного remote, singleflight для одинаковых параллельных запросов, жёсткий deadline, гарантированное завершение дерева процессов через Windows Job Object и circuit breaker, который после обнаружения зависшего UNC некоторое время вообще не даёт приложению снова долбиться в проблемный путь. А UNC для локального alias я в итоге просто запретил в мастере и предлагаю использовать нормальный SMB backend.
В документации архитектура выглядит красиво: App → rclone → Storage. В реальности иногда получается что‑то вроде App → rclone → Windows → DFS → MUP → ???, после чего ты некоторое время смотришь на зависший процесс и пытаешься понять, почему твой таймаут никого не впечатлил.
Это хороший пример того, чем реальный продукт отличается от схемы на салфетке.
Почему Rust + Iced
Все три проекта постепенно оказались в одном технологическом пространстве: Rust, Iced, общее ядро и похожие инженерные подходы. EvertyDesk Next работает с машинами и транспортом, EvertyDisplay — с пространством экранов, EvertyCloud — с пространством данных.
Мне нравится Rust здесь не потому, что «Rust быстрый». Это слишком поверхностное объяснение. Я строю систему, в которой одновременно живут сеть, процессы, файловые системы, шифрование, фоновые задачи, состояния подключений, монтирование дисков, удалённые машины, таймауты, кеши, GUI и жизненный цикл десятков ресурсов. То есть почти всё то, где плохо контролируемое состояние очень быстро превращается в очень хорошо контролирующую тебя боль.
Поэтому Rust здесь для меня довольно естественный выбор. А Iced позволяет не тащить рядом ещё один технологический мир только ради интерфейса. В результате EvertyDesk Next, EvertyDisplay и EvertyCloud могут не просто одинаково выглядеть, а постепенно становиться частями одной архитектуры.
EvertyID
Ещё одна вещь, которая связывает всё вместе, — EvertyID. Один аккаунт, одна система идентификации, одни права и постепенно одна экосистема: EvertyDesk, EvertyDisplay и EvertyCloud.
EvertyCloud уже использует device authorization flow: приложение показывает код, пользователь подтверждает вход в браузере, клиент получает токен, проверяет его через JWKS и затем получает свои entitlements. На первый взгляд это самая скучная часть всей истории. OAuth, токены, права доступа — инфраструктура.
Но именно такая инфраструктура однажды позволяет открыть приложение и сказать: вот мои компьютеры, вот мои удалённые рабочие пространства, вот мои виртуальные дисплеи, вот мои облака, вот сетевые диски, вот компьютеры организации, которые предоставляют часть своего хранилища.
И всё это принадлежит не отдельной программе. Это принадлежит пользователю.
Три проекта на самом деле решают одну задачу
Я долго не формулировал это настолько прямо, но сейчас картина для меня выглядит очень просто: EvertyDesk Next убирает физическое расстояние между компьютерами. EvertyDisplay убирает физическую границу между рабочими столами. EvertyCloud убирает физическую привязку данных к конкретному диску.
Условно это можно представить так:
EvertyDesk Next → компьютеры
↓
EvertyDisplay → пространство
↓
EvertyCloud → данные
↓
EVERTY
Это, конечно, не означает, что завтра я напишу распределённый Dropbox на двадцати офисных компьютерах и объявлю задачу закрытой. Скорее наоборот: как только начинаешь всерьёз думать о такой системе, перед тобой появляются консистентность, репликация, шифрование, версионирование, split brain, кворумы, garbage collection, erasure coding, восстановление узлов, bandwidth scheduling, TCP/UDP, relay, offline nodes, метаданные, snapshots, конфликты и ещё десятки вещей, о существовании которых ты узнаёшь обычно в самый неподходящий момент.
Но именно поэтому идея мне и нравится.
Мне не нужен ещё один облачный диск
Если бы целью EvertyCloud было просто открыть Яндекс.Диск в красивом интерфейсе, я бы, скорее всего, вообще не стал его писать. Таких программ достаточно.
Мне интересно другое. Я хочу открыть файловый менеджер и постепенно перестать задаваться вопросами: этот файл локальный или лежит в S3? Эта папка находится на NAS или на компьютере через EvertyDesk? Файл хранится целиком на одном сервере или разбит на блоки между семью машинами?
Пусть этим занимается система.
С сетью это уже произошло. Открывая сайт, я не думаю, через какие автономные системы и маршрутизаторы прошёл пакет. С виртуальной памятью произошло то же самое: большинство программ не размышляет, в какой конкретно физической ячейке RAM сейчас лежит значение. Между физическим устройством и нашим представлением о ресурсе давно существуют уровни абстракции.
Почему тогда человек до сих пор должен настолько хорошо понимать физическую географию собственных файлов?
Мне кажется, со временем не должен.
Может быть, «персональный компьютер» пора понимать иначе
Когда‑то персональный компьютер действительно был коробкой: внутри процессор, память и диск, рядом монитор, перед ним человек. Эта модель до сих пор очень глубоко сидит у нас в голове.
Технически она давно перестала быть обязательной. CPU может находиться в другой машине, GPU — на сервере, файл — в S3, экран — быть виртуальным, приложение — исполняться удалённо, а хранилище вообще может состоять из двадцати физических компьютеров. И при этом для человека всё это способно оставаться одной рабочей средой.
Поэтому я всё меньше воспринимаю Everty как набор отдельных программ. Мне гораздо интереснее рассматривать его как попытку собрать персональный компьютер, который больше не совпадает с физическим компьютером.
У него могут быть удалённые процессоры, чужие рабочие столы, виртуальные мониторы, распределённые диски и облака разных компаний. Но человек не должен смотреть на это как на инфраструктуру. Перед ним должен оставаться его компьютер.
И снова здравствуйте
С EvertyDesk я полез в удалённый доступ и довольно быстро оказался внутри TCP, UDP, relay и кодеков. С EvertyDisplay я решил сделать виртуальный монитор и пришёл к мысли, что удалённый рабочий стол вообще не обязан быть окном. С EvertyCloud я вроде бы просто хотел сделать удобный клиент для облачных хранилищ — и почему‑то снова оказался перед распределённой системой из двадцати компьютеров.
Похоже, у меня действительно плохо получается делать маленькие программы.
Поэтому снова здравствуйте. Я Артур Валиев. Это EvertyCloud.
А дальше мы, похоже, опять будем обсуждать TCP и UDP.
На этот раз я не буду отвечать больше на провоцированные комментарии, я своим трио заявил право первой брачной ночи.
V.
Автор: vaalimusic


