“Скажи мне — и я забуду, покажи мне — и я запомню, дай мне сделать — и я пойму”.
Когда я со своим котом начинал разработку движка биржи, именно эта цитата Конфуция звучала в моей голове. Мы были сплоченной и мотивированной на результат командой. Интерес и готовность преодолевать трудности, возникающие на пути к MVP, — вот как можно было описать наше состояние. Вызовы и открытия, возникшие в процессе разработки, определенно внесли свои коррективы и стоили затраченного времени. Об основных из них, а также об итогах эксперимента, я и хочу поведать сегодня.
Для нетерпеливых — вот ссылка на демо версию биржи, которую можно запустить на своих машинах.
Всех остальных прошу под кат.
Самый большой вызов этого проекта состоял в ограниченности ресурсов. Наверняка если бы это ограничение не стояло так остро, список выглядел бы иначе. Возможно, для кого-то этот список будет банальностью, но любой вопрос можно воспринимать по разному: пропасть между “услышал о проблеме”, “понял ее” и “осознал” довольно велика.
Список того, что я осознал при разработке проекта:
Довести проект до MVP сложнее, чем начать его.
Когда работаешь над проектом один, тем более только в свободное время, очень легко отклониться от намеченных сроков. В разработке пришлось сделать полугодовую паузу из-за возросшей основной рабочей нагрузки и семейных дел.
Реализация проекта была разделена на 2 временных отрезка: март-апрель 2019 и ноябрь-декабрь 2019. В ноябре я не был уверен, что доведу проект до MVP. Но так как уже были готовы все внутренние интерфейсы, система хранения, процессинг ордеров и оставалось только создать интерфейсы пользователей, я решил продолжить.
Как итог, я понял, что лучше не приостанавливать проект, так как теряется исходная мотивация и происходит переключение внимания. Чтобы продолжить работу, пришлось приложить некоторые усилия чтобы найти время для завершения проекта.
Маркетинг бывает разным.
Этот пункт я включил после анализа и выбора стека для фронтенда. Разнообразие библиотек и фреймворков поражает, а скорость изменений их API вообще иногда вводит в ступор.
Хайп — это не всегда хорошо, так как размер сообщества вокруг проекта часто не коррелирует с качеством решения.
Если проект/решение/технология позиционирует себя, как лучшее решение, а в описании многое объясняется “магией”, лучше избегать их применения. Это сохранит ваше время в будущем.
Никогда не знаешь, с какой проблемой или недоработкой в стороннем ПО столкнешься.
Даже проверенные решения иногда подводят. Редко, но все же случается ситуация, когда инструмент, который используешь довольно продолжительное время, начинает вести себя не так, как ожидаешь.
Во время проекта у меня было несколько ситуаций, когда я удивлялся. Это были Timescale и его time_bucket не поддерживающий большие интервалы; Tarantool и вопросы, связанные с репликацией, а также ручным управлением транзакциями; Rustler, который стал копировать больше данных при вызове функций… Этот список можно продолжать, но главное и самое ценное — в мире открытого программного обеспечения всегда можно исправить проблему, либо же, исследовав исходный код приложения, понять, как ее обойти.
Из-за ограниченности ресурсов приходится тщательно планировать объем работ. Но в случае возникновения незапланированных трудностей, любые и мелкие и крупные проблемы приходится решать самому. Их просто некому делегировать.
Таким образом, каждая новая техническая сложность, например ошибка в сторонней библиотеке или обнаруженное ограничение в используемой технологии, а иногда и архитектурная ошибка внутри проекта могут очень сильно сдвинуть сроки.
Когда взгляд замыливается, это влияет на принятие решений
В обычных условиях коммерческой разработки мы коммуницируем с другими людьми. Любой проект — люди, создающие и использующие его. В процессе разработки мы постоянно получаем новую информацию от других участников и дополняем свое видение вопроса.
Принятие любого технически сложного решения — процесс непростой. Когда вы погружены в проблему и проводите часы, а иногда и дни, обдумывая пути решения, ваш взгляд замыливается.
Я осознал, насколько важно и ценно работать над проектом в команде. Возможность посовещаться с коллегой, который в теме, но не работает над этой же задачей и может критически оценить ваш подход и решение, сохранит время и снизит вероятность ошибок.
Кота сложно научить программировать (для тех кто хочет повторить эксперимент).
Несмотря на то, что мой четырехлапый друг демонстрировал неподдельный интерес к проекту, это не мешало ему постоянно отвлекаться и всячески лениться. Уже после пары недель, я понял, что программистом ему не стать. Однако нельзя недооценить его навыки командной игры. В итоге в зону его ответственности перешли вопросы поддержания командного духа, с которыми, надо признать, он справился на отлично.
Баги есть? Ну или хотя бы мышки...
Итоги эксперимента
В начале эксперимента я поставил 2 основных задачи:
- углубление собственных знаний и прокачка экспертизы;
- исследование применимости функциональных языков и проектов с открытым исходным кодом при разработке торговых систем.
За время эксперимента я определенно систематизировал и углубил свои знания предметной области и даже попытался поделиться ими с сообществом (ссылки на предыдущие скучные теоретические статьи можно найти в моем профиле). Поэтому данный пункт считаю успешно выполненным.
Что касается функционального программирования… Опять же, я смотрю через призму Erlang/OTP. Erlang как язык и OTP как фреймворк определенно подходят для промышленного программирования и реализации финансовых систем. Экосистема зрелая, а минимальный синтаксический базис языка, иммутабельность и подходы, заложенные в OTP, позволяют быстро реализовывать масштабируемые распределенные и при этом надежные системы. К сожалению я не вел журнал затраченного времени, но вся разработка заняла 4 неполных месяца в свободное время после основной работы. При этом в проекте более 200 интеграционных тестов.
Но и ложка дегтя в бочке меда все же есть. Erlang по производительности очень похож на Python. В отличии от последнего, на нем легко писать высококонкурентные системы с настраиваемым уровнем параллельности. Кроме того, эти системы довольно легко масштабировать и разносить компоненты в рамках кластера. Эти системы в результате получаются хоть и емкими, но не сверхбыстрыми.
Исходя из последнего вывода, я понял, что наиболее эффективным и производительным подходом будет не разнесение обработчиков рынков и аккаунтов клиентов по разным машинам в рамках кластера, а обработка всех рынков и аккаунтов в рамках одной машины с репликацией данных для обеспечения надежности.
Из-за недостаточной производительности Erlang, обработку рынков стоить делать на более низкоуровневых языках без GC и справедливых планировщиков. В текущей реализации я уже вынес часть функционала в NIF на Rust.
Таким образом, благодаря оптимизированной работе с сетью и бинарными структурами, Erlang прекрасно решает вопросы организации надежной и быстрой распределенной платформы. А вот вопрос работы с ордерами и аккаунтами лучше реализовать на Rust/C/C++ (добавлять по вкусу).
Еще одним немаловажным моментом является выбор языка для фронтенда. По старой привычке я отдал предпочтение Vue + Js. Но если бы я выбирал стек сейчас, то выбрал бы Vue + Typescript. Более строгая типизация позволила бы ускорить разработку.
Спасибо всем, кто следил за развитием эксперимента. Надеюсь вам было не очень скучно! Не прощаемся! :)
Возможно будет интересно:
Kwisatz
А вы бы не могли статейку накидать по этому делу и вообще поделиться опытом использования. После пайплайна не всегда и не все там очевидно
mr_elzor Автор
Попробую найти время и подготовить материал