All streams
Search
Write a publication
Pull to refresh
63
0.5
Михаил @michael_v89

Программист

Send message

С этим не соглашусь. Пришел к выводу, что graphql лучше использовать как аналог rest api. Так сильно проще код на бэкенде и меньше проблем типа N+1 из-за резольверов полей. Контроллер принимает DTO, возвращает DTO, это можно замапить как на graphql интерфейс, так и на rest.

Вложенная пагинация в graphql не поддерживается. Ну то есть запросить 3-ю страницу order items у всех orders с 4-й страницы конечно можно, только практической пользы от этого нет. А cursor based pagination вообще работать не будет.

Такие хеши очень похожи на роуты с REST. Часто проще просто использовать REST.

Мне еще интересно, почему несколько десятков человек поставили плюс статье с таким содержанием и оформлением. Выглядит похоже на ботоферму.

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

Может хватит бегать за мной

Я комментирую статьи на Хабре, некоторые из них ваши. Это вы за мной бегаете со своим "невежеством".

«Патернака не читал, но осуждаю», ясно.

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

mnesia-то тут причем вообще?

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

Вот я вам и объясняю, что не интересны. Это не то же самое, что невежество, о котором вы почему-то упорно твердите в разных комментариях.

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

Потом я нахожу статью о том, как Klarna переехала с Mnesia на Postgres из-за проблем с поддержкой и масштабируемостью, в том числе по причинам "сost effective", "rich query language" и "schema evolution", и понимаю, что правильно сделал.

Это вывод, основанный на той информации, которую вы соизволили сообщить. А мысли читать я не умею.

Вы говорите "Можно не сохранять данные в базу данных, а хранить в процессах на нодах". Я спрашиваю "У меня бизнес хочет иметь страницу, где заказы выводятся списком с фильтром по актуальному статусу и другим полям, с сортировкой и пагинацией. Как мне это сделать с хранением данных в процессах?". Вы вместо конструктивного ответа начинаете отговорки "Ну это что-то на джейсоноукладочном". Если даже специалист, который рекомендует этот подход, не может ответить на такой простой вопрос, то мне этот подход не подходит. Как минимум потому что надо будет потратить много времени на выяснение самому, как максимум окажется, что надо все равно использовать базу данных, или писать кучу кода, который ее имитирует.

Ну это уж совсем какой-то разврат.

Вы в каждой функции пишете защиту от падения метеорита и космической радиации, которая случайным образом меняет биты в оперативной памяти?

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

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

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

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

Отстаньте от меня со своим бизнесом

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

я не боюсь показаться неправым

"хотя и говорите обратное"

Я пишу в базу от сотен тысяч процессов, на языке, в котором нет такого примитива: лок.

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

На всякий случай, под процессом я имел в виду код, который работает со своим подключением к БД, потому что из одного подключения запросы идут последовательно, и одновременных изменений одного ресурса быть не может. Ваш язык может и поддерживает сотни тысяч процессов, но вот базы данных типа PostgreSQL не поддерживают сотни тысяч одновременных подключений. Поэтому с точки зрения базы данных процессов у вас сильно меньше. Если вы используете одно подключение на все сотни тысяч процессов в контексте вашего языка, то в контексте моего утверждения и в контексте данной дискуссии у вас один процесс. Странно, что приходится объяснять такие банальные вещи.

И ничё.

Ну так многие и входные данные подставляют в SQL-запрос через sprintf, и ничё.

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

Я задаю вам вопросы по вашим текстам. Я желаю понять вашу точку зрения, но ваших текстах часто для этого недостаточно информации. По тому, что я понял, я вам объясняю, что уже огляделся, и то, что вы предлагаете мне не подходит. Это вы не желаете это понять.

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

Это у вас есть непонимание, что все понимают, что в реальном физическом мире нет 100% гарантий, и любые гарантии инструментов работают только в предположении, что всё остальное работает нормально, и подразумевают сравнение ситуаций с инструментом и без. Все понимают, что в любой момент может прилететь метеорит и упасть на датацентр, и программные инструменты от этого не защитят.
Я пытался вам это объяснить, когда вы пытались рассказать, но видимо вы так и не поняли.

Опросите 10 синьёров бигтеха
скрывает внутреннюю кухню, не позволяя получить к ней доступ напрямую. Ха-ха-ха. Проект AspectJ

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

Странно, что приходится объяснять это человеку с опытом.

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

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

Добиться, чтобы при создании черновика документа он был сохранён в базе
Нас интересует не факт сохранения в базе, а появление возможности публикации.
Поэтому прикладной код должен предпринять определенные действия, если черновику была отдана команда сохраниться, а действие «публикация» — всё еще недоступно.

Бизнес в таких задачах обычно интерсует не действия вашего кода по показу ошибки "Публикация недоступна, попробуйте еще раз", а чтобы пользователь не терял данные в черновике, которые он редактировал полчаса. В числе прочего это означает, что если он нажал "Сохранить", а потом обновил страницу в браузере, то он должен увидеть свои изменения, а не так что они пропадают на полчаса, он начинает снова набирать, а потом они появляются. Или не появляются, потому что произошел деплой, и все несохраненные данные потерлись. Если вы это реализовали, то это и есть то, что бизнес понимает под словами "Сохранить черновик документа в базе", а уж готовую базу вы используете или самописный аналог, это ему неинтересно.

Просто для общего развития

Я вам уже сказал, что я знаю, что это такое. Что именно вам непонятно в этой фразе? Мои слова этому определению не противоречат.

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

На всякий случай напомню, что термином "дедлок" называется ситуация, когда один процесс запрашивает локи в порядке (A, B), а другой в порядке (B, A), поэтому ждать освобождения локов они будут бесконечно. Когда оба процесса запрашивают только один лок, дедлока быть не может, просто по определению. Вот именно тому, которое вы привели.

Мьютекс в коде не может помешать изменить сущность в базе.

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

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

Оба вместе — прямой путь к дедлоку

Ну смотрите. В ваших представлениях это прямой путь. В реальности это не происходит. Значит ваши представления не соответствуют реальности. Предлагаю вам подумать, где именно.

Ну, это вы зря. Предполагать всегда надо самое худшее.

Нет. Такие случаи редки относительно общего количества людей, поэтому правильнее ожидать обратное. Иначе не получится общаться с другими людьми.

Вы не пытаетесь понять, о чем идет речь

Вот именно что пытаюсь. Я вам задавал много вопросов, чтобы понять, как у вас это организовано, вы на них не отвечаете. А мысли читать я не умею.

Hidden text

https://habr.com/ru/articles/910210/#comment_28318262
"потом сервер с этим процессом отключился, потому что в нем сломался жесткий диск, и что дальше?"

https://habr.com/ru/articles/876742/comments/#comment_28036226
"Как ваш гринтред будет подхватывать данные из персистентного хранилища (которое не база) после перезапуска на другом сервере в случае падения или деплоя новой версии кода, и получать по нему и данным из базы актуальное значения остатка для записи в переменую?"

https://habr.com/ru/articles/910210/comments/#comment_28320786
"Я легко мог бы и тут показать, как такие задачи решаются без реляций, но сегодня воскресенье, а подаю я только по пятницам."

Вы бы хоть по ссылке сходили, которую я в текст добавил

Понятия не имею, что вам не понравилось в документации, там все стандартно написано. А мысли, как я уже сказал, я читать не умею. Предлагаю вам перестать говорить загадками и цитировать то, что вы имеете в виду.
И независимо от того, что вы считаете проблемами с консистентностью, для приостановки параллельных изменений все равно можно использовать FOR UPDATE, он для этого и сделан. Поэтому я так и написал.

И списание средств произойдёт сколько раз вы там жобу повторяете.

С чего оно произойдет, если первая транзакция не закоммичена? Через некоторое время она откатится по таймауту.

База доступна в момент обращения к ней, а потом соединение рвётся. В тексте это очень внятно написано.

Я предполагал, что в моем тексте это тоже достаточно внятно написано, но ок, поясню подробнее.
База доступна в момент обращения к ней, а потом соединение рвётся. Если приложение узнало, что "вызов падает по таймауту", то с точки зрения приложения это означает, что база недоступна. Драйвер БД в этой ситуации обычно генерирует что-то вроде ConnectionTimeoutException. Если приложение зачем-то хочет повторить операцию, оно должно поймать его и открыть новое подключение.

Да, если это произошло во время отправки "COMMIT", решение тоже есть, и даже писать код не надо, потому что он должен быть написан в любом случае.

Hidden text

Проверка поля status после получения лока и перед вызовом логики.

Простите, а вы точно знаете, что такое дедлок?

Да. Подумайте, что означает первая часть слова, и сколько минимально сущностей в нем должно участвовать. Я говорю про одну сущность.

А что случится при атаке на определенный ID, например?

Я написал в предыдущем комментарии.

А что будет, если редис отвалился?

Internal server error в ответ на запрос. Я вам уже объяснял, что многим бизнесам не нужна ситуация, когда создание заказа происходит через 20 минут после запроса пользователя, когда редис поднимется.

Что будет, если при загрузке данных сущности — половина загрузилась, а потом сеть — тогось?

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

И вот тут-то соседний запрос и изменил эту сущность в базе до неузнаваемости. Что тогда?

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

Бывает. Жизнь сурова.

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

Да, правильнее было назвать status. Просто иногда называют state_id, вспомнилось, поэтому так написал.

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

Ну то есть на вопрос вы не ответили. Просил я не то, что вы написали.

и обновления стали приходить 1000 раз в секунду
прислал обновление названий всех товаров в кодировке UTC2
и подписался на их обновления
но перепутал секунды и миллисекунды

С учетом общей информации в качестве ответа на мой вопрос о конкретике, могу ответить только "транзакции, мьютексы и поле state". Ну или status, если хотите. Но могу добавить, что ситуация "сотни параллельных обновлений" у нас была на практике, и прекрасно всё отработало.
Не могу сказать, что это крайние случаи, вполне стандартное ожидаемое поведение, особенно перед праздниками.

поженить транзакцию с мьютексом

Поскольку я предпочитаю вести дискуссию конструктивно, то напишу детали, как это работает.
В приложение приходит веб-запрос, в нем указан id сущности. Запрашивается лок на сочетание "название сущности + id" через Redis или advisory lock в базе. Лок должен быть на корень агрегата, а не на входящие в него сущности. Лок естественно имеет таймаут, поэтому никаких бесконечных дедлоков не возникает. После этого в приложение загружаются данные сущности. Не в транзакции, потому что логика может включать чтение с диска или сетевые запросы, и не стоит держать транзакцию всё это время открытой, а также чтобы не возиться с уровнями изоляции. Производятся необходимые бизнес-проверки, выполняется логика действия, запускается транзакция БД, сохраняются изменения (в режиме все или ни одного). После этого лок освобождается. При большой нагрузке на один ресурс (сущность) некоторые запросы могут получить ответ 429 "Попробуйте позже", и клиент должен повторить запрос. Многие сервисы умеют автоматически это делать. Там, где это не подходит, запросы складываются в очередь и обрабатываются позже. Прекрасно всё работает, изменения одной сущности происходят сериализовано, изменения разных сущностей параллельно.

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

Давайте обсудим? Какие крайние случаи вы тут видите, как они решаются в вашем подходе?
Насколько я вижу, с базой нет особых проблем это сделать. Транзакции, мьютексы и поле state. Во всяком случае не больше, чем с другим подходом.

Наличие в этом уравнении сущности «сеть» — сразу ломает все гарантии, потому что не существует способа синхронизировать состояние в базе там и в приложении здесь.

А должен быть? Как это связано с транзакциями?
Если нужно приостановить параллельные изменения в базе пока приложение обрабатывает загруженное состояние, для этого используются мьютексы. Внутри транзакции можно использовать FOR UPDATE.

Если в этот момент просто отловить ошибку и попытаться транзакцию повторить (что, смею предположить, делает примерно 90% всего клиентского кода в мире)

Не знаю, как в других языках, но в веб-проектах на PHP такое встречается крайне редко. База недоступна, процесс пишет в лог и падает с исключением. Fail-fast и всё такое. Я такое встречал только пару раз в фоновых консольных командах, которые обрабатывают много записей, чтобы переподключиться заново.

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

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

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

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

Information

Rating
1,989-th
Location
Россия
Registered
Activity