Telegram Web
А от шарповой версии запроса уже конкретно начинает течь кровь из глаз, при том, что простые запросы там прекрасны. В качестве примерна приведу получение всех записей, где определенное поле равно чему-то:

_mongoCollection.Find(record=>record.Field3=="qwerty123").ToList();

В примере используется трансляция в монговский формат внутришарпового языка запросов к коллекциям LINQ, потому всё максимально прозрачно.

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

В монге встроен механизм, который может быть использован в т.ч. для подобного переезда без отключения базы: создаём реплики на новых серверах, после чего постепенно отключаем старые инстансы и база перенесена.

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

Прилагаю статью с описанием процесса переноса продакшн базы без остановки доступа к данным. Кросивое.

Теперь надо бы для общего развития поднять кластер где-нибудь у себя.

#mongo
В прошлом году итоги я подвёл в ноябре при запуске #палантир@eshu_coding, после него ничего особо интересного не было.

В этом году никаких проектов не под NDA, я в общем-то не делал. Если без подробностей, то вот краткие итоги личностного роста:
1. Научился готовить Tarantool, прошёлся по куче граблей, примерно понял, где он реально нужен, и главное, где не нужен. Пришлось поверхностно познакомиться и с механизмом построения кластеров: репликация, шардирование, вот это вот всё.

2. Нырнул в MongoDB на уровне, отличном от "положил как в помойку, достал по id/однострочному запросу". Многоступенчатые запросы, подписки на обновления коллекций, TTL, транзакции, materialised view. Впервые завел реплика-сет вместо отдельностоящего инстанса.

3. Построил пару обменников на RabbitMQ, пришло осознание проглоченного и применённого на коленке в 2021.

4. Влюбился в систему сбора метрик Prometheus. Если раскидать их по приложению и заодно подключить сбор с компонентов системы (баз данных и т.д.), получается крайне информативно. Дефолтный визуализатор так себе, но основные функции выполняет.

5. Познакомился с EKL стеком - сбор и визуализация логов. Особой любви не случилось, уж больно оно огромно и прожорливо. Можно кстати использовать ELK для построения красивых дашбордов по данным из Prometheus-а, но это мне пока не особо нужно.

6. Прогресс как шарписта у меня вышел так себе. Научился красиво описывать rest api с помощью Swagger, да в общем-то и всё. Ну ещё окончательно освоил разработку с использованием докера: приложение сразу запускается и отлаживается в контейнере, окружённое соседними сервисами. При прогоне тестов также активно использую песочницу, поднятую в docker-compose.

P.S. NoSQL я накушался досыта, 2023 - время вернуться к истокам - C# + PostgreSQL.
👍91
Ну чтож, надо посмешить богов, озвучить свои планы.

Чего хочу я в этом году:
1. Немного обмазаться фронтенд разработкой, но без фанатизма. Пока думаю о связке React + Typescript.

2. Попробовать на практике стандартную шарповую ORM: Entity Framework.

3. Углубиться в PostgreSQL, поиграться с уровнями изоляции транзакций, подтянуть оптимизацию запросов, возможно попробовать пособирать разные конфигурации кластеров на foreign table.

4. Прочитать несколько умных книжек, что-то типа:
a) Рихтер
b) Высоконагруженные приложения Фаулера
c) Ещё что-нибудь по архитектуре.

5. Начать подтягивать базу по Computer Science, мб копнуть алго задачи.

Вот такие планы, интересно, что исполнится к концу года:)
🔥7👍4👏2
Эшу быдлокодит
Ну чтож, надо посмешить богов, озвучить свои планы. Чего хочу я в этом году: 1. Немного обмазаться фронтенд разработкой, но без фанатизма. Пока думаю о связке React + Typescript. 2. Попробовать на практике стандартную шарповую ORM: Entity Framework. 3.…
Ну что же, фронтенд мой пока закончился на попытке нормально подружить Visual Studio и фронтенд разработку.

Я стремительно расширяю сознание в части строительства всякого интересного на базе MongoDB, скоро буду выходить на новый уровень в части работы с RabbitMQ.

PostgreSQL? Entity Framework? Фронтенд? Планирование? Не, это для лохов.
🔥3🤡2🤔1
Не прошло и 5 лет работы с с#, как я сподобился начать читать в режиме "от корки до корки" базовую книгу: Рихтера. Она несколько устарела: относится к версии языка от 2012 года. Но т.к. базовые концепции, лежащие в основе, с тех пор не поменялись, так что ознакомиться надо.

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

Так, операцию сравнения - == между двумя экземплярами класса надо применять с осторожностью, результат зависит далеко не только от их содержимого.

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

Во всех экземплярах классов хранится ссылка на объект-тип. GetType как раз ее и возвращает. Не то, чтобы что-то революционное, просто небольшой штрих в общей картине.

Далее здесь будет что-то типа конспекта, который буду писать по мере прочтения. Ну и будут новые теги:
#книги
#Рихтер
👍2
Практически осилил фундаментальную главу про типы. В целом - почти ничего нового, но пару занятных нюансов вычитал.

В с# есть разделение на типы - значимые (структуры, живут обычно в стеке) и ссылочные (обычные классы, живут в куче).

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

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

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

Ещё из интересного - если выдавливать максимум производительности, то использовать штатные методы -ToString, GetType, GetHashCode для значимых типов стоит с осторожностью - легко наступить на грабли и засрать кучу мусором - во многих случаях сначала будет произведена операция упаковки (сама по себе не очень быстрая) значимого типа в кучу из стека, а потом уже вызван метод. Те из них, которые поддаются переопределению - переопределить. А GetType - использовать только по большой нужде. Кроме траты времени на упаковку мы нагружаем сборщик мусора, что в некоторых случаях даже печальнее.

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

#книги
#рихтер
👍3
Сколько времени программисту нужно, чтобы разобраться с тем, как включить мультики с usb с телевизора?

15 минут и помощь системного аналитика, знающего бэкдор: направлять пульт строго в правый нижний угол телевизора.
😁5
Эшу быдлокодит
Практически осилил фундаментальную главу про типы. В целом - почти ничего нового, но пару занятных нюансов вычитал. В с# есть разделение на типы - значимые (структуры, живут обычно в стеке) и ссылочные (обычные классы, живут в куче). Для значимых сравнение…
Продолжаю читать про типы. Наткнулся на пару моментов, где я по незнанию лепил избыточный код:
1. Увидел как вызывать конструктор из другого конструктора. Чуть меньше копипасты:)
2. Узнал, что статический конструктор по умолчанию потокобезопасен. То есть все мои неэстетичные огородики с блокировками в таких конструкторах отправляются на помойку. Отлично.

#рихтер
#книги
👍4
Наткнулся на забавный вопрос к собеседованиям:

Как изменить в уже запущенной программе значение строковой константы?

Константа на то и константа, чтобы быть неизменной. Да ещё строки в c# неизменяемые, но есть обходной путь, правда череватый выстрелом даже не в ногу, а в живот.

В c# есть особый раздел языка: unsafe. По сути, это что-то вроде урезанного языка c++. И вот с помощью такой вставки можно получить указатель на место в памяти, где хранится эта константа и нагадить записать туда свои байтики.

Потому родился встречный вопрос:
А у вас в кодовой базе такое практикуется?
🔥6
Forwarded from javawatch
ChatGPT достигла уровня человека! Я попросил ее написать пример использования модулей в C++23 через cmake, и у нее не получилось. У меня тоже не получилось. Каких высот мы достигли!
😁6🤡1
Познакомился с работой с координатами на карте. Широта и долгота, x и y, логично ведь? Север на карте - сверху, вертикаль - это y. А горизонталь - x.

А вот стандартная шарповая библиотека для работы с пространством считает иначе, придется с этим жить.

#csharp
А монга своей простотой однако развращает. После года плотной работы с ней, почти в любой ситуации, когда надо какое-то хранение состояния хочется просто насрать им записать его в монгу и пойти дальше.
На неделе надо было максимально быстро накидать незамысловатый UI для внутреннего пользования, так чтобы работало на Винде, посмотрел несколько вариантов реализации:
1. C# Win Forms
2. C# WPF.
3. C# MAUI
4. React.js

У Win Forms в наличии визуальный редактор: накидал элементов, сгенерировался c# код, чуть поправил его под себя - и готово.

У WPF - тоже есть редактор, но генерируется xaml разметка, что-то типа xml. Главная проблема, что его тоже нужно знать.

MAUI - тот же xaml. Не предполагает визуального редактора. Предлагаемый путь разработки - пересборка приложения на ходу, на живую: приложение запущено в дебаге, ты на ходу правишь xaml и смотришь результат. Заманчивой выглядит перспектива кроссплатформенности: одна и та же кодовая база собирается под Android, iOS и Windows. Главный недостаток MAUI - низкая распространенность. Изучать его имеет смысл если только для души.

React - это другой язык программирования - Java Script. Может быть собран в приложение под любую распространенную ОС, но основная точка приложения - веб сайты. Разработка идёт примерно как в MAUI: открыт браузер, меняется код - меняется внешний вид сайта.

В целом, наименьшее отвращение у меня вызвали React и MAUI. Но даже для решения простых задач в оба из них надо погружаться, это как минимум пара дней.

В итоге я зажал нос и решил свою задачу на Win Forms за несколько часов, после чего пошел дальше. Но с реактом я когда-нибудь разберусь!
👍4😁3
Есть такой продукт для обмена данными между микросервисами - RabbitMQ, я его неоднократно упоминал в канале выше. Это - брокер сообщений, вся суть его - передача информации из входной точки (обменника) к выходным (очереди), на которые подписываются сервисы. RabbitMQ поддерживает гарантированную доставку сообщения. Даже если рухнет мироздание вся инфраструктура, когда она оживет - брокер может поднять помещенные в него сообщения и продолжить передавать их подписчикам.

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

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

Оказалось, что настройка "не удалять очередь при рестарте RabbitMQ" вообще ниразу не значит, что надо сохранять все помещенные в нее сообщения. Удаление сообщения регулируется отдельно, при том в момент публикации можно выбрать настройку персистентентности для каждого сообщения в отдельности.

RabbitMQ позволяет принимать сообщения как синхронно, так и асинхронно. Для обоих способов предусмотрены специальные методы. Но вот беда - асинхронный прием сообщений не работает. Оказалось, сообщать RabbitMQ что я буду принимать асинхронные оповещения надо на этапе подключения к нему.

В остальном RabbitMQ прекрасен: удобно и быстро настраивается из с#, нагрузку держит.

#rabbitmq
👍3
Наткнулся на неочевидную проблему при приеме данных от RabbitMQ. Когда блямкает оповещение, оно представляется неким классом, имеющим поле типа ReadonlyMemorySpan<byte>, то есть по большому счету ссылка на область памяти с указанием размера.

Ну я и складировал эти классы для последующей обработки. Поддал нагрузки при тестировании - и из кролика полезла какая-то фигня, которую я туда не передавал.

Сделал копирование байтиков в массив сразу по получении - и проблема рассосалась.

#rabbitmq
😁1
Эшу быдлокодит
На неделе надо было максимально быстро накидать незамысловатый UI для внутреннего пользования, так чтобы работало на Винде, посмотрел несколько вариантов реализации: 1. C# Win Forms 2. C# WPF. 3. C# MAUI 4. React.js У Win Forms в наличии визуальный редактор:…
У меня таки дошли руки до раскуривания реакта, ещё немного и я смогу быть junior react developer!

В несколько подходов отработал основные концепции:
1. Хранение состояний, композиция хранилищ, перерисовка компонента при изменение состояния, относящегося к ней (например - таблицы при появлении новых данных).
2. Роутинг внутри сайта: переходы между логин-экран1-экран-2 и так далее.
3. Адаптивная верстка: на мобилке - один ui, в браузере - другой.
4. Потыкал самые распространенные компоненты, типа текстового ввода.
5. Разобрался с разметкой страниц (ни капли html, что характерно).
6. Научился принимать и отправлять данные как обычными запросами, так и веб советами.

В общем, можно начинать творить:)

#react #кодинг #js
До недавнего времени из-за ограничений браузера для организации постоянной связи браузер-бэкенд надо было или использовать веб-сокеты и гонять через них json-ы, или использовать web-gRPC, прибавляя дополнительный узел прокси сервера на бэке, роль которого сводилась к конвертации порезанного под браузер протокола в вид, понятный человеческому gRPC.

И тут совершенно случайно узнал, что в c# совсем недавно завезли поддержку браузерной gRPC. Осталось протестировать и насадить практику использования этого чуда инженерной мысли на фронте.
👍1
Оказалось довольно удобно совмещать ORM с хранением jsonb в постгресе. Делаешь модельку вида:

class Model
{
Int Field1,
String Field2,
String Field3,
InnerModel ClassField
}

В обычные поля таблицы кладешь то, по чему будут строиться индексы и какую-то важнейшую информацию, к которой нужен максимально быстрый доступ.

А остальные поля, которые надо будет только читать, в т.ч. содержащие подклассы и массивы, уезжают в поле, содержащее класс (ClassField в примере). Помечяешь поле атрибутом "хранить как jsonb" и ORM сама сериализует и десериализует его. В итоге, вместо веера из десятка таблиц, разложенных по нормальным формам, получаем одну, время чтения и модификации данных соответственно уменьшается.

Итого, лёгким движением руки Postgres превращается, Postgres превращается...
в мутанта, содержащего признаки реляционки и монги.

/Напевает себе под нос/ Денормализация! Денормализация!

#postgresql
😁3
2025/07/09 08:31:22
Back to Top
HTML Embed Code: