Pull to refresh

Comments 36

По сути, проблемы которых Rust создан избегать, можно решить другими способами - хорошим тестированием, хорошей системой код-ревью и хорошим мониторингом.

"Just be careful"?

Что действительно кусается, так это когда вам нужно изменить сигнатуру какого-то глобального интерфейса. Вы можете завязнуть в часовой подготовке, где вы меняете каждое место, где используется тип, только для того, чтобы увидеть, осуществима ли ваша первоначальная идея или нет. А затем переделывать всю это работу, когда вы понимаете, что вам необходимо что-то еще изменить.

Моя собственная практика показывает, что ещё больнее может укусить, если не изменить какое-то место, где используется тип (потому что оно просто проскочило мимо внимания). Впрочем, возможно, именно для прототипа это не страшно, потому что он всё равно кусается постоянно, чисто в силу изменяющихся требований.

Как вы яхту назовёте, так она и поплывёт. Чего хорошего можно ожидать от языка с названием Ржавый?

Ржавые болты не всегда можно выкрутить, иногда их приходится срезать, высверливать и нарезать новую резьбу.

Вообще довольно пугающая история :). Выбрать специфический язык и стек для стартапа. В стартапах всегда нехватка всего: ресурсов, времени. Да просто людей искать сложно. Грубо говоря специфический стек уменьшает компетенцию команды из-за меньшего охвата. А компетенция - это то чего не хватает в первую очередь всегда :))).

Вообще похоже на плач менеджера. Пара увлеченных людей сделала проект на расте, он выстрелил, пришел менеджер и начал жаловаться, что людей на дальнейшую поддержку и развитие не найти

Откуда вывод про "выстрелил"? Судя по cv автора https://www.mdw.la/ и информации про компанию - https://www.crunchbase.com/organization/xnor-ai она мертва с 2020 года.

Ну на тот момент казалось, что выстрелил, иначе зачем компании расширятся в 10 раз?

Это не выстрелил. Это получил первый раунд, освоил и умер. При этом у стартапа может вообще не быть пользователей. Могут и быть. Но "выстрелил" надо ещё показать.

Интересно, какое следующее озарение придет автору оригинальной статьи? Что писать frontend на С не лучшая идея? Затрагивая данную тему мне кажется нужно было бы обсудить актуальную тему самодурства основателей стартапа, которые вместо того чтобы подобрать инструмент согласно потребностям и возможностям, решили в игрушки поиграть. Причем вместо Rust можно подставить любую модную но не подходящую для задачи технологию. Но нет, откроем людям правду что оказывается язык программирования в основном предназначенный для системного программирования не очень подходит для написания crud приложений.

Ребята не смогли превратить "крутую кривую" в механизм объективной оценки кадров и саморазвития. Эффективных менеджеров которым нужно хотя бы одно из этого - не видел.

UFO just landed and posted this here

После компилятора раста компилятор go выглядит как интерпретатор js на фоне компилятора go

Мне кажется резкий перевод команды из 15 человек на новый язык - одна из причин боли. Насколько крута кривая обучения, настолько медленным по идее должно быть и раскатывание языка по команде. Ну и прагматичность как-то вас подвела в плане использования мощных штук типа актикса.

Я всегда жаловался на скорость разработки на Rust. И мой опыт, в целом, соответствует опыту в статье. Правда у меня был большой pet-проект, на расте я писал его около двух лет, после очередной борьбы (https://t.me/inv2004_dev_blog/28 https://t.me/inv2004_dev_blog/29) наконец-то плюнул и решился сменить язык. Но, главное удивление, я понимаю что в голове уже были некие дорожки по этому проекту, но переписывание всего функционала параллельно улучшая, заняло ТРИ НЕДЕЛИ, три недели и два года, Карл!

Что-то ни в одной вашей истории не понятно на что вообще жалоба.


Чем вам помешало разделение чанков, что пришлось аж сервер менять?


Где вы в mongodb::Cursor вообще увидели ссылку, да такую что её аж пинить пришлось?

Нужен был подсчёт чанков, пришлось патчить hyper: https://github.com/hyperium/hyper/pull/2087

Ws на actix-web оказалось неподъёмной задачей

Там надо было хранить и коллекцию и курсор/итератор. Получается циклическая структура

Нужен был подсчёт чанков, пришлось патчить hyper: https://github.com/hyperium/hyper/pull/2087

Вам нужна была хрень. Чанки http имеют семантику потока байт, а не потока сообщений. Нет никакой причины, по которой получателя в принципе должен волновать вопрос сколько чанков ему пришло. Собственно, вам об этом и написали:


Intermediaries (proxies and gateways) may re-interpret the chunked encoding, so this isn't reliable. Additionally, HTTP2 and 3 don't use chunked encoding.

Понимаете, это не библиотека виновата, и не Rust, это протокол HTTP так работает!


Всё, что требовалось — это натравить потоковый парсер json на поток байт в асинхронном цикле. Это делается куда быстрее чем те несколько недель, которые вы упоминали в истории.




Там надо было хранить и коллекцию и курсор/итератор. Получается циклическая структура

О каком цикле речь?


Да, Cursor ссылается (через Arc) на Collection, но Collection же на Cursor не ссылается… В чём проблема просто положить их рядом двумя полями?

Люблю такие бесплатные советы. Жаль вас не было в раст-чате когда я там спрашивал, потому как вы, очевидно, опытнее чем 1000+ человек оттуда.

Но, напишу еще раз, в первом случае надо или делать свой протокол, либо переходить на ws, хотя проблема только в отсутствии одного метода. Причём тут json и каким образом он потоковый вообще? Дело не в http, ведь хайпер умеет обрабатывать чанками

А второе - вы не проходите их вместе, по причине что я описал выше

Честно говоря, не понимаю почему всем так нравятся чаты. Там, конечно, попытаются помочь (если это не чат по линуксу), но вы можете просто не пересечься во времени с кем-то знающим ответ. Что, видимо, и произошло.


SO, форумы или списки рассылки выглядят куда более надёжными. Я, например, периодически на ru.SO наведываюсь. Но период бывает большой, да — неделю прождёте запросто.


Дело не в http, ведь хайпер умеет обрабатывать чанками

То, что хайпер умеет (точнее, умел) обрабатывать чанками — это иллюзия. Такая же, как приём TCP пакетами. И проблема именно в этом.


Json же тут при том, что у вас (цитата) Server sends several jsons: one per http-chunk. И эти самые джейсоны у вас склеиваются при приёме сплошным потоком. А потоковый парсер позволит выцепить из потока json-сообщения без предварительного чтения всего потока в память.


А второе — вы не проходите их вместе, по причине что я описал выше

Не пройду куда? Вот я написал следующий код, и он скомпилировался:


use mongodb::{Collection, Cursor, bson::Document, options::FindOptions, error::Error};

pub struct MyIterator<T>(Collection<T>, Cursor<T>);

impl<T> MyIterator<T>{
    pub async fn new(collection: Collection<T>) -> Result<Self, Error> {
        let cursor = collection.find(
            Document::default(),
            FindOptions::default()
        ).await?;

        Ok(Self(collection, cursor))
    }
}

Чтобы не быть голословным, если хотите, я восстановлю тот код с циклическими ссылками и сделаю минимальный пример. Если вы сделаете за час - я вам оплачу этот час, если нет - то вы мне . потому что писать слова в чате типа "просто заворачиваешь один поток в другой", здорово конечно, но часто в реальности не так просто

Код я вам привёл выше, бесплатно.

Я даже не уверен что вы разобрались в датах сообщений и взяли тот монго-крейт, который был актуален на момент того что я написал

Ваши сообщения без VPN не открываются, это сильно мешает подробно разбираться. Однако, раз вы настаиваете, я всё же скомпилировал код с версией 1.2.5, которая вышла за три недели до вашего второго сообщения:


use mongodb::{Collection, Cursor, bson::Document, options::FindOptions, error::Error};
use serde::{Serialize, de::DeserializeOwned};
use std::fmt::Debug;

pub struct MyIterator<T: Serialize + DeserializeOwned + Unpin + Debug>
    (Collection<T>, Cursor<T>);

impl<T: Serialize + DeserializeOwned + Unpin + Debug> MyIterator<T>{
    pub async fn new(collection: Collection<T>) -> Result<Self, Error> {
        let cursor = collection.find(
            Document::default(),
            FindOptions::default()
        ).await?;

        Ok(Self(collection, cursor))
    }
}

Пришлось добавить несколько ограничений, но в остальном никаких изменений.

Посмотрите тут: https://github.com/inv2004/mongo-rust-driver/tree/change-stream

Ситуация довольно проста: на тот момент оффициальный драйвер не умел вообще почти ничего кроме примитивной выборки. Оставались два mongodb, который по перфомансу сильно отставал (оффициальный тоже был нетороплив), и только mongo_driver - работал нормально, но не поддерживал change streams - пришлось добавлять поддержку в него. Собственно, если я правильно помню, на нём это и работало

Собственно итоговая структура такая:

rental! {
    mod rentals {
        use super::*;

        #[rental]
        pub struct MongoIteratorTicker<'m> {
            coll: Box<Collection<'m>>,
            cursor: Cursor<'coll>
        }

        #[rental]
        pub struct MongoIteratorFull<'m> {
            coll: Box<Collection<'m>>,
            cursor: Cursor<'coll>
        }
    }
}

По моему личному опыту, разработка CRUD на Rust (Actix Web, SqlX, Postgres) была в среднем равна по скорости разработке на Node.JS и Typescript (хотя и разрабатывал я его в одиночку). В однотипном (и достаточно простом, чего уж) коде, коим является CRUD, проблемы и ошибки достаточно однотипны, и сильной просадки по скорости разработки не было.

Ощущения от разработки на Rust, конечно, совершенно другие, чем от Typescript, почти нет мелких досадных ошибок типизации (хотя и на Тайпскрипте их не очень много, по сравнению с чистым Джаваскриптом, не представляю, как люди нем пишут), основные ошибки - в логике программы. Хотя код получается более объемным.

Странные ребята. Переходят на экзотический язык во имя личных пристрастий. Бизнес за такое бьёт по рукам очень сильно. У меня на работе есть определённая свобода в выборе стека технологий для команды, но даже при своём пристрастии к Rust я никогда не выберу его для прода вместо например C++ в команде, пишущей на плюсах, потому что это означает гемор с обучением, наймом разработчиков в будущем, плюс непрерывные траты усилий в код-ревью "чтобы люди с опытом в C++ не писали на Rust как на C++", плюс ряд прочих проблем, по большей части нетехнических.

Но раз уж команда авторов взялась делать всё на расте, непонятно откуда эти проблемы с возросшим временем разработки. Не знаю как в крудостроении, но у нас 90% времени занимают бесконечные обсуждения поведения, и только 10% написание кода, причём кода в стиле достаточно туповатого ООП, который будет выглядеть плюс-минус одинаково что на C++ что на Rust что на Python, и потребует примерно одинакового времени реализации на различных языках. Возможно они полезли в асинхронщину.

По сравнению, скажем, с Go, библиотеки и экосистема документаций Rust невероятно незрелы. Преимущество Go заключалось в том, что его разрабатывала и поддерживала целая специальная команда

Всё там прекрасно документировано. У Rust Foundation тоже выделенная команда тех. писателей и та же std и ряд стандартных крейтов документированы ими вдоль и поперёк. Подозреваю, что автор в основном пользуется крейтами и продуктами третьей стороны, тем же Actix, он хочет чтобы всё было документировано на том же уровне?

В Rust такая "черновая разработка" чрезвычайна сложна, потому что компилятор может и будет жаловаться на каждую чертову вещь, которая не проходит проверку типов и времени жизни - как это и было специально задумано.

Я только изучаю Rust, параллельно разрабатывая свой небольшой проект. Даже имея такой маленький опыт, могу с уверенностью сказать, что в Rust ничего не заставляет использовать обобщённые типы, указатели, их времена жизни и т.п.. Делая прототип, я везде использовал .unwrap(), чтобы не тратить время на обработку ошибок, всюду, где ругался компилятор, передавал объекты через .clone(), а дженерики вообще не нужны, если у меня всюду один f64. Когда все тесты написаны, то можно спокойно заняться мытьём полов, избавляясь от грязного кода, заняться продумыванием системы типов и обработкой ошибок. В этом плане я не заметил ухудшения своей производительности по сравнению с Питоном с его "игрушечной" типизацией.

Даже в растбуке написано - перфомансом занимайтесь когда будете понимать что он вам нужен, а сейчас достаточно clone() =)

Поддержу. Опыт работы с web на Rust, в частности с actix ужасен. Это прям "не его". После Go-шных миллионов веб-библиотек (не говоря о стандартной) этот скудный выбор и откровенно неудобные решения...прям брр.

Пару месяцев назад (т.е. исключаем незрелость) я на нем не смог сделать даже обработку array значения из query string (a[]=1&a[]=2&a[]=3). Ну вот просто не работает (судя по SO, не у меня одного). Компилируется и втихаря всегда возвращает пустой массив. Пришлось просто сплитить строку по запятым (благо у меня простые значения).

В ту же копилку загрузку файлов на actix. Таких ужасных примеров/документации я очень давно не видел, это прям жесть. Хотя, казалось бы, очень простая задача для веб-фреймворка.

За время моей работы в этой компании мы наняли массу людей, но только двое или трое из 60+ человек, имели реальный опыт работы с Rust. ... мы не решались нанимать людей, которые хотели кодить только на Rust

За что боролись - на то и напоролись.

Но я думаю, что Rust часто используется в ситуациях, где он не очень-то и подходит.

Ну да, большинство чуть что сразу асинками думает. А ведь можно на том же Расте писать код как на Java, без всяких асинков, которые как раз из-за красно-синих функций усложняют проекты. И прототипировать на Расте можно очень эффективно, главное юзать нормальные IDE, а не nano :)

Основная причина, почему был использован Rust - это потому что двое основателей компании были экспертам в нем.

Во-первых, хорошо, что не в Ассемблере.

С другой стороны, может основная цель стартапа и была в том, чтобы проверить гипотезу о возможности создания продукта целиком(!) и сразу(!) на Rust (со всеми "пирогами": найм, обучение, ...). Просто, автор был не в курсе. Статьи и обсуждения, это -- одно, а личный опыт -- другое.

Реальный, практической опыт применения Rust в растущей компании - это весьма ценная вещь. Лично я теперь буду лучше ориентироваться когда и какой язык лучше применять. Спасибо за статью!)

Почему вы продолжали использовать раст в микросервисной архитектуре - смысл микросервисов в том чтобы независимости друг от друга. Если микросервисная архитектура была реализована правильно, то вы могли бы добавлять новые микросервисы написанные на любом другом языке. Также, если вам, всё же, захотелось переписать код - вы можете переписывать каждый микросервис отдельно - нет нужды вываливать весь код в бэклог одним куском.

То есть у С++ кривая обучения пологая, значит?

Статья вроде обо всем, но как бы и ни о чем. Подставь сюда руби или тот же тайпскрипт пару лет назад, будет то же самое.

Хорошо что перевод, можно поругать не задев чувства ex-head of engineering.

Группа некомпетентных разработчиков не умеющих в предварительное проектирование. Завязли в сложности и завалили проект. Ничего нового. А виноват ЯП конечно же.

Sign up to leave a comment.

Articles