В современном мире обмен сообщениями происходит практически мгновенно благодаря множеству централизованных сервисов и приложений, от популярных мессенджеров до корпоративных платформ. Однако нередко важна именно независимость от центральных серверов, возможность работы оффлайн и гарантия того, что при синхронизации между устройствами сохраняется корректный порядок сообщений. Именно эти задачи решаются при помощи концепции CRDT — Conflict-free Replicated Data Types, или конфликтно-свободных реплицируемых структур данных. CRDT — это класс структур данных, разработанных для того, чтобы поддерживать согласованное состояние данных на разных устройствах, даже при одновременных изменениях и без центрального администратора. Главное их преимущество — гарантированное слияние данных таким образом, чтобы обеспечить консистентность и согласованность на всех узлах сети.
Простыми словами, CRDT позволяют разным устройствам независимо вносить изменения, а затем после синхронизации все они окажутся в одном и том же состоянии. Создать полноценный мессенджер на CRDT кажется сложной задачей, тем более если использовать популярные языки программирования и фреймворки. Но оказывается, что эффект CRDT можно добиться при помощи минимального по размеру Bash-скрипта всего в 12 строк, используя простейшую методику записи сообщений в файлы с уникальными именами и синхронизацию этих файлов через облачные сервисы или локальные утилиты. Идея решения базируется на использовании уникальных идентификаторов UUID для имен файлов, в которых хранятся текстовые сообщения. Каждый раз, когда пользователь вводит новое сообщение и нажимает Enter, создаётся новый файл с именем в формате UUID, в который сохраняется содержимое сообщения.
Таким образом, исключается возможность конфликта имен файлов между несколькими машинами. Поскольку каждая машина пишет свои сообщения в отдельные файлы, синхронизация этих файлов между устройствами обеспечивает консистентность переписки. Для вывода сообщений используется простая функция, которая очищает экран и выводит последние 30 сообщений, отсортированных по времени создания или модификации файла. Это гарантирует, что все участники видят историю диалога в одном и том же порядке, независимо от того, когда и на каком устройстве были созданы сообщения. При этом цветная подсветка имени пользователя в командной строке делает интерфейс более наглядным и удобным.
Что касается самой синхронизации, её обеспечивает сторонняя программа или сервис, например, Syncthing, Dropbox, Google Drive или даже rsync. Программа выполняет регулярный обмен файлами и следит за появлением новых. Особенность подхода в том, что в системе не используется централизованный сервер, нет единой базы данных или очереди сообщений. Вместо этого каждое устройство играет равнозначную роль, создавая и получая сообщения через синхронизируемую папку. Такая архитектура существенно повышает отказоустойчивость и приватность.
Плюс такого решения — возможность писать сообщения в оффлайне и затем автоматически получить их на всех устройствах после возобновления подключения. Это особенно полезно в условиях нестабильного интернета или при удалённой работе на нескольких компьютерах. Кроме того, система сама по себе проста, не требует установки сложного программного обеспечения, и её можно развернуть в считанные минуты. Разумеется, данный мессенджер не претендует стать заменой крупным корпоративным платформам или Discord, он представляет собой скорее эксперимент, наглядный пример практического применения CRDT и минимализма в программировании. Тем не менее его потенциальные применения выходят далеко за рамки обмена сообщениями.
Например, та же методика может быть использована для создания распределённого трекера времени, счётчика задач или других инструментов, которые требуют точного учёта и синхронизации изменений между несколькими устройствами. При работе с данным методом есть и определённые ограничения. Основное из них — невозможность редактирования или удаления сообщений напрямую. Поскольку каждое сообщение — это отдельный файл с уникальным именем, его нельзя просто взять и изменить без нарушения принципов согласованности. Однако выход из этой ситуации существует — создание дополнительных файлов, которые помечают определённые сообщения как удалённые или отредактированные.
Это реализуется, например, через положительно-отрицательные счётчики, где создаются дополнительные записи с указанием удаления или запроса на изменение конкретного сообщения. Такая схема сохраняет свойства CRDT и гарантирует, что все устройства согласятся по окончании синхронизации. Технические детали работы скрипта просты и понятны. Путь к папке для хранения сообщений создаётся автоматически, если его не существует. Запуск процессе наблюдения за изменениями в папке осуществляется с помощью утилиты watchexec, которая на Linux и Termux может отслеживать изменения файлов и вызывать функцию обновления интерфейса.
При отсутствии watchexec можно использовать альтернативу fswatch, хотя она имеет небольшие нюансы в работе при старте. Важно отметить, что для повышения скорости синхронизации при работе с Syncthing рекомендуется настроить параметр fsWatcherDelayS в конфигурации сервиса, установив минимально возможное значение. Это снизит задержки в распространении сообщений между устройствами и сделает общение более оперативным. В результативном плане система демонстрирует пример того, как базовые компоненты — пару команд Bash, утилиты для генерации UUID и любой сервис синхронизации файлов — позволяют создать распределённый чат со всеми основными преимуществами CRDT и никакими сложностями с развёртыванием и поддержкой. Этот подход вдохновляет на мысль, что сложные распределённые системы можно реализовывать не только с помощью мощных баз данных и микросервисов, но и используя минималистичные инструменты.
Это открывает пространство для инноваций и новых решений, которые эффективны, адаптивны и весьма просты в понимании и применении. Концепция CRDT зарекомендовала себя как фундамент для множества современных приложений, в том числе в таких крупных компаниях, как Microsoft и Facebook, где она помогает синхронизировать данные между устройствами и пользователями без потери информации и конфликтов. В условиях растущей популярности распределённых систем и необходимости защиты данных от централизованного контроля, CRDT становится всё более актуальной и востребованной. В завершение стоит отметить, что простой мессенджер на Bash — лишь одна из возможных реализаций CRDT в реальной жизни. В принципе, архитектура позволяет создавать любые синхронизируемые и адаптивные системы, будь то заметки, списки задач, трекеры или даже игры.
Возможность совместной работы без постоянного подключения к интернету, без конфликтов изменений и с лёгким развертыванием — вот сильные стороны, которые делают CRDT и подобные им подходы чрезвычайно привлекательными сегодня. Подход, описанный здесь, является отличным примером, как современные концепции могут быть быстро реализованы в среде, привычной многим администраторам и разработчикам — в Bash. Простота кода делает идею доступной для изучения и экспериментов, что способствует распространению знаний о CRDT и внедрению новых решений в повседневную работу и коммуникацию.