Search
Write a publication
Pull to refresh
-10
0
Влад @Varim

ASP.NET Core WebAPI, SQL, JavaScript

Send message
Недавно решал такую же задачу. Сначала очень хотелось сохранить асинхронность вызовов, делал всякие хаки типа вызова конфигурации после создания хоста, но до его старта. Это даже работало. Но как правильно упомянули — это не очень понятно для тех, кто потом будет читать код.
В итоге сделал элементарную обёртку:
public static class RunSyncUtil
    {
        private static readonly TaskFactory factory = new
            TaskFactory(default,
                TaskCreationOptions.None,
                TaskContinuationOptions.None,
                TaskScheduler.Default);

        public static void RunSync(Func<Task> task)
            => factory.StartNew(task).Unwrap().GetAwaiter().GetResult();
}

И в нескольких местах проекта, где раньше вызывался GetAwaiter().GetResult() заменил на такой вызов. Таким оразом мы явным образом берём поток из ThreadPool и уже на нём выполняем блокировку GetResult
Делать это пришлось не только из-за эстетических соображений, но ещё потому что у нас зависали интеграционные тесты. Дело в том, что сам по себе asp.net core не устанавливает никакой специальный SynchronizationContext, поэтому в нём можно без последствий вызывать GetAwaiter().GetResult(). Но XUnit применяет свой хитрый контекст для контроля параллельного выполнения теста и тут мы легко приходим к дедлоку.
Кстати, есть баг, который описывает потенциальное решение проблемы github.com/dotnet/aspnetcore/issues/5897 но пока его не хотят исправлять и это печально
А ещё LoadAsync().GetAwaiter().GetResult() и LoadAsync().Result вызывают дедлоки и категорически запрещены к использованию, являются жутким говнокодом. Но их используют по старой привычке и потому что ни разу не «прилетело».

Правильно вызывать асинхронный код исключительно через новый поток как написано выше:
var value = Task.Run(async () => await GetValueAsync()).Result;

потому что в зависимости от контекста вызова там куча вариантов (кажется 6), когда поток попадёт 100% в дедлок, когда не 100% и когда не попадёт. Разница для одного и того же кода будет даже если вы вызывали его как часть библиотеки, через IIS или как часть сервиса.

Вообще-то непонятно, почему было принято архитектурное решение CQRS/ES. Логики не прослеживается именно в описании выбора. Дано:
1) пришел готовый проект, который писали по CRUD.
2) Он работает плохо. Симптоматика кратко дана.
3) ?????
4) Поэтому решили делать на CQRS/ES.


Почему плохо подходит CRUD? Может, это проблема реализации, а не подхода? Как CQRS/ES была признана способной решить именно эти проблемы, помимо "поговорили с коллегами"? Что получилось сделать хорошо, помимо описанных в статье проблем? Это хорошо, что тут CQRS/ES подошел отлично, исходя из опыта проекта, но из статьи совсем не понятно, почему.
Ну и в самом CQRS сливать Event и Command в одной транзакции — это достаточно сильное искажение архитектуры. Command может быть проигнорирован, а Event обязан выполниться — это их основное отличие, диктующее способ применения.

Я пока в раздумьях над сервером с NVMe SSD под PostgreSQL. Нужно много IOPS. Пока сложно всё.

Интелы P4610 вам в помощью. Как раз для этих целей.
Схематически.

Здорово. Я просто к тому, что вот клиент получил ссылку, ему не надо ее хардкодить — все хорошо. Но потом ему надо ее вызвать, т.е. надо знать что это за метод (POST, DELETE и т.д.) и еще неплохо знать, что отправить. А REST, как мудрый филин, ничего об этом не говорит и вообще он не про это, он о высоком.
Простой пример, фильтр по параметрам, довольно часто это делают POST и передают json с выбранными параметрами фильтрации. И теперь получается, что к конкретной ссылке будет прибит гвоздями объект фильтрации.
В случае с JSON сервер может передать описание формы через JSON Schema

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

Важную часть забыли: "в сторону внутренних кругов и повышения абстракции" ('toward higher-level policies"). Теперь давайте задумаемся, как же расположить слои "Service, Repository, Model" в порядке повышения абстракции?

(вынесу в корень, многобукав)


Но SCREAMING ARCHITECTURE нужно рассматривать отдельно от Clean Architecture. [...] И самый главный момент, книга написана по уже имеющийся архитектуре, а не код организовали по книге.

Хорошо, давайте посмотрим на только Clean Architecture, это глава 22 соответствующей книги.


Пост:


для примера возьму эталонную реализацию этой архитектуры для Asp.Net Core.

Вот упрощенный пример приложения:

Из кода я оставлю только самое (для меня) важное:


public IndexController(IUserProfileService userProfileService)
public UserProfileService(IUserProfileService userProfileService)
//упс, циклическая зависимость
//наверное, вот это имелось в виду?
public UserProfileService(IUserProfileRepository userProfileRepository)
public UserProfileRepository(DBContext dbContext)

Рисуем цепочку зависимостей: контроллер -> сервис -> репозиторий -> БД. Проверяем себя — в статье явно написано то же самое (это, кстати, важно, потому что одно небольшое изменение радикально изменит архитектуру):


В программе слой Controller зависит от слоя Service, а он зависит от слоя Repository.

Поскольку сервис зависит от репозитория, слой репозитория является внутренним по отношению к слою сервисов. Аналогично, слой БД является внутренним по отношению к слою репозитория. Это соответствует главному правилу из Clean Architecture:


Source code dependencies must point only inward...

… точнее, только первой его части. Потому что вот вторая:


...toward higher-level policies.

Но репозиторий и БД — это не higher-level policy, а деталь имплементации. Проверяем себя (выделение мое):


The software in the interface adapters layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the database or the web. [...] No code inward of this circle should know anything at all about the database.

Напомню, что согласно диаграмме в той же главе, слой interface adapters — это слой gateways, второй снаружи. Слой сервисов (бизнес-логики) — третий, и он не может зависеть от репозиториев, размещенных во втором, согласно основному правилу. Следовательно, описанное в статье


он [слой Service] зависит от слоя Repository.

противоречит CA, как она описана в главе 22. Ровно то же самое применимо и к зависимости репозиторий-фреймворк БД (второй и первый слои соответственно).


Вывод: приведенная в статье "эталонная реализация этой архитектуры", как ее объясняет автор статьи, не соответствует принципам, приведенным в главе, на которую автор статьи ссылается.


PS Бонус-пойнт:


Достигается такая гибкость за счет разделения приложения на слои Service, Repository, Model.

Вот только нет таких слоев у Мартина. У него есть четыре слоя:


  1. Frameworks & drivers
  2. Interface Adapters
  3. Application Business Rules
  4. Enterprise Business Rules

Из которых два внутренних еще называются Use Cases и Entities.


Слово Model как название слоя в главе 22 не встречается. Слово Repository там не встречается вообще.


Еще про репозитории (хотя это, конечно, глава 34 уже):


The keen-eyed reader will notice that the OrdersRepository from previous diagrams has been renamed to simply be Orders. [...] To put that another way, we talk about “orders” when we’re having a discussion about the domain, not the “orders repository.”
В синей книге (DDD) Сервис определен как любой класс без состояния. Ну и разделение такое нужно чтобы отделить те классы без состояния которые служат слоем изоляции от тех классов без состояния которые что-то вычисляют.

Более того. Открываем книгу, глава 21, "SCREAMING ARCHITECTURE" (дадада, вам ее уже поминали"):


So what does the architecture of your application scream? When you look at the top-level directory structure, and the source files in the highest-level package, do they scream “Health Care System,” or “Accounting System,” or “Inventory Management System”? Or do they scream “Rails,” or “Spring/Hibernate,” or “ASP”?
[...]
Just as the plans for a house or a library scream about the use cases of those buildings, so should the architecture of a software application scream about the use cases of the application.

Открываем репозиторий по ссылке: команды, контроллеры, ядро, модели, режимы, сервисы, представления.


Явно противоречит написанному в книге.

Можно в base64 конвертировать и копипастить куда хочется.
Да тот же ETL Toolkit Кимбалла, глава про Cleaning and Conforming. А вот уже про конкретные реализации лучше читать соответствующие разделы документации к ETL инструментам.
Моя ситуация со спиной подобна описанной автором статьи, возникла также порядка 15ти лет назад.

В своё время отказался от предложенной операции. Много чего перепробовал, в итоге вот к чему пришел:

  • Каждый день утром комплекс из нескольких упражнений на спину и одно на пресс. Собирал информацию из разных источников, перепробовал кучу разных упражнений, в итоге оставил те, что по моим ощущениям наиболее эффективны в моём случае.
  • Вечером условно говоря йога. Условно — потому что под этим словом подразумеваю не духовную практику и не гимнастику, которую под видом йоги предлагают в фитнес-центрах, а несколько асан для расслабления и растяжки мышц спины. В моём случае — эффект очень ощутим, с добавлением растяжки эффективность остальных мероприятий повысилась. Рекомендую автору статьи повторно обратить внимание на йогу. Без лишнего фанатизма, как на инструмент для решения конкретной проблемы.
  • Раз в неделю закачка спины в спортзале. Малые веса, большое количество повторений. Основа — тренажер для гиперэкстензии, упомянутый автором статьи.
  • Раз в год — курс массажа.

Спина в результате ощущается и работает хорошо. Спорт, катание детей на шее и т.п. — как со здоровой спиной. А ведь был момент, когда самостоятельно не мог с бока на бок перевернуться, несколько месяцев не мог себе шнурки завязать.

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

Бассейн, как не странно, не особенно помогает, даже возможно мешает. Бег — отлично, особенно если в процессе следить за состоянием спины, помогает снять лишние напряжения.

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

Моё мнение по поводу стульев

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

Много лет использовал такого типа:
image

Благодаря наклону сиденья, при работе за компом получается более естественное положение поясницы. Минус — могут уставать колени, но можно поочерёдно снимать ноги с упора, меняя таким образом и положение позвоночника в том числе. После поломки решил попробовать другие варианты.

Сейчас использую типа седло:

image

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

Раньше стоили довольно дорого, в последнее время появился отечественный производитель, цена стала вменяемой.

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

И с сиденьем на шарнире:

image

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

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

Я тоже из тех, кто проводит 10+ часов в день с мышью в руках. И тоже столкнулся с данной проблемой. В моем случае помогает следующее:
  1. При первых болевых симптомах в суставе правой руки, я иду в ближайший спортмагазин и покупаю обычный кистевой эспандер (резиновый тор). Каждый раз, когда есть свободная минутка — разминаю кисть. Через месяц такой терапии, боль уходит и не возвращается ближайшие года 2-3 как минимум.
  2. Использую коврик с гелевой подушкой. Тут важно выбрать не первый попавшийся, а такой, у которого подушка достаточно высокая, широкая и плотная.

хороший коврик
image

плохой коврик
image
На Хабре несколько человек писало о болях в большом пальце после долгого пользования подобным.
Мошков В. Н. «Лечебная физкультура в клинике нервных болезней»

Не ищите такие вещи на английском! =)
Они никогда не появятся в открытом доступе.
Их медицина (хотя и наша тоже, чего уж греха таить) идёт по пути фармации — торговли таблетками. Капитализьм и всё такое...)
«Фармаци́я — комплекс научно-практических дисциплин, изучающих проблемы создания, безопасности, исследования, хранения, изготовления, отпуска и маркетинга лекарственных средств, а также поиска природных источников лекарственных субстанций.»

image
Нэ бэспокойтесь!
Всё уже придумано до нас! Жаль не удалось утаить до следующей статьи. =(
Такие вы тут на Хабре проницательные… И суток не прошло а решение нашли.

Пожалста!
Будем надеятся, что этот коммент никто не увидит и интрига сохранится до следующей моей публикации)))
Тогда начинайте читать.
Сначала учебник биомеханики, а потом Каптелина.
«Котикова Е.А. — Биомеханика физических упражнений.»
«Каптелин А.Ф. — Восстановительное лечение при травмах и деформациях опорно-двигательного аппарата.»

Если хорошо пошло, ещё работы Мошкова В.Н. можно добавить!
UFO landed and left these words here

В очередной раз спасибо самому полезному расширению в этой стране, даже не заметил блокировку.


А вообще, удивляюсь, что с ними не сотрудничают… Когда на Кинопоиске встретил интересующий сериал в озвучке от Кубик в кубике, например, был очень рад.

Возможно я что-то не так понял, но ведь чтобы отлавливать состояние, достаточно выбрать его в инспекторе:
Пример
image

Information

Rating
Does not participate
Location
Россия
Date of birth
Registered
Activity

Specialization

Backend Developer
Senior
From 6,500 $
ASP.NET Web API
Entity Framework
RabbitMQ
Redis
Apache Kafka
Elasticsearch
Docker
English
SQL
.NET