← На главную

Flow от FoundationDB избавляет от колбэков, но с ограничениями IDE

02.07.2026 14:41 · hackernews

Когда FoundationDB задумывали, перед ними стояли амбициозные цели: высокая производительность на узел и масштабируемость. Нужна была эффективная асинхронная связь процессов, как в Erlang или .NET Async, но с сырой скоростью и эффективностью ввода-вывода C++. Решили не выбирать — написали свой инструмент. Так появился Flow — язык, который добавляет акторную конкурентность прямо в C++11. Flow расширяет C++ новыми ключевыми словами и примитивами для управления асинхронностью. Компилятор анализирует актор (функцию с пометкой ACTOR) и переписывает её в объект с внутренними колбэками, который не блокирует поток. На выходе — обычный C++11, который собирается стандартными средствами. Flow также передаёт данные симулятору FoundationDB для детерминированного тестирования всей системы, включая отказы железа.

Основные строительные блоки — Promise<T> и Future<T>. Один компонент даёт обещание (Promise), другой ждёт результат (Future). Уникальная фича: промисы можно передавать по сети, связь остаётся. Когда актору нужно реальное значение, он вызывает wait(). Выполнение актора приостанавливается, но другие акторы в том же процессе продолжают работать — вот вам асинхронность.

Потоки сообщений обслуживают PromiseStream<T> и FutureStream<T> — мультиплексирование и надёжная доставка. Для работы с потоком используют waitNext(), а выбор из нескольких фьючерсов организуют через choose … when. В статье приведён реальный код сервера, который держит счётчик и обрабатывает три типа запросов. Если бы это писали на чистом C++, пришлось бы городить сложные колбэки с обработкой исключений. Flow делает то же самое без потери производительности.

Но жизнь с Flow не сахар. Это не совсем C++. Локальные переменные не переживают вызов wait — разработчику приходится самим следить за областями видимости, например, заключать блоки в фигурные скобки. this внутри актора — указатель на скомпилированный класс, что ломает работу IDE. Для совместимости есть специальный хедер actorcompiler.h и флаг -DOPEN_FOR_IDE=ON, генерируется compile_commands.json. state-переменные — после компиляции становятся полями класса, но в IDE-режиме выглядят как локальные; из-за этого методы могут не скомпилироваться, если не помечены const. Нужно передавать ссылки явно. И главное: state-переменные не подчиняются обычным правилам области видимости, их лучше объявлять в самой внешней зоне использования.

Читать оригинал →