День 2136. #Оффтоп
async2 — Завершение Эксперимента с Асинхронностью в .NET. Начало
Команда .NET работала над новым экспериментом под названием async2, который представляет собой новую реализацию шаблона async/await, разработанную для большей эффективности и гибкости, чем текущая реализация. Он начался с зелёных потоков и закончился экспериментом, который перемещает async и await в среду выполнения. Рассмотрим путь async2 и то, чем закончился эксперимент.
Зелёные потоки
Всё началось с зелёных потоков. Это пользовательские потоки, которые управляются библиотекой времени выполнения или виртуальной машиной, а не операционной системой. Они лёгкие и могут создаваться и управляться быстрее, чем потоки ядра. Зелёные потоки также известны как «сопрограммы» или «волокна» в других языках программирования. Идея заключается в том, что вам, как разработчику, не нужно беспокоиться о потоках.
В настоящее время для потоков и в некоторой степени для async/await создаётся новый стек. Вы можете легко увидеть это в IDE, при отладке (см. картинку).
Зелёные потоки отличаются. Память зелёного потока выделяется в куче. Но это имеет свою цену: поскольку они не управляются ОС, они по своей сути не могут использовать преимущества нескольких ядер. Но для операций, связанных с вводом-выводом, они хорошо подходят.
Отказ от зелёных потоков
Ключевые проблемы, которые привели к отказу от эксперимента с зелеными потоками, были следующими:
1. Сложное взаимодействие между зелёными потоками и существующей моделью асинхронности;
2. Взаимодействие с нативным кодом было сложным и медленнее, чем при использовании обычных потоков;
3. Проблемы совместимости с мерами безопасности, такими как теневые стеки;
4. Неопределённость относительно того, можно ли сделать зелёные потоки быстрее, чем async в важных сценариях, учитывая усилия, необходимые для улучшения.
Это привело к выводу, что зелёные потоки — неверный путь для среды выполнения .NET, и породило эксперимент async2.
async2
Очевидно, это просто кодовое имя. Целью эксперимента было переместить async и await в среду выполнения. Главной мотивацией этого было сделать async более эффективным и гибким. Поскольку async уже используется как идентификатор в C#, команда решила использовать async2 в качестве кодового имени для эксперимента. Если эта штука когда-нибудь попадёт в среду выполнения, она будет называться async — то есть это будет замена текущей реализации async. В следующем посте разберём, что же это такое.
Окончание следует…
Источник: https://steven-giesel.com/blogPost/59752c38-9c99-4641-9853-9cfa97bb2d29/async2-the-net-runtime-async-experiment-concludes
async2 — Завершение Эксперимента с Асинхронностью в .NET. Начало
Команда .NET работала над новым экспериментом под названием async2, который представляет собой новую реализацию шаблона async/await, разработанную для большей эффективности и гибкости, чем текущая реализация. Он начался с зелёных потоков и закончился экспериментом, который перемещает async и await в среду выполнения. Рассмотрим путь async2 и то, чем закончился эксперимент.
Зелёные потоки
Всё началось с зелёных потоков. Это пользовательские потоки, которые управляются библиотекой времени выполнения или виртуальной машиной, а не операционной системой. Они лёгкие и могут создаваться и управляться быстрее, чем потоки ядра. Зелёные потоки также известны как «сопрограммы» или «волокна» в других языках программирования. Идея заключается в том, что вам, как разработчику, не нужно беспокоиться о потоках.
В настоящее время для потоков и в некоторой степени для async/await создаётся новый стек. Вы можете легко увидеть это в IDE, при отладке (см. картинку).
Зелёные потоки отличаются. Память зелёного потока выделяется в куче. Но это имеет свою цену: поскольку они не управляются ОС, они по своей сути не могут использовать преимущества нескольких ядер. Но для операций, связанных с вводом-выводом, они хорошо подходят.
Отказ от зелёных потоков
Ключевые проблемы, которые привели к отказу от эксперимента с зелеными потоками, были следующими:
1. Сложное взаимодействие между зелёными потоками и существующей моделью асинхронности;
2. Взаимодействие с нативным кодом было сложным и медленнее, чем при использовании обычных потоков;
3. Проблемы совместимости с мерами безопасности, такими как теневые стеки;
4. Неопределённость относительно того, можно ли сделать зелёные потоки быстрее, чем async в важных сценариях, учитывая усилия, необходимые для улучшения.
Это привело к выводу, что зелёные потоки — неверный путь для среды выполнения .NET, и породило эксперимент async2.
async2
Очевидно, это просто кодовое имя. Целью эксперимента было переместить async и await в среду выполнения. Главной мотивацией этого было сделать async более эффективным и гибким. Поскольку async уже используется как идентификатор в C#, команда решила использовать async2 в качестве кодового имени для эксперимента. Если эта штука когда-нибудь попадёт в среду выполнения, она будет называться async — то есть это будет замена текущей реализации async. В следующем посте разберём, что же это такое.
Окончание следует…
Источник: https://steven-giesel.com/blogPost/59752c38-9c99-4641-9853-9cfa97bb2d29/async2-the-net-runtime-async-experiment-concludes
👍25
День 2137. #Оффтоп
async2 — Завершение Эксперимента с Асинхронностью в .NET. Окончание
Начало
async — функция компилятора
Текущая реализация async и await — это функция компилятора. Компилятор генерирует конечный автомат для async -метода. Среда выполнения ничего не знает об async и await. Нет никаких следов ключевого слова async в IL или в JIT-скомпилированном коде. И вот с этого начался эксперимент, подробно описанный здесь.
async — функция среды выполнения
Целью эксперимента было переместить async и await в среду выполнения. Это позволило бы среде выполнения иметь больше контроля над самим шаблоном. При этом также была бы другая семантика.
async2 не сохраняет и не восстанавливает контекст синхронизации и контекст исполнения на границах функций, вместо этого позволяя вызывающим методам наблюдать изменения. С ExecutionContext это изменяет поведение AsyncLocal.
Сегодня AsyncLocal используется для хранения данных, которые передаются с логическим контекстом вызова. Они копируются в новый контекст. Тем не менее, если функция глубоко в стеке вызовов изменяет значение AsyncLocal, вызывающий метод не увидит обновлённое значение, его увидят только методы ниже по логическому асинхронному потоку. Например:
Вывод:
В async2 изменения не «откатываются», что приводит к другому выводу:
Сравнение с текущей реализацией
Команда обнаружила, что подход с помещением асинхронности в JIT может дать наилучшие результаты в целом. Вот основные отличия:
1. Производительность
Async обычно медленнее, чем async2, особенно для глубоких стеков вызовов, где async2 имеет производительность, сопоставимую с синхронным кодом в сценариях без приостановки исполнения.
2. Обработка исключений
В async медленно и неэффективно, вызывает паузы GC и влияет на отзывчивость приложений. В async2 улучшена.
3. Ограничение глубины стека
Присутствует в async, что может вызвать проблемы для глубоких стеков вызовов. Нет явных ограничений в async2.
4. Потребление памяти
В async обычно ниже, особенно в сценариях с большим количеством приостановленных задач. В async2 более высокое потребление памяти из-за захвата целых стековых кадров и регистров, но все ещё приемлемо по сравнению с другими факторами, такими как время паузы.
Полный документ здесь.
Что дальше?
Пока это всего лишь эксперимент, который может привести к замене async через несколько лет. Да, может пройти некоторое время, прежде чем это будет выпущено. А для переходной фазы должен быть interop для async <-> async2. В любом случае - очень хорошая отправная точка. Ждём async2, как юнионов.
Источник: https://steven-giesel.com/blogPost/59752c38-9c99-4641-9853-9cfa97bb2d29/async2-the-net-runtime-async-experiment-concludes
async2 — Завершение Эксперимента с Асинхронностью в .NET. Окончание
Начало
async — функция компилятора
Текущая реализация async и await — это функция компилятора. Компилятор генерирует конечный автомат для async -метода. Среда выполнения ничего не знает об async и await. Нет никаких следов ключевого слова async в IL или в JIT-скомпилированном коде. И вот с этого начался эксперимент, подробно описанный здесь.
async — функция среды выполнения
Целью эксперимента было переместить async и await в среду выполнения. Это позволило бы среде выполнения иметь больше контроля над самим шаблоном. При этом также была бы другая семантика.
async2 не сохраняет и не восстанавливает контекст синхронизации и контекст исполнения на границах функций, вместо этого позволяя вызывающим методам наблюдать изменения. С ExecutionContext это изменяет поведение AsyncLocal.
Сегодня AsyncLocal используется для хранения данных, которые передаются с логическим контекстом вызова. Они копируются в новый контекст. Тем не менее, если функция глубоко в стеке вызовов изменяет значение AsyncLocal, вызывающий метод не увидит обновлённое значение, его увидят только методы ниже по логическому асинхронному потоку. Например:
await new AsyncLocalTest().Outer();
public class AsyncLocalTest
{
private readonly AsyncLocal<string>
_al = new();
public async Task Outer()
{
_al.Value = "Out";
Console.WriteLine($"Outer: {_al.Value}");
await Inner();
Console.WriteLine($"Outer: {_al.Value}");
}
private async Task Inner()
{
_al.Value = "In";
Console.WriteLine($"Inner: {_al.Value}");
await Task.Yield();
Console.WriteLine($"Inner: {_al.Value}");
}
}
Вывод:
Outer: Out
Inner: In
Inner: In
Outer: Out
В async2 изменения не «откатываются», что приводит к другому выводу:
Outer: Out
Inner: In
Inner: In
Outer: In
Сравнение с текущей реализацией
Команда обнаружила, что подход с помещением асинхронности в JIT может дать наилучшие результаты в целом. Вот основные отличия:
1. Производительность
Async обычно медленнее, чем async2, особенно для глубоких стеков вызовов, где async2 имеет производительность, сопоставимую с синхронным кодом в сценариях без приостановки исполнения.
2. Обработка исключений
В async медленно и неэффективно, вызывает паузы GC и влияет на отзывчивость приложений. В async2 улучшена.
3. Ограничение глубины стека
Присутствует в async, что может вызвать проблемы для глубоких стеков вызовов. Нет явных ограничений в async2.
4. Потребление памяти
В async обычно ниже, особенно в сценариях с большим количеством приостановленных задач. В async2 более высокое потребление памяти из-за захвата целых стековых кадров и регистров, но все ещё приемлемо по сравнению с другими факторами, такими как время паузы.
Полный документ здесь.
Что дальше?
Пока это всего лишь эксперимент, который может привести к замене async через несколько лет. Да, может пройти некоторое время, прежде чем это будет выпущено. А для переходной фазы должен быть interop для async <-> async2. В любом случае - очень хорошая отправная точка. Ждём async2, как юнионов.
Источник: https://steven-giesel.com/blogPost/59752c38-9c99-4641-9853-9cfa97bb2d29/async2-the-net-runtime-async-experiment-concludes
👍20
День 2138. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Командная работа. Начало
Каждая организация, компания и команда имеет свою культуру. Под культурой понимается философия «как мы работаем». Здоровая культура разработки ПО характеризуется набором общих ценностей и технических практик, определяющих поведение и решения людей в организации. Здоровую культуру составляют обязательства на индивидуальном, командном и организационном уровнях по созданию качественных продуктов путём неукоснительного следования соответствующим процессам и методам. Если всё идет хорошо, то члены команды получают удовольствие от работы.
Культура компании развивается органично, если только руководители активно не направляют её в определённое русло. Молодые компании, основным продуктом которых является ПО, часто устанавливают сильные культурные требования, наилучшим образом сказывающиеся на их командах и выполняемой ими работе. И наоборот, IT-подразделение в нетехнологической корпорации наследует общие культурные особенности компании. Работа в IT имеет свои особенности, отличающие её от работы в других сферах, поэтому логично, что культура в них должна развиваться в другом направлении, желательно совместимом и дополняющем. Некоторые аспекты корпоративной культуры вошли в противоречие с требованиями современной гибкой и быстро меняющейся IT-сферы.
Характерный признак укоренения здоровой культуры в организации, — сохранение новых взглядов, методов и моделей поведения даже после ухода ключевых руководителей. Например, если новые руководители не сохранят курс на постоянное совершенствование, то некоторые члены команды могут вернуться в привычную для них зону комфорта. В результате некоторые процессы, которым команда следовала, постепенно станут неактуальными.
Культурная конгруэнтность
Конгруэнтность означает, что руководители и рядовые сотрудники действуют согласно заявлениям организации о ценностях, а не в соответствии с негласными правилами, которые могут противоречить официальным заявлениям. Ответы на вопросы, подобные следующим, могут показать, является ли культура конгруэнтной:
- Следуют ли руководители убеждениям, которые они проповедуют, или могут отступать от них под давлением извне, например, выпуская продукты, не соответствующие высоким критериям качества?
- Следуют ли технические специалисты установленным процессам или могут экономить на качестве перед дедлайном?
- Берут ли члены команды на себя реально достижимые обязательства и выполняют их или дают обещания, которые часто остаются невыполненными?
Поведение, которое вознаграждается руководителями организации, может служить чётким признаком их истинных ценностей. Зачастую можно видеть, как команда берётся за проект без чёткого планирования, а затем «тушит пожары» из-за постоянных сбоев в их системе. И эта команда, создавая постоянную видимость работы, получает больше благодарностей от руководства, чем другая, у которой всё просто работает, и кажется, что они прохлаждаются.
Кристаллизация культуры
Некоторые компании систематизируют важные черты своей культуры в виде руководств для сотрудников. Это помогает держать культурные ценности на виду, облегчает их передачу новым членам команды и ведёт к улучшению совместной работы.
В своей книге Software Teamwork Джим Броссо рекомендует каждой команде выработать свой контракт. Контракт должен отражать специфику конкретной команды, но быть связан с другими командами и компанией в целом. Он может содержать заявления, подобные этим:
- Для принятия решений на основе консенсуса мы проводим дебаты, уважая при этом мнения друг друга.
- Мы вовремя приходим на встречи и другие мероприятия и соблюдаем повестку дня.
- Члены команды должны стремиться завершить к установленным срокам все задачи, которые взяли на себя.
- Мы можем расходиться во мнениях внутри команды, но вовне представляем единую позицию.
- Мы приветствуем различные точки зрения, чтобы максимизировать коллективное творчество.
Окончание следует…
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
Уроки 50 Лет Разработки ПО
Командная работа. Начало
Каждая организация, компания и команда имеет свою культуру. Под культурой понимается философия «как мы работаем». Здоровая культура разработки ПО характеризуется набором общих ценностей и технических практик, определяющих поведение и решения людей в организации. Здоровую культуру составляют обязательства на индивидуальном, командном и организационном уровнях по созданию качественных продуктов путём неукоснительного следования соответствующим процессам и методам. Если всё идет хорошо, то члены команды получают удовольствие от работы.
Культура компании развивается органично, если только руководители активно не направляют её в определённое русло. Молодые компании, основным продуктом которых является ПО, часто устанавливают сильные культурные требования, наилучшим образом сказывающиеся на их командах и выполняемой ими работе. И наоборот, IT-подразделение в нетехнологической корпорации наследует общие культурные особенности компании. Работа в IT имеет свои особенности, отличающие её от работы в других сферах, поэтому логично, что культура в них должна развиваться в другом направлении, желательно совместимом и дополняющем. Некоторые аспекты корпоративной культуры вошли в противоречие с требованиями современной гибкой и быстро меняющейся IT-сферы.
Характерный признак укоренения здоровой культуры в организации, — сохранение новых взглядов, методов и моделей поведения даже после ухода ключевых руководителей. Например, если новые руководители не сохранят курс на постоянное совершенствование, то некоторые члены команды могут вернуться в привычную для них зону комфорта. В результате некоторые процессы, которым команда следовала, постепенно станут неактуальными.
Культурная конгруэнтность
Конгруэнтность означает, что руководители и рядовые сотрудники действуют согласно заявлениям организации о ценностях, а не в соответствии с негласными правилами, которые могут противоречить официальным заявлениям. Ответы на вопросы, подобные следующим, могут показать, является ли культура конгруэнтной:
- Следуют ли руководители убеждениям, которые они проповедуют, или могут отступать от них под давлением извне, например, выпуская продукты, не соответствующие высоким критериям качества?
- Следуют ли технические специалисты установленным процессам или могут экономить на качестве перед дедлайном?
- Берут ли члены команды на себя реально достижимые обязательства и выполняют их или дают обещания, которые часто остаются невыполненными?
Поведение, которое вознаграждается руководителями организации, может служить чётким признаком их истинных ценностей. Зачастую можно видеть, как команда берётся за проект без чёткого планирования, а затем «тушит пожары» из-за постоянных сбоев в их системе. И эта команда, создавая постоянную видимость работы, получает больше благодарностей от руководства, чем другая, у которой всё просто работает, и кажется, что они прохлаждаются.
Кристаллизация культуры
Некоторые компании систематизируют важные черты своей культуры в виде руководств для сотрудников. Это помогает держать культурные ценности на виду, облегчает их передачу новым членам команды и ведёт к улучшению совместной работы.
В своей книге Software Teamwork Джим Броссо рекомендует каждой команде выработать свой контракт. Контракт должен отражать специфику конкретной команды, но быть связан с другими командами и компанией в целом. Он может содержать заявления, подобные этим:
- Для принятия решений на основе консенсуса мы проводим дебаты, уважая при этом мнения друг друга.
- Мы вовремя приходим на встречи и другие мероприятия и соблюдаем повестку дня.
- Члены команды должны стремиться завершить к установленным срокам все задачи, которые взяли на себя.
- Мы можем расходиться во мнениях внутри команды, но вовне представляем единую позицию.
- Мы приветствуем различные точки зрения, чтобы максимизировать коллективное творчество.
Окончание следует…
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
👍10
День 2139. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Командная работа. Окончание
Начало
Команды разработчиков ПО наиболее продуктивны, а их члены наиболее счастливы, когда удовлетворены следующие их основные потребности:
- безопасная и комфортная физическая среда;
- атмосфера честности и открытости для совместной работы;
- эмоциональная сплочённость команды и взаимная поддержка;
- сложная, но выполнимая работа;
- правильно подобранные инструменты;
- самоопределение и независимость в работе, которую они выполняют;
- возможность внести вклад и профессиональный рост.
IT — необычная техническая дисциплина, поскольку привлекает людей с широким спектром знаний, характеристик и взглядов и выигрывает от их присутствия. Группа разработчиков, состоящая из экспертов в области технологий, только выиграет от присутствия в ней нетехнических специалистов с сильными коммуникативными навыками и знанием предметной области.
Увеличение команды
Эффективная командная работа требует согласования общих целей и механизмов для их достижения. Новые члены команды привносят свой культурный багаж, как положительный, так и отрицательный. Проводя собеседование с кандидатами на вступление в команду, постарайтесь оценить, насколько хорошо они впишутся в вашу культуру.
Важно разобраться, почему человек возражает против определенных аспектов вашей нынешней культуры (например, против ведения журнала учёта потраченного времени). Возможно, ему знаком лучший подход, используемый в другом месте, или, может быть, он столкнулся с некими недостатками, проявляющимися в долгосрочной перспективе, которых вы ещё не достигли. Одно это может помочь повысить культуру команды.
Первые шаги
Потратьте несколько минут, ответив на следующие вопросы. Подумайте, в какой степени каждый из этих пунктов применим к вашей организации или команде.
1. Можно ли сказать, что в вашей организации здоровая культура разработки ПО? Почему да или почему нет?
2. Попробуйте перечислить предпринимаемые руководителями или членами команды модели поведения и действия, которые усиливают внимание к культуре, ориентированной на качество.
3. Наблюдали ли вы действия, убивающие культуру, негативно влияющие на отношения, мораль, поведение или работу членов команды?
4. Насколько хорошо вы понимаете культуру компании? Соответствует ли культура вашей команды культуре компании? Если нет, то что можно сделать, чтобы уменьшить разрыв?
5. Определите любые проблемы (болевые точки), которые можно отнести к недостаткам вашей культуры и того, как люди и команды взаимодействуют между собой. Каковы материальные и нематериальные издержки этих проблем?
6. Как каждая проблема влияет на вашу способность успешно завершать проекты. Как все они мешают достижению успеха в бизнесе и организации, и её клиентам? Недостатки в культуре могут привести к тому, что люди перестанут обмениваться информацией, не будут принимать или выполнять обязательства или начнут игнорировать установленные процессы. Моральные проблемы и текучка кадров указывают на то, что культура имеет некоторые изъяны.
7. Для каждой проблемы определите основные причины, провоцирующие или усугубляющие её. Проблемы и причины могут сливаться, поэтому постарайтесь разделить их и увидеть, как они связаны. Вы можете найти несколько причин, способствующих появлению одной и той же проблемы, или несколько проблем, обусловленных одной общей причиной.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
Уроки 50 Лет Разработки ПО
Командная работа. Окончание
Начало
Команды разработчиков ПО наиболее продуктивны, а их члены наиболее счастливы, когда удовлетворены следующие их основные потребности:
- безопасная и комфортная физическая среда;
- атмосфера честности и открытости для совместной работы;
- эмоциональная сплочённость команды и взаимная поддержка;
- сложная, но выполнимая работа;
- правильно подобранные инструменты;
- самоопределение и независимость в работе, которую они выполняют;
- возможность внести вклад и профессиональный рост.
IT — необычная техническая дисциплина, поскольку привлекает людей с широким спектром знаний, характеристик и взглядов и выигрывает от их присутствия. Группа разработчиков, состоящая из экспертов в области технологий, только выиграет от присутствия в ней нетехнических специалистов с сильными коммуникативными навыками и знанием предметной области.
Увеличение команды
Эффективная командная работа требует согласования общих целей и механизмов для их достижения. Новые члены команды привносят свой культурный багаж, как положительный, так и отрицательный. Проводя собеседование с кандидатами на вступление в команду, постарайтесь оценить, насколько хорошо они впишутся в вашу культуру.
Важно разобраться, почему человек возражает против определенных аспектов вашей нынешней культуры (например, против ведения журнала учёта потраченного времени). Возможно, ему знаком лучший подход, используемый в другом месте, или, может быть, он столкнулся с некими недостатками, проявляющимися в долгосрочной перспективе, которых вы ещё не достигли. Одно это может помочь повысить культуру команды.
Первые шаги
Потратьте несколько минут, ответив на следующие вопросы. Подумайте, в какой степени каждый из этих пунктов применим к вашей организации или команде.
1. Можно ли сказать, что в вашей организации здоровая культура разработки ПО? Почему да или почему нет?
2. Попробуйте перечислить предпринимаемые руководителями или членами команды модели поведения и действия, которые усиливают внимание к культуре, ориентированной на качество.
3. Наблюдали ли вы действия, убивающие культуру, негативно влияющие на отношения, мораль, поведение или работу членов команды?
4. Насколько хорошо вы понимаете культуру компании? Соответствует ли культура вашей команды культуре компании? Если нет, то что можно сделать, чтобы уменьшить разрыв?
5. Определите любые проблемы (болевые точки), которые можно отнести к недостаткам вашей культуры и того, как люди и команды взаимодействуют между собой. Каковы материальные и нематериальные издержки этих проблем?
6. Как каждая проблема влияет на вашу способность успешно завершать проекты. Как все они мешают достижению успеха в бизнесе и организации, и её клиентам? Недостатки в культуре могут привести к тому, что люди перестанут обмениваться информацией, не будут принимать или выполнять обязательства или начнут игнорировать установленные процессы. Моральные проблемы и текучка кадров указывают на то, что культура имеет некоторые изъяны.
7. Для каждой проблемы определите основные причины, провоцирующие или усугубляющие её. Проблемы и причины могут сливаться, поэтому постарайтесь разделить их и увидеть, как они связаны. Вы можете найти несколько причин, способствующих появлению одной и той же проблемы, или несколько проблем, обусловленных одной общей причиной.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
👍8
День 2140. #МоиИнструменты
Создаём и Тестируем Устойчивые Приложения в .NET с Помощью Dev Proxy
При создании приложений, подключающихся к API, мы обычно фокусируемся на том, чтобы приложение работало. Но что, если API работает медленно, возвращает ошибки или становится недоступным? Сложно смоделировать, как ваше приложение будет справляться с этими сценариями, если вы не контролируете API, с которыми вы интегрируетесь.
Моделирование ошибок и поведения API, таких как ограничение скорости или частоты запросов, не невозможно, но сложно. Обычно вы не контролируете API, с которыми вы интегрируетесь, поэтому для моделирования их различного поведения вы пишете сложные моки — кучу кода, который вы не будете поставлять.
Dev Proxy — это симулятор API, который позволяет моделировать различное поведение API, не изменяя ни одной строки кода вашего приложения. Вы можете моделировать ошибки, задержки, ограничение скорости и многое другое. И всё это время ваше приложение думает, что оно подключено к настоящему API.
Dev Proxy — это веб-прокси, который вы запускаете локально на своей машине разработки. Перед запуском вы настраиваете его для отслеживания запросов на определённые URL. Затем определяете, как он должен обрабатывать эти запросы: возвращать предопределённый ответ, выдавать ошибку, задерживать ответ или имитировать ограничение скорости или другие поведения? Когда вы запускаете Dev Proxy, он регистрируется как ваш системный прокси и перехватывает все запросы, которые соответствуют настроенным вами URL. Затем он применяет определённые вами поведения. Ваше приложение не знает, что оно не общается с реальным API. Оно просто получает ответы. Это отличный способ проверить, как ваше приложение обрабатывает различные поведения API.
По умолчанию Dev Proxy имитирует ошибку в ответ на запрос с вероятностью 50%. Если запрос не возвращает ошибку, Dev Proxy передаёт его реальному API.
Как улучшить устойчивость приложения для обработки сценария с ошибкой API? Во-первых, мы должны рассмотреть возможность перехвата исключения API и отображения его в удобном для пользователя виде. Это поможет обрабатывать как ошибки API, так и, например, ограничения частоты запросов (ошибка 429 Too Many Requests). Мы также должны рассмотреть возможность обработки ошибки 429 отлично от остальных ошибок, чтобы гарантировать, что приложение корректно сделает паузу и даст API время на восстановление.
Наблюдаемые URL, виды ошибок, периодичность их возникновения и варианты ответов на них можно настраивать как через параметры командной строки, так и с помощью файла конфигурации devproxyrc.json. Кроме того, можно настроить, например, возврат заголовка RetryAfter, сообщающего клиенту, который попал под ограничение частоты запросов, через сколько секунд надо повторить запрос.
Подробный пример работы с Dev Proxy рассмотрен в этом видео.
Источник: https://devblogs.microsoft.com/dotnet/build-test-resilient-apps-dotnet-dev-proxy/
Создаём и Тестируем Устойчивые Приложения в .NET с Помощью Dev Proxy
При создании приложений, подключающихся к API, мы обычно фокусируемся на том, чтобы приложение работало. Но что, если API работает медленно, возвращает ошибки или становится недоступным? Сложно смоделировать, как ваше приложение будет справляться с этими сценариями, если вы не контролируете API, с которыми вы интегрируетесь.
Моделирование ошибок и поведения API, таких как ограничение скорости или частоты запросов, не невозможно, но сложно. Обычно вы не контролируете API, с которыми вы интегрируетесь, поэтому для моделирования их различного поведения вы пишете сложные моки — кучу кода, который вы не будете поставлять.
Dev Proxy — это симулятор API, который позволяет моделировать различное поведение API, не изменяя ни одной строки кода вашего приложения. Вы можете моделировать ошибки, задержки, ограничение скорости и многое другое. И всё это время ваше приложение думает, что оно подключено к настоящему API.
Dev Proxy — это веб-прокси, который вы запускаете локально на своей машине разработки. Перед запуском вы настраиваете его для отслеживания запросов на определённые URL. Затем определяете, как он должен обрабатывать эти запросы: возвращать предопределённый ответ, выдавать ошибку, задерживать ответ или имитировать ограничение скорости или другие поведения? Когда вы запускаете Dev Proxy, он регистрируется как ваш системный прокси и перехватывает все запросы, которые соответствуют настроенным вами URL. Затем он применяет определённые вами поведения. Ваше приложение не знает, что оно не общается с реальным API. Оно просто получает ответы. Это отличный способ проверить, как ваше приложение обрабатывает различные поведения API.
По умолчанию Dev Proxy имитирует ошибку в ответ на запрос с вероятностью 50%. Если запрос не возвращает ошибку, Dev Proxy передаёт его реальному API.
Как улучшить устойчивость приложения для обработки сценария с ошибкой API? Во-первых, мы должны рассмотреть возможность перехвата исключения API и отображения его в удобном для пользователя виде. Это поможет обрабатывать как ошибки API, так и, например, ограничения частоты запросов (ошибка 429 Too Many Requests). Мы также должны рассмотреть возможность обработки ошибки 429 отлично от остальных ошибок, чтобы гарантировать, что приложение корректно сделает паузу и даст API время на восстановление.
Наблюдаемые URL, виды ошибок, периодичность их возникновения и варианты ответов на них можно настраивать как через параметры командной строки, так и с помощью файла конфигурации devproxyrc.json. Кроме того, можно настроить, например, возврат заголовка RetryAfter, сообщающего клиенту, который попал под ограничение частоты запросов, через сколько секунд надо повторить запрос.
Подробный пример работы с Dev Proxy рассмотрен в этом видео.
Источник: https://devblogs.microsoft.com/dotnet/build-test-resilient-apps-dotnet-dev-proxy/
👍10
День 2141. #ЧтоНовенького
Обновите Проекты Windows Forms для Повышения Безопасности
Каждый выпуск .NET представляет множество новых функций и исправлений ошибок, которые повышают как производительность, так и безопасность. Чтобы воспользоваться этими преимуществами, разработчики как сервисных, так и настольных приложений должны обновить свои приложения до последних версий .NET. Последнее обновление повысит безопасность опыта разработки WinForms в Visual Studio и мотивирует разработчиков WinForms обновлять свои приложения для повышения безопасности. Также это означает, что больше не будут поддерживаться проектирование форм в проектах, ориентированных на старые, неподдерживаемые версии .NET. Т.е. разработчикам также необходимо будет обновить свои проекты до поддерживаемых сред выполнения .NET, чтобы создавать формы в Visual Studio.
Обновление WinForms Designer и ваших приложений до новых версий .NET не только повышает безопасность, но и улучшает надёжность и производительность во время разработки за счет использования улучшений, доступных в новых версиях .NET и связанных NuGet-пакетах. Настоятельно рекомендуется обновлять ваши приложения до последних версий .NET.
Начиная с выпуска VS 17.12 Preview 3, WinForms Designer будет автоматически проверять целевую версию .NET вашего проекта. Если она ниже минимальной поддерживаемой версии, вы получите уведомление. Эта функция будет держать вас в курсе совместимости вашего проекта, обеспечивая лёгкий доступ к списку версий .NET и статусу их поддержки.
Будущая поддержка WinForms Designer в отношении сред выполнения .NET
Каждый раз, когда поддержка LTS выпуска .NET будет заканчиваться, Visual Studio будет обновлять минимальную поддерживаемую версию утилиты дизайна форм до этой версии LTS. Например, поддержка .NET 6 прекратилась в ноябре 2024 года, следующий выпуск Visual Studio, 17.13, обновит дизайнер форм, чтобы в качестве минимальной поддерживаемой версии была указана .NET 6. Следовательно, проекты, ориентированные на версии .NET ниже 6, такие как .NET Core 3.1 и .NET 5, больше не будут загружаться в дизайнере. Поэтому настоятельно рекомендуется обновить приложение до последней версии .NET, чтобы сохранить совместимость с Visual Studio 17.13 или более новыми версиями. Для миграции можно использовать дизайнер в Visual Studio 17.12.
Важное примечание: эти изменения повлияют только на работу дизайнера форм WinForms во время проектирования. Во время выполнения все версии .NET продолжат работать так же, как и сейчас.
Источник: https://devblogs.microsoft.com/visualstudio/upgrade-your-windows-forms-net-projects-to-the-latest-net-version-for-enhanced-security/
Обновите Проекты Windows Forms для Повышения Безопасности
Каждый выпуск .NET представляет множество новых функций и исправлений ошибок, которые повышают как производительность, так и безопасность. Чтобы воспользоваться этими преимуществами, разработчики как сервисных, так и настольных приложений должны обновить свои приложения до последних версий .NET. Последнее обновление повысит безопасность опыта разработки WinForms в Visual Studio и мотивирует разработчиков WinForms обновлять свои приложения для повышения безопасности. Также это означает, что больше не будут поддерживаться проектирование форм в проектах, ориентированных на старые, неподдерживаемые версии .NET. Т.е. разработчикам также необходимо будет обновить свои проекты до поддерживаемых сред выполнения .NET, чтобы создавать формы в Visual Studio.
Обновление WinForms Designer и ваших приложений до новых версий .NET не только повышает безопасность, но и улучшает надёжность и производительность во время разработки за счет использования улучшений, доступных в новых версиях .NET и связанных NuGet-пакетах. Настоятельно рекомендуется обновлять ваши приложения до последних версий .NET.
Начиная с выпуска VS 17.12 Preview 3, WinForms Designer будет автоматически проверять целевую версию .NET вашего проекта. Если она ниже минимальной поддерживаемой версии, вы получите уведомление. Эта функция будет держать вас в курсе совместимости вашего проекта, обеспечивая лёгкий доступ к списку версий .NET и статусу их поддержки.
Будущая поддержка WinForms Designer в отношении сред выполнения .NET
Каждый раз, когда поддержка LTS выпуска .NET будет заканчиваться, Visual Studio будет обновлять минимальную поддерживаемую версию утилиты дизайна форм до этой версии LTS. Например, поддержка .NET 6 прекратилась в ноябре 2024 года, следующий выпуск Visual Studio, 17.13, обновит дизайнер форм, чтобы в качестве минимальной поддерживаемой версии была указана .NET 6. Следовательно, проекты, ориентированные на версии .NET ниже 6, такие как .NET Core 3.1 и .NET 5, больше не будут загружаться в дизайнере. Поэтому настоятельно рекомендуется обновить приложение до последней версии .NET, чтобы сохранить совместимость с Visual Studio 17.13 или более новыми версиями. Для миграции можно использовать дизайнер в Visual Studio 17.12.
Важное примечание: эти изменения повлияют только на работу дизайнера форм WinForms во время проектирования. Во время выполнения все версии .NET продолжат работать так же, как и сейчас.
Источник: https://devblogs.microsoft.com/visualstudio/upgrade-your-windows-forms-net-projects-to-the-latest-net-version-for-enhanced-security/
День 2142. #ЗаметкиНаПолях
Пакеты NuGet: Риски Безопасности и Лучшие Практики. Начало
NuGet-пакеты предлагают удобный способ обмена кодом, но многие разработчики загружают их, не просматривая содержимое или не проверяя обновления при выпуске новых версий.
Когда вы устанавливаете NuGet-пакет, вы:
- Загружаете код неизвестных авторов, который, не обязательно был тщательно проверен другими;
- Запускаете его с полными правами на локальном компьютере, что потенциально раскрывает ваши персональные данные;
- Выполняете его с полным доступом на машинах непрерывной интеграции (CI), что подвергает риску ваши секреты и среду.
Рассмотрим, что может пойти не так.
Что может сделать NuGet-пакет?
1. props и targets в MSBuild
NuGet-пакет может содержать файлы MSBuild, которые автоматически импортируются при сборке проекта. Эти файлы могут изменить процесс сборки вашего приложения. Может быть запущен target, выполняющий команды, или динамический код C#. Также может изменяться код вашего приложения перед его сборкой.
Вы можете проверить содержимое файлов в папках build, buildMultitargeting и buildTransitive NuGet-пакета.
2. Анализаторы и генераторы исходного кода Roslyn
NuGet-пакеты могут содержать анализаторы Roslyn. Они выполняются во время проектирования в IDE и во время сборки и могут делать всё, что угодно на вашем компьютере. Хотя анализаторы предназначены для анализа кода, на самом деле они работают внутри процесса компиляции и могут делать всё (песочницы нет): писать файлы, обновлять двоичные файлы после компиляции и т.д.
Генераторы исходного кода Roslyn очень похожи на анализаторы, поэтому к ним применяются те же проблемы безопасности. Они также могут добавлять или обновлять код вашего приложения при его сборке.
Обратите внимание, что вы можете запретить загрузку анализаторов из пакета, используя свойства IncludeAssets или ExcludeAssets в файле .csproj. Например, вы можете использовать следующий код, чтобы загрузить только библиотеки из пакета:
См. подробнее об управлении ресурсами зависимостей.
3. Библиотеки
Вы уверены, что DLL в NuGet-пакете — те, которые вам нужны? Даже если код находится на GitHub, вы уверены, что DLL собраны из этого кода? Вы можете проверить содержимое DLL, декомпилировав его. Если символы (PDB) предоставлены и содержат правильную информацию, вы можете автоматически проверить, что код построен из предоставленного исходного кода.
4. Выполнение кода при установке/удалении пакета
NuGet-пакеты могут содержать скрипты PowerShell, которые выполняются при установке или удалении пакета. Обратите внимание, что эти скрипты выполняются только для проектов, которые не используют <PackageReference>. Поэтому для большинства современных проектов это не проблема.
Перед установкой пакета обязательно проверьте содержимое пакета. Вы можете сделать это, загрузив пакет и распаковав его. Обязательно проверьте следующие файлы:
Окончание следует…
Источник: https://meziantou.net/nuget-packages-security-risks-and-best-practices.htm
Пакеты NuGet: Риски Безопасности и Лучшие Практики. Начало
NuGet-пакеты предлагают удобный способ обмена кодом, но многие разработчики загружают их, не просматривая содержимое или не проверяя обновления при выпуске новых версий.
Когда вы устанавливаете NuGet-пакет, вы:
- Загружаете код неизвестных авторов, который, не обязательно был тщательно проверен другими;
- Запускаете его с полными правами на локальном компьютере, что потенциально раскрывает ваши персональные данные;
- Выполняете его с полным доступом на машинах непрерывной интеграции (CI), что подвергает риску ваши секреты и среду.
Рассмотрим, что может пойти не так.
Что может сделать NuGet-пакет?
1. props и targets в MSBuild
NuGet-пакет может содержать файлы MSBuild, которые автоматически импортируются при сборке проекта. Эти файлы могут изменить процесс сборки вашего приложения. Может быть запущен target, выполняющий команды, или динамический код C#. Также может изменяться код вашего приложения перед его сборкой.
Вы можете проверить содержимое файлов в папках build, buildMultitargeting и buildTransitive NuGet-пакета.
2. Анализаторы и генераторы исходного кода Roslyn
NuGet-пакеты могут содержать анализаторы Roslyn. Они выполняются во время проектирования в IDE и во время сборки и могут делать всё, что угодно на вашем компьютере. Хотя анализаторы предназначены для анализа кода, на самом деле они работают внутри процесса компиляции и могут делать всё (песочницы нет): писать файлы, обновлять двоичные файлы после компиляции и т.д.
Генераторы исходного кода Roslyn очень похожи на анализаторы, поэтому к ним применяются те же проблемы безопасности. Они также могут добавлять или обновлять код вашего приложения при его сборке.
Обратите внимание, что вы можете запретить загрузку анализаторов из пакета, используя свойства IncludeAssets или ExcludeAssets в файле .csproj. Например, вы можете использовать следующий код, чтобы загрузить только библиотеки из пакета:
<PackageReference Include="Some.Package" Version="3.2.1">
<IncludeAssets>compile</IncludeAssets>
</PackageReference>
См. подробнее об управлении ресурсами зависимостей.
3. Библиотеки
Вы уверены, что DLL в NuGet-пакете — те, которые вам нужны? Даже если код находится на GitHub, вы уверены, что DLL собраны из этого кода? Вы можете проверить содержимое DLL, декомпилировав его. Если символы (PDB) предоставлены и содержат правильную информацию, вы можете автоматически проверить, что код построен из предоставленного исходного кода.
4. Выполнение кода при установке/удалении пакета
NuGet-пакеты могут содержать скрипты PowerShell, которые выполняются при установке или удалении пакета. Обратите внимание, что эти скрипты выполняются только для проектов, которые не используют <PackageReference>. Поэтому для большинства современных проектов это не проблема.
Перед установкой пакета обязательно проверьте содержимое пакета. Вы можете сделать это, загрузив пакет и распаковав его. Обязательно проверьте следующие файлы:
tools/init.ps1
tools/install.ps1
tools/uninstall.ps1
Окончание следует…
Источник: https://meziantou.net/nuget-packages-security-risks-and-best-practices.htm
👍14
День 2143. #ЗаметкиНаПолях
Пакеты NuGet: Риски Безопасности и Передовой Опыт. Окончание
Начало
Другие векторы атаки
1. Тайпсквоттинг
Злоумышленник может создать пакет с именем похожим на популярный пакет. Например, Newtonsoft.Json можно заменить на Newtomsoft.Json или Newtomsoft-Json. Это называется тайпсквоттинг (атака через опечатки). Обязательно проверьте имя пакета перед его установкой.
Обратите внимание, что nuget.org позволяет резервировать префикс для предотвращения такого рода атак. Например, Newtonsoft – единственный автор, кто может создать пакет с префиксом Newtonsoft. Все его пакеты имеют галочку, указывающую на то, что они из зарезервированного префикса.
2. Тот же пакет, что и приватный пакет
Если у вас есть пакет, опубликованный во внутреннем канале, таком как Azure Packages, с тем же именем, что и у публичного пакета, публичный пакет можно использовать вместо приватного. Это проблема безопасности, поскольку вы не знаете содержимое публичного пакета. Вы можете использовать сопоставление источников пакетов, чтобы предотвратить эту проблему.
3. Удалённый пакет
Даже если вы проверили пакет и установили его, вы можете быть не в безопасности. На nuget.org вы не можете удалить пакет. Вы можете только пометить его как исключённый из списка (unlisted). Unlisted-пакет не отображается на веб-сайте или при разрешении графа пакетов. Но когда пакет обновляется, вы автоматически получаете новую версию. Это означает, что ваше приложение может использовать новую версию пакета, которую вы не проверили.
Чтобы предотвратить эту проблему, вы можете использовать файл блокировки (Lock-файл). Он содержит точную версию используемых вами пакетов. При восстановлении пакетов вы получаете точную версию, которую использовали ранее.
Лучшие практики
1. Проверяйте содержимое NuGet-пакета перед его установкой с помощью такого инструмента, как NuGet Package Explorer.
2. Используйте файл блокировки, чтобы предотвратить использование версии пакета, отличной от проверенной.
3. Используйте сопоставление источников пакетов, если ваш источник отличается от nuget.org.
4. Используйте IncludedAssets или ExcludedAssets для управления ресурсами, загруженными из пакета.
5. Проверяйте использование зарезервированного префикса, чтобы предотвратить тайпсквоттинг из-за опечаток
Итого
NuGet-пакет может:
- Выполнять код на вашем компьютере с разрешениями текущего пользователя.
- Выполнять код на CI-машинах с разрешениями пользователя CI.
- Изменять код вашего приложения и потенциально добавлять вредоносный код. Так он может выполнять код на ваших производственных компьютерах.
- Большинство пакетов безопасны, но вы не знаете, что может произойти в будущем. Взлом аккаунта NuGet или GitHub — это не редкость. Поэтому обязательно проверяйте содержимое пакетов, которые вы устанавливаете или обновляете.
И последнее, но не менее важное: другие менеджеры пакетов имеют похожие проблемы. Будьте бдительны при использовании любого пакета!
Источник: https://meziantou.net/nuget-packages-security-risks-and-best-practices.htm
Пакеты NuGet: Риски Безопасности и Передовой Опыт. Окончание
Начало
Другие векторы атаки
1. Тайпсквоттинг
Злоумышленник может создать пакет с именем похожим на популярный пакет. Например, Newtonsoft.Json можно заменить на Newtomsoft.Json или Newtomsoft-Json. Это называется тайпсквоттинг (атака через опечатки). Обязательно проверьте имя пакета перед его установкой.
Обратите внимание, что nuget.org позволяет резервировать префикс для предотвращения такого рода атак. Например, Newtonsoft – единственный автор, кто может создать пакет с префиксом Newtonsoft. Все его пакеты имеют галочку, указывающую на то, что они из зарезервированного префикса.
2. Тот же пакет, что и приватный пакет
Если у вас есть пакет, опубликованный во внутреннем канале, таком как Azure Packages, с тем же именем, что и у публичного пакета, публичный пакет можно использовать вместо приватного. Это проблема безопасности, поскольку вы не знаете содержимое публичного пакета. Вы можете использовать сопоставление источников пакетов, чтобы предотвратить эту проблему.
3. Удалённый пакет
Даже если вы проверили пакет и установили его, вы можете быть не в безопасности. На nuget.org вы не можете удалить пакет. Вы можете только пометить его как исключённый из списка (unlisted). Unlisted-пакет не отображается на веб-сайте или при разрешении графа пакетов. Но когда пакет обновляется, вы автоматически получаете новую версию. Это означает, что ваше приложение может использовать новую версию пакета, которую вы не проверили.
Чтобы предотвратить эту проблему, вы можете использовать файл блокировки (Lock-файл). Он содержит точную версию используемых вами пакетов. При восстановлении пакетов вы получаете точную версию, которую использовали ранее.
Лучшие практики
1. Проверяйте содержимое NuGet-пакета перед его установкой с помощью такого инструмента, как NuGet Package Explorer.
2. Используйте файл блокировки, чтобы предотвратить использование версии пакета, отличной от проверенной.
3. Используйте сопоставление источников пакетов, если ваш источник отличается от nuget.org.
4. Используйте IncludedAssets или ExcludedAssets для управления ресурсами, загруженными из пакета.
5. Проверяйте использование зарезервированного префикса, чтобы предотвратить тайпсквоттинг из-за опечаток
Итого
NuGet-пакет может:
- Выполнять код на вашем компьютере с разрешениями текущего пользователя.
- Выполнять код на CI-машинах с разрешениями пользователя CI.
- Изменять код вашего приложения и потенциально добавлять вредоносный код. Так он может выполнять код на ваших производственных компьютерах.
- Большинство пакетов безопасны, но вы не знаете, что может произойти в будущем. Взлом аккаунта NuGet или GitHub — это не редкость. Поэтому обязательно проверяйте содержимое пакетов, которые вы устанавливаете или обновляете.
И последнее, но не менее важное: другие менеджеры пакетов имеют похожие проблемы. Будьте бдительны при использовании любого пакета!
Источник: https://meziantou.net/nuget-packages-security-risks-and-best-practices.htm
👍14
День 2144. #Оффтоп
Развлекаемся с ValueTuple
Этот пост, скорее всего, не принесёт вам никакой пользы в вашей повседневной жизни — ну, разве что улыбку. Сегодня мы доведём ValueTuple до крайности!
Тип ValueTuple — это приятный синтаксический сахар. Если у вас есть следующий код, даже если вы назвали элементы кортежа:
Это будет преобразовано компилятором в:
Итак, компилятор генерирует список элементов, пронумерованных от 1 до любого количества элементов, которые у вас есть. Но происходит что-то интересное, если вы добавляете больше 7 элементов:
Это преобразовывается компилятором в:
После 7го элемента компилятор генерирует новое свойство Rest для хранения… ну, остального. Поэтому, если мы немного посходим с ума:
И используем это так:
То мы получим что-то вроде
Если хотите поиграть с этим, заходите на sharblap.io.
Источник: https://steven-giesel.com/blogPost/0a3db64c-e514-45fc-a1a1-2b79cc42f797/having-fun-with-valuetuple
Развлекаемся с ValueTuple
Этот пост, скорее всего, не принесёт вам никакой пользы в вашей повседневной жизни — ну, разве что улыбку. Сегодня мы доведём ValueTuple до крайности!
Тип ValueTuple — это приятный синтаксический сахар. Если у вас есть следующий код, даже если вы назвали элементы кортежа:
(var one, var two) = MyFunc();
Console.WriteLine(one + two);
(int ANumber, int AnotherNumber)
MyFunc() => (1,2);
Это будет преобразовано компилятором в:
[CompilerGenerated]
internal class Program
{
private static void <Main>$(string[] args)
{
ValueTuple<int, int> valueTuple = <<Main>$>g__MyFunc|0_0();
int item = valueTuple.Item1;
int item2 = valueTuple.Item2;
Console.WriteLine(item + item2);
}
[CompilerGenerated]
[return: TupleElementNames(new string[] { "ANumber", "AnotherNumber" })]
internal static ValueTuple<int, int> <<Main>$>g__MyFunc|0_0()
{
return new ValueTuple<int, int>(1, 2);
}
}
Итак, компилятор генерирует список элементов, пронумерованных от 1 до любого количества элементов, которые у вас есть. Но происходит что-то интересное, если вы добавляете больше 7 элементов:
var (a,b,c,d,e,f,g,h) = MyFunc();
Console.WriteLine(a+b+c+d+e+f+g+h);
(int a, int b, int c, int d, int e, int f, int g, int h) MyFunc()
=> (1,2,3,4,5,6,7,8);
Это преобразовывается компилятором в:
ValueTuple<int, int, int, int, int, int, int, ValueTuple<int>> valueTuple = <<Main>$>g__MyFunc|0_0();
int item = valueTuple.Item1;
int item2 = valueTuple.Item2;
int item3 = valueTuple.Item3;
int item4 = valueTuple.Item4;
int item5 = valueTuple.Item5;
int item6 = valueTuple.Item6;
int item7 = valueTuple.Item7;
int item8 = valueTuple.Rest.Item1;
Console.WriteLine(item + item2 + item3 + item4 + item5 + item6 + item7 + item8);
После 7го элемента компилятор генерирует новое свойство Rest для хранения… ну, остального. Поэтому, если мы немного посходим с ума:
(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z, int aa, int bb, int cc, int dd, int ee, int ff, int gg, int hh, int ii, int jj, int kk, int ll, int mm, int nn, int oo, int pp, int qq, int rr, int ss, int tt, int uu, int vv, int ww, int xx) MyFunc()
{
return (1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50);
}
И используем это так:
var (a,b,c,…,xx) = MyFunc();
То мы получим что-то вроде
valueTuple.Rest.Rest.Rest.Rest.Item1
.Если хотите поиграть с этим, заходите на sharblap.io.
Источник: https://steven-giesel.com/blogPost/0a3db64c-e514-45fc-a1a1-2b79cc42f797/having-fun-with-valuetuple
👍22👎1
День 2145. #Карьера
Метрика Улучшения
В аэропорту при проходе через службу безопасности можно наблюдать интересный момент. Используем эту аналогию, чтобы поразмышлять о том, что люди делают с кодом.
Вы складываете вещи в контейнеры, отправляете их по ленте, и проходите через рамку. Дальше все стоят и ждут свои вещи. Телефонов в руках нет, поэтому их ничто не отвлекает. Контейнеры приезжают по ленте, и люди забирают свои вещи. И часто нет специально выделенного человека, который бы убирал контейнеры. Так можно выделить несколько групп людей.
Группа A
Большинство берут свои вещи, но оставляют контейнеры на ленте, по сути, создавая кучу пустых контейнеров, что в итоге заставляет кого-то другого убрать их с ленты, чтобы освободить место для своего контейнера. Эти люди выполнили свои задачи, но оставили технический долг для уборки другими.
Группа B
Другие берут свои вещи и снимают контейнер с ленты, приложив дополнительные усилия, чтобы не оставлять окружающую среду хуже, чем она была.
Группа C
Небольшая группа складывает все контейнеры и очищает ленту, но только когда лента заполнена, то есть они действуют так только для того, чтобы освободить место для своего контейнера.
Группа D
Наконец, несколько человек (меньшинство) используют своё время ожидания, чтобы улучшить систему для всех. Они убирают все оставшиеся контейнеры, чтобы очистить ленту, даже когда лента не заполнена.
Одной из метрик оценки качества программиста, которую можно использовать, является «Улучшение» (Betterment). Может ли программист определять области для улучшения и делает ли он их лучше без подсказок?
Некоторым может быть сложно представить, как они могут улучшить работу. Этот небольшой пример служит отличной аналогией для применения показателя улучшения.
Группа A: ниже ожиданий
Эта группа сосредоточилась только на достижении собственных целей, непреднамеренно ухудшая систему, оставляя больше работы другим.
Группа B: соответствуют ожиданиям
Эта группа не только сосредоточилась на своих целях, но и позаботилась о том, чтобы оставить систему нетронутой.
Группа C: соответствуют ожиданиям
Хотя эта группа действительно улучшила систему, их усилия были ситуативными и реактивными, и происходили только тогда, когда препятствие мешало им достичь своей цели.
Группа D: превышают ожидания
Эта группа последовательно действовала, чтобы очистить ленту и улучшить систему, обеспечивая бесперебойную работу для всех, даже когда это не было их работой или напрямую не влияло на них.
Будь то проход через службу безопасности в аэропорту или ваша кодовая база, вопрос в том, к какой группе вы хотите принадлежать?
Источник: https://angiejones.tech/the-betterment-metric/
Метрика Улучшения
В аэропорту при проходе через службу безопасности можно наблюдать интересный момент. Используем эту аналогию, чтобы поразмышлять о том, что люди делают с кодом.
Вы складываете вещи в контейнеры, отправляете их по ленте, и проходите через рамку. Дальше все стоят и ждут свои вещи. Телефонов в руках нет, поэтому их ничто не отвлекает. Контейнеры приезжают по ленте, и люди забирают свои вещи. И часто нет специально выделенного человека, который бы убирал контейнеры. Так можно выделить несколько групп людей.
Группа A
Большинство берут свои вещи, но оставляют контейнеры на ленте, по сути, создавая кучу пустых контейнеров, что в итоге заставляет кого-то другого убрать их с ленты, чтобы освободить место для своего контейнера. Эти люди выполнили свои задачи, но оставили технический долг для уборки другими.
Группа B
Другие берут свои вещи и снимают контейнер с ленты, приложив дополнительные усилия, чтобы не оставлять окружающую среду хуже, чем она была.
Группа C
Небольшая группа складывает все контейнеры и очищает ленту, но только когда лента заполнена, то есть они действуют так только для того, чтобы освободить место для своего контейнера.
Группа D
Наконец, несколько человек (меньшинство) используют своё время ожидания, чтобы улучшить систему для всех. Они убирают все оставшиеся контейнеры, чтобы очистить ленту, даже когда лента не заполнена.
Одной из метрик оценки качества программиста, которую можно использовать, является «Улучшение» (Betterment). Может ли программист определять области для улучшения и делает ли он их лучше без подсказок?
Некоторым может быть сложно представить, как они могут улучшить работу. Этот небольшой пример служит отличной аналогией для применения показателя улучшения.
Группа A: ниже ожиданий
Эта группа сосредоточилась только на достижении собственных целей, непреднамеренно ухудшая систему, оставляя больше работы другим.
Группа B: соответствуют ожиданиям
Эта группа не только сосредоточилась на своих целях, но и позаботилась о том, чтобы оставить систему нетронутой.
Группа C: соответствуют ожиданиям
Хотя эта группа действительно улучшила систему, их усилия были ситуативными и реактивными, и происходили только тогда, когда препятствие мешало им достичь своей цели.
Группа D: превышают ожидания
Эта группа последовательно действовала, чтобы очистить ленту и улучшить систему, обеспечивая бесперебойную работу для всех, даже когда это не было их работой или напрямую не влияло на них.
Будь то проход через службу безопасности в аэропорту или ваша кодовая база, вопрос в том, к какой группе вы хотите принадлежать?
Источник: https://angiejones.tech/the-betterment-metric/
👍12
День 2146. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Урок 35. От передачи знаний выигрывают все
Знания не похожи на материальные предметы. Если у меня есть 3 штуки чего-то, и я дам вам 1, то у меня останется 2. Я должен потерять часть, чтобы вы что-то приобрели. Но со знаниями дело обстоит иначе: если я передам вам часть своих знаний, то не потеряю их. Я могу поделиться ими с другими людьми, как и вы. Этот расширяющийся круг знаний приносит пользу всем.
Пожиратели знаний
Некоторые неохотно передают свои знания из-за неуверенности. Они опасаются, что, поделившись с другими своими знаниями, добытыми с таким трудом, станут менее конкурентоспособными. Некоторые тщательно охраняют свои знания, стремясь получить гарантии своей востребованности. Если никто другой не знает того, что знают они, то компания не сможет их уволить, поскольку потеряет слишком много специфических знаний.
Люди, скрывающие организационные знания, представляют опасность. Они создают среду, которая может помешать работе других людей. Сокрытие информации является отличной практикой для проектирования ПО, но плохо подходит для команд разработчиков.
Исправление невежества
Здоровая организация способствует культуре свободного обмена знаниями и непрерывного обучения. Обмен знаниями повышает продуктивность каждого, поэтому руководство должно вознаграждать тех, кто свободно передаёт свои знания, а не тех, кто держит их при себе. В организации, поощряющей обучение, члены команды уверены, что могут без опаски задавать вопросы.
Опытные сотрудники могут передавать свой опыт разными путями. Помимо простых ответов на вопросы, эксперты могут делиться своими мыслями о том, как применять знания в конкретных ситуациях. Они должны быть доступными для коллег, особенно новичков, и быть вдумчивыми и терпеливыми, когда кто-то донимает их расспросами.
В некоторых организациях существуют официальные программы наставничества, помогающие ускорить адаптацию новых сотрудников. Закрепление новых сотрудников за опытными коллегами-наставниками значительно ускоряет обучение.
Расширение масштабов передачи знаний
Для развития культуры обмена знаниями есть несколько вариантов, кроме общения 1 на 1.
1. Технические беседы
Можно обсуждать прочитанные книги или статьи с коллегами за обедом. Это способствует формированию общего понимания материала и общего словарного запаса.
2. Презентации и обучение
Если вы создаёте внутреннюю программу обучения, подберите несколько квалифицированных инструкторов, чтобы одному человеку не приходилось всё время читать одни и те же курсы.
3. Документация
Письменная документация — очень эффективный организационный актив при условии, что члены команды воспринимают его как полезный ресурс. Все члены организации должны иметь возможность обновлять такие документы, чтобы они оставались ценными источниками коллективного опыта.
4. Готовые шаблоны и примеры
Можно создать репозиторий кода с примерами шаблонов и лучших практик, используемых в компании.
5. Технические обзоры
Обзоры кода тоже могут служить неформальным механизмом обмена техническими знаниями. Это отличный способ посмотреть, как работает другой человек, и позволить ему понаблюдать за вашей работой.
6. Дискуссионные группы
Можно опубликовать вопрос в групповом чате компании. Признаваться в незнании перед большим сообществом может быть неудобно. Поэтому важно развивать культуру, в которой поощряется желание задавать вопросы и вознаграждаются те, кто помогает получить на них ответ. Не стыдно не знать, стыдно не учиться.
Здоровая информационная культура
Необязательно быть экспертом в какой-то теме, чтобы быть полезным. Нужен лишь какой-то ценный блок знаний и готовность поделиться ими. В мире технологий, если вы на неделю опережаете другого человека в какой-либо области, то вы волшебник. Кто-то другой, несомненно, опережает вас в других областях, поэтому воспользуйтесь его знаниями. Люди в здоровой культуре обучения делятся тем, что они знают, а также признают, что кто-то другой может знать способ лучше.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
Уроки 50 Лет Разработки ПО
Урок 35. От передачи знаний выигрывают все
Знания не похожи на материальные предметы. Если у меня есть 3 штуки чего-то, и я дам вам 1, то у меня останется 2. Я должен потерять часть, чтобы вы что-то приобрели. Но со знаниями дело обстоит иначе: если я передам вам часть своих знаний, то не потеряю их. Я могу поделиться ими с другими людьми, как и вы. Этот расширяющийся круг знаний приносит пользу всем.
Пожиратели знаний
Некоторые неохотно передают свои знания из-за неуверенности. Они опасаются, что, поделившись с другими своими знаниями, добытыми с таким трудом, станут менее конкурентоспособными. Некоторые тщательно охраняют свои знания, стремясь получить гарантии своей востребованности. Если никто другой не знает того, что знают они, то компания не сможет их уволить, поскольку потеряет слишком много специфических знаний.
Люди, скрывающие организационные знания, представляют опасность. Они создают среду, которая может помешать работе других людей. Сокрытие информации является отличной практикой для проектирования ПО, но плохо подходит для команд разработчиков.
Исправление невежества
Здоровая организация способствует культуре свободного обмена знаниями и непрерывного обучения. Обмен знаниями повышает продуктивность каждого, поэтому руководство должно вознаграждать тех, кто свободно передаёт свои знания, а не тех, кто держит их при себе. В организации, поощряющей обучение, члены команды уверены, что могут без опаски задавать вопросы.
Опытные сотрудники могут передавать свой опыт разными путями. Помимо простых ответов на вопросы, эксперты могут делиться своими мыслями о том, как применять знания в конкретных ситуациях. Они должны быть доступными для коллег, особенно новичков, и быть вдумчивыми и терпеливыми, когда кто-то донимает их расспросами.
В некоторых организациях существуют официальные программы наставничества, помогающие ускорить адаптацию новых сотрудников. Закрепление новых сотрудников за опытными коллегами-наставниками значительно ускоряет обучение.
Расширение масштабов передачи знаний
Для развития культуры обмена знаниями есть несколько вариантов, кроме общения 1 на 1.
1. Технические беседы
Можно обсуждать прочитанные книги или статьи с коллегами за обедом. Это способствует формированию общего понимания материала и общего словарного запаса.
2. Презентации и обучение
Если вы создаёте внутреннюю программу обучения, подберите несколько квалифицированных инструкторов, чтобы одному человеку не приходилось всё время читать одни и те же курсы.
3. Документация
Письменная документация — очень эффективный организационный актив при условии, что члены команды воспринимают его как полезный ресурс. Все члены организации должны иметь возможность обновлять такие документы, чтобы они оставались ценными источниками коллективного опыта.
4. Готовые шаблоны и примеры
Можно создать репозиторий кода с примерами шаблонов и лучших практик, используемых в компании.
5. Технические обзоры
Обзоры кода тоже могут служить неформальным механизмом обмена техническими знаниями. Это отличный способ посмотреть, как работает другой человек, и позволить ему понаблюдать за вашей работой.
6. Дискуссионные группы
Можно опубликовать вопрос в групповом чате компании. Признаваться в незнании перед большим сообществом может быть неудобно. Поэтому важно развивать культуру, в которой поощряется желание задавать вопросы и вознаграждаются те, кто помогает получить на них ответ. Не стыдно не знать, стыдно не учиться.
Здоровая информационная культура
Необязательно быть экспертом в какой-то теме, чтобы быть полезным. Нужен лишь какой-то ценный блок знаний и готовность поделиться ими. В мире технологий, если вы на неделю опережаете другого человека в какой-либо области, то вы волшебник. Кто-то другой, несомненно, опережает вас в других областях, поэтому воспользуйтесь его знаниями. Люди в здоровой культуре обучения делятся тем, что они знают, а также признают, что кто-то другой может знать способ лучше.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
10👍12
День 2147. #ЧтоНовенького
Новинки Visual Studio 17.12
В новой версии Visual Studio 2022 (17.12) представлено несколько интересных новинок.
1. Уведомление о переименовании файла
Часто возникает путаница в том, как работает Git при переименовании файлов. Git не хранит никакой информации для отслеживания переименований. Даже когда вы запускаете операцию git mv, это всего лишь сокращение для выполнения git rm, а затем git add для файла. Иногда Git запускает обнаружение переименования и может отображать удаление+добавление как переименование, но под капотом он использует эвристику, основанную на сходстве двух файлов, чтобы назвать это переименованием — и иногда он ошибается!
Когда вы переименовываете файл в Solution Explorer и смотрите на список изменённых файлов, это отображается как удаление+добавление. После того как вы сделаете Stage изменений, Git запустит обнаружение переименования, и вы сможете увидеть, как он заменит удаление+добавление на переименование в разделе Stage. Чтобы напоминать вам об этом, и добавлено новое уведомление.
2. Постоянная ссылка на код
Если вам нужно поделиться фрагментом кода с коллегами, вы знаете, как сложно сохранить контекст. С новой функцией Copy Git Permalink (Копировать Постоянную Ссылку на Git) вы теперь можете создать постоянную ссылку непосредственно из VS на удалённый репозиторий. Просто выберите нужный код, щёлкните правой кнопкой мыши и выберите Git > Copy Permalink. Ваш коллега сможет открыть ссылку, которой вы поделились, чтобы перейти к этой строке кода в интернет. Функция поддерживает репозитории Azure DevOps и GitHub (требуется вход в систему).
3. Подсказка о возвращаемых значениях
Вы когда-нибудь создавали временные переменные, только чтобы проверить возвращаемые значения функций? Эта новая функция позволит просматривать возвращаемые значения непосредственно в коде.
Раньше можно было посмотреть возвращаемые значения в окнах Autos или Locals. Они появляются после выхода из функции и возврата вызывающей стороне. Новая функция показывает эту информацию до выхода из функции и непосредственно в редакторе. Когда вы достигаете точки останова или проходите по коду, VS 2022 автоматически отображает значение, которое будет возвращено, в строке рядом с закрывающей скобкой метода.
Чтобы подробнее изучить возвращаемые значения, наведите указатель мыши это него и щёлкните значок Ask Copilot (Спросить Copilot) на подсказке по данным. Откроется новое окно чата Copilot, отладчик соберёт соответствующий контекст и передаст его Copilot для анализа. Copilot объяснит, почему вы видите это значение, предоставит информацию о потенциальных проблемах и даже сможет предложить исправления кода.
4. Неблокирующая очистка кода
Традиционный процесс Code Cleanup в VS может занимать некоторое время и заблокировать всю IDE, что делало его нецелесообразным для запуска при каждом сохранении. Теперь, когда вы сохраняете свою работу, Code Cleanup может работать в фоновом режиме, не прерывая ваш рабочий процесс. Больше не нужно ждать завершения очистки, прежде чем возобновить работу. Если вам нужно внести изменения, то, когда редактор обнаруживает пользовательский ввод, процесс очистки останавливается. Сохранитесь ещё раз, чтобы перезапустить очистку обновленного кода.
Включить очистку кода при сохранении можно в меню Tools > Options > Text Editor > Code Cleanup (Инструменты > Опции > Текстовый Редактор > Очистка Кода).
Источники:
- https://devblogs.microsoft.com/visualstudio/boost-your-git-confidence-with-the-new-file-rename-notification/
- https://devblogs.microsoft.com/visualstudio/introducing-the-copy-git-permalink-feature-in-visual-studio-17-12/
- https://devblogs.microsoft.com/visualstudio/how-inline-return-values-simplify-debugging-in-visual-studio-2022/
- https://devblogs.microsoft.com/visualstudio/keep-working-with-non-blocking-code-cleanup/
Новинки Visual Studio 17.12
В новой версии Visual Studio 2022 (17.12) представлено несколько интересных новинок.
1. Уведомление о переименовании файла
Часто возникает путаница в том, как работает Git при переименовании файлов. Git не хранит никакой информации для отслеживания переименований. Даже когда вы запускаете операцию git mv, это всего лишь сокращение для выполнения git rm, а затем git add для файла. Иногда Git запускает обнаружение переименования и может отображать удаление+добавление как переименование, но под капотом он использует эвристику, основанную на сходстве двух файлов, чтобы назвать это переименованием — и иногда он ошибается!
Когда вы переименовываете файл в Solution Explorer и смотрите на список изменённых файлов, это отображается как удаление+добавление. После того как вы сделаете Stage изменений, Git запустит обнаружение переименования, и вы сможете увидеть, как он заменит удаление+добавление на переименование в разделе Stage. Чтобы напоминать вам об этом, и добавлено новое уведомление.
2. Постоянная ссылка на код
Если вам нужно поделиться фрагментом кода с коллегами, вы знаете, как сложно сохранить контекст. С новой функцией Copy Git Permalink (Копировать Постоянную Ссылку на Git) вы теперь можете создать постоянную ссылку непосредственно из VS на удалённый репозиторий. Просто выберите нужный код, щёлкните правой кнопкой мыши и выберите Git > Copy Permalink. Ваш коллега сможет открыть ссылку, которой вы поделились, чтобы перейти к этой строке кода в интернет. Функция поддерживает репозитории Azure DevOps и GitHub (требуется вход в систему).
3. Подсказка о возвращаемых значениях
Вы когда-нибудь создавали временные переменные, только чтобы проверить возвращаемые значения функций? Эта новая функция позволит просматривать возвращаемые значения непосредственно в коде.
Раньше можно было посмотреть возвращаемые значения в окнах Autos или Locals. Они появляются после выхода из функции и возврата вызывающей стороне. Новая функция показывает эту информацию до выхода из функции и непосредственно в редакторе. Когда вы достигаете точки останова или проходите по коду, VS 2022 автоматически отображает значение, которое будет возвращено, в строке рядом с закрывающей скобкой метода.
Чтобы подробнее изучить возвращаемые значения, наведите указатель мыши это него и щёлкните значок Ask Copilot (Спросить Copilot) на подсказке по данным. Откроется новое окно чата Copilot, отладчик соберёт соответствующий контекст и передаст его Copilot для анализа. Copilot объяснит, почему вы видите это значение, предоставит информацию о потенциальных проблемах и даже сможет предложить исправления кода.
4. Неблокирующая очистка кода
Традиционный процесс Code Cleanup в VS может занимать некоторое время и заблокировать всю IDE, что делало его нецелесообразным для запуска при каждом сохранении. Теперь, когда вы сохраняете свою работу, Code Cleanup может работать в фоновом режиме, не прерывая ваш рабочий процесс. Больше не нужно ждать завершения очистки, прежде чем возобновить работу. Если вам нужно внести изменения, то, когда редактор обнаруживает пользовательский ввод, процесс очистки останавливается. Сохранитесь ещё раз, чтобы перезапустить очистку обновленного кода.
Включить очистку кода при сохранении можно в меню Tools > Options > Text Editor > Code Cleanup (Инструменты > Опции > Текстовый Редактор > Очистка Кода).
Источники:
- https://devblogs.microsoft.com/visualstudio/boost-your-git-confidence-with-the-new-file-rename-notification/
- https://devblogs.microsoft.com/visualstudio/introducing-the-copy-git-permalink-feature-in-visual-studio-17-12/
- https://devblogs.microsoft.com/visualstudio/how-inline-return-values-simplify-debugging-in-visual-studio-2022/
- https://devblogs.microsoft.com/visualstudio/keep-working-with-non-blocking-code-cleanup/
👍10
День 2148. #ЗаметкиНаПолях
Гибридный Кэш в ASP.NET Core 9. Начало
В .NET 9 представлен гибридный кэш (HybridCache), механизм кэширования, который сочетает скорость кэширования в памяти с масштабируемостью распределённого кэширования. Я уже писал о новинке тут. Теперь рассмотрим его подробнее.
Что это?
HybridCache — это абстрактный класс с реализацией по умолчанию, который обрабатывает большинство аспектов сохранения в кэш и извлечения из кэша. HybridCache также включает в себя некоторые важные функции, относящиеся к процессу кэширования:
- Двухуровневое кэширование (L1/L2)
Использует быстрый кэш в памяти (L1) для быстрого извлечения данных и распределённый кэш (L2) для согласованности данных в нескольких экземплярах приложения.
- Защита от паники в кэше
Предотвращает панику в кэше при нескольких параллельных запросах, гарантируя, что только один запрос извлекает данные, а другие ждут, что снижает ненужную нагрузку.
- Инвалидация на основе тегов
Позволяет группировать записи кэша тегами, что обеспечивает эффективное удаление связанных элементов кэша одновременно.
- Настраиваемая сериализация
Позволяет настраивать методы сериализации данных, поддерживая различные форматы, такие как JSON, Protobuf или XML, в соответствии с потребностями конкретного приложения.
Добавляем гибридный кэш в .NET 9
1. Установим NuGet-пакет
2. Зарегистрируем сервис
Cвойства HybridCacheOptions позволяют настраивать ограничения, применяемые ко всем записям кэша:
- MaximumPayloadBytes — максимальный размер записи кэша. Значение по умолчанию — 1 МБ.
- MaximumKeyLength — максимальная длина ключа. Значение по умолчанию — 1024 символа.
Попытки сохранить значения, превышающие эти размеры, записываются в лог, но значение не сохраняется в кэше.
- DefaultEntryOptions – настраивает время хранения элементов в кэше: Expiration – общее время хранения элемента, LocalCacheExpiration – время хранения элемента в кэше L1.
3. Настроим распределённый кэш (не обязательно)
Например, используем Redis:
Это делать не обязательно, т.к. HybridCache может работать и как кэш только в памяти.
Окончание следует…
Источник: https://thecodeman.net/posts/hybrid-cache-in-aspnet-core
Гибридный Кэш в ASP.NET Core 9. Начало
В .NET 9 представлен гибридный кэш (HybridCache), механизм кэширования, который сочетает скорость кэширования в памяти с масштабируемостью распределённого кэширования. Я уже писал о новинке тут. Теперь рассмотрим его подробнее.
Что это?
HybridCache — это абстрактный класс с реализацией по умолчанию, который обрабатывает большинство аспектов сохранения в кэш и извлечения из кэша. HybridCache также включает в себя некоторые важные функции, относящиеся к процессу кэширования:
- Двухуровневое кэширование (L1/L2)
Использует быстрый кэш в памяти (L1) для быстрого извлечения данных и распределённый кэш (L2) для согласованности данных в нескольких экземплярах приложения.
- Защита от паники в кэше
Предотвращает панику в кэше при нескольких параллельных запросах, гарантируя, что только один запрос извлекает данные, а другие ждут, что снижает ненужную нагрузку.
- Инвалидация на основе тегов
Позволяет группировать записи кэша тегами, что обеспечивает эффективное удаление связанных элементов кэша одновременно.
- Настраиваемая сериализация
Позволяет настраивать методы сериализации данных, поддерживая различные форматы, такие как JSON, Protobuf или XML, в соответствии с потребностями конкретного приложения.
Добавляем гибридный кэш в .NET 9
1. Установим NuGet-пакет
dotnet add package Microsoft.Extensions.Caching.Hybrid
2. Зарегистрируем сервис
builder.Services.AddHybridCache(opts =>
{
opts.MaximumPayloadBytes = 1024 * 1024; // 1 MB
opts.MaximumKeyLength = 512;
opts.DefaultEntryOptions = new HybridCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(30),
LocalCacheExpiration = TimeSpan.FromMinutes(30)
};
});
Cвойства HybridCacheOptions позволяют настраивать ограничения, применяемые ко всем записям кэша:
- MaximumPayloadBytes — максимальный размер записи кэша. Значение по умолчанию — 1 МБ.
- MaximumKeyLength — максимальная длина ключа. Значение по умолчанию — 1024 символа.
Попытки сохранить значения, превышающие эти размеры, записываются в лог, но значение не сохраняется в кэше.
- DefaultEntryOptions – настраивает время хранения элементов в кэше: Expiration – общее время хранения элемента, LocalCacheExpiration – время хранения элемента в кэше L1.
3. Настроим распределённый кэш (не обязательно)
Например, используем Redis:
builder.Services
.AddStackExchangeRedisCache(opts =>
{
opts.Configuration = "connectionString";
});
Это делать не обязательно, т.к. HybridCache может работать и как кэш только в памяти.
Окончание следует…
Источник: https://thecodeman.net/posts/hybrid-cache-in-aspnet-core
👍22
День 2149. #ЗаметкиНаПолях
Гибридный Кэш в ASP.NET Core 9. Окончание
Начало
Используем HybridCache
Допустим, у нас есть API, предоставляющий информацию о продукте. Часто используемые данные будут кэшироваться для повышения производительности:
1. L1 (в памяти) - для обслуживания быстрых чтений из локального кэша.
2. L2 (Redis) - для обеспечения согласованности данных в распределённых экземплярах.
Как это работает
1. Метод проверяет, существует ли key в HybridCache. Если да, возвращаются кэшированные данные (из L1, если доступно; в противном случае из L2).
2. Если данные отсутствуют в кэшах L1 и L2, вызывается делегат (FetchFromDB) для извлечения данных из базы данных.
3. После извлечения данных они сохраняются в кэшах L1 и L2 с указанными политиками истечения срока действия (HybridCacheEntryOptions - их можно задать для всех элементов при регистрации кэша, либо в перегруженной версии GetOrCreateAsync).
4. Метод возвращает список продуктов либо из кэша, либо после извлечения из базы данных.
Удаление данных из кэша
Можно использовать метод RemoveAsync:
Запись удаляется из кэшей L1 и L2. Если ключ не существует, метод не делает ничего.
Добавление элементов с тегами
При сохранении записей в кэше вы можете назначать теги для их логической группировки. Для этого используется перегрузка GetOrCreateAsync:
Здесь мы задаём другие параметры истечения срока действия, а также тег для элементов.
Чтобы удалить все элементы, имеющие определённый тэг, используется метод RemoveByTagAsync:
Источник: https://thecodeman.net/posts/hybrid-cache-in-aspnet-core
Гибридный Кэш в ASP.NET Core 9. Окончание
Начало
Используем HybridCache
Допустим, у нас есть API, предоставляющий информацию о продукте. Часто используемые данные будут кэшироваться для повышения производительности:
1. L1 (в памяти) - для обслуживания быстрых чтений из локального кэша.
2. L2 (Redis) - для обеспечения согласованности данных в распределённых экземплярах.
public class ProductService(
HybridCache cache)
{
public async Task<List<Product>>
GetProductsByCategoryAsync(
string category,
CancellationToken ct = default)
{
var key = $"products:category:{category}";
return await cache.GetOrCreateAsync(
key,
async token =>
await FetchFromDB(category, token),
ct
);
}
}
Как это работает
1. Метод проверяет, существует ли key в HybridCache. Если да, возвращаются кэшированные данные (из L1, если доступно; в противном случае из L2).
2. Если данные отсутствуют в кэшах L1 и L2, вызывается делегат (FetchFromDB) для извлечения данных из базы данных.
3. После извлечения данных они сохраняются в кэшах L1 и L2 с указанными политиками истечения срока действия (HybridCacheEntryOptions - их можно задать для всех элементов при регистрации кэша, либо в перегруженной версии GetOrCreateAsync).
4. Метод возвращает список продуктов либо из кэша, либо после извлечения из базы данных.
Удаление данных из кэша
Можно использовать метод RemoveAsync:
public async Task RemoveFromCache(
string category,
CancellationToken ct = default)
{
var key = $"products:category:{category}";
await cache.RemoveAsync(key, ct);
}
Запись удаляется из кэшей L1 и L2. Если ключ не существует, метод не делает ничего.
Добавление элементов с тегами
При сохранении записей в кэше вы можете назначать теги для их логической группировки. Для этого используется перегрузка GetOrCreateAsync:
// …
return await cache.GetOrCreateAsync(
key,
async token =>
await FetchFromDB(category, token),
new HybridCacheEntryOptions
{
Expiration = TimeSpan.FromMinutes(10),
LocalCacheExpiration = TimeSpan.FromMinutes(5),
Tags = new List<string> { $"category:{category}" }
},
ct
);
Здесь мы задаём другие параметры истечения срока действия, а также тег для элементов.
Чтобы удалить все элементы, имеющие определённый тэг, используется метод RemoveByTagAsync:
public async Task InvalidateByTag(
string tag,
CancellationToken ct = default
)
{
await _cache.RemoveByTagAsync(tag, ct);
}
Источник: https://thecodeman.net/posts/hybrid-cache-in-aspnet-core
👍13
День 2150. #ЧтоНовенького #NET10
Заглядываем в .NET 10
9я версия .NET вышла всего месяц назад, а уже появляются предложения того, что может появиться через год в юбилейной 10й версии.
1. «Левое объединение» в LINQ
В LINQ есть оператор Join, который чаще всего в SQL преобразуется во что-то вроде INNER JOIN. В LINQ нет встроенного оператора для LEFT JOIN, но вы можете достичь того же результата, используя комбинацию GroupJoin, SelectMany и DefaultIfEmpty:
Имейте в виду, если вы хотите объединить несколько столбцов, они должны иметь одинаковые имена и типы данных.
Теперь появилось предложение добавить оператор LeftJoin в .NET 10. Тогда запрос выше будет выглядеть так:
На данный момент неясно, будет ли в синтаксисе запроса новое ключевое слово, представляющее оператор LeftJoin. Но вполне вероятно, что оно будет добавлено в синтаксис методов.
2. Неблокирующий старт фоновых сервисов
Небольшое изменение в способе запуска BackgroundService в .NET 10. Вы могли заметить, что запуск фонового сервиса блокирует запуск приложения до тех пор, пока не будет запущен сервис. Это происходит из-за того, что метод StartAsync вызывается синхронно в реализации IHostedService. Вы можете использовать следующий трюк, чтобы обойти это:
Или обернуть всё в Task.Run. Но это не очень хорошо и нелегко обнаружить. В .NET 10 это поведение будет заменено на реально асинхронное, и приложение не будет блокироваться при запуске.
3. Новый компаратор строк
Представьте, что вы хотите отсортировать следующие две строки: Windows 10 и Windows 7. Если рассматривать их исключительно как строки, Windows 10 будет идти перед Windows 7, потому что символ 1 идет перед 7. Но есть контексты, в которых вам нужно рассматривать некоторую часть строки как число и сортировать строки соответствующим образом. Вот тут и пригодится новый StringComparer. Он позволит вам сортировать строки как числа, поэтому Windows 10 будет идти после Windows 7.
Другой пример, упомянутый в предложении, - сортировка IP адресов.
Источники:
- https://steven-giesel.com/blogPost/82ebfd51-23c0-44b7-9602-628d1aba5f3c/linq-might-get-a-left-join-operator-in-net-10
- https://steven-giesel.com/blogPost/3a8c29a3-750a-40f0-aa43-c236b855813e/some-news-about-net-10-backgroundservices-and-new-string-comparer
Заглядываем в .NET 10
9я версия .NET вышла всего месяц назад, а уже появляются предложения того, что может появиться через год в юбилейной 10й версии.
1. «Левое объединение» в LINQ
В LINQ есть оператор Join, который чаще всего в SQL преобразуется во что-то вроде INNER JOIN. В LINQ нет встроенного оператора для LEFT JOIN, но вы можете достичь того же результата, используя комбинацию GroupJoin, SelectMany и DefaultIfEmpty:
var query =
_dbctx.Table1
.GroupJoin(
_dbctx.Table2,
t1 => t1.T2Id,
t2 => t2.Id,
(t1, t2) => new { t1, t2 }
)
.SelectMany(
t => t.t2.DefaultIfEmpty(),
(t, t2) => new { t1 = @t.t1, t2 }
);
Имейте в виду, если вы хотите объединить несколько столбцов, они должны иметь одинаковые имена и типы данных.
Теперь появилось предложение добавить оператор LeftJoin в .NET 10. Тогда запрос выше будет выглядеть так:
var query = _dbctx.Table1
.LeftJoin(
_dbctx.Table2,
t1 => t1.T2Id,
t2 => t2.Id,
(t1, t2) => new { t1, t2 }
);
На данный момент неясно, будет ли в синтаксисе запроса новое ключевое слово, представляющее оператор LeftJoin. Но вполне вероятно, что оно будет добавлено в синтаксис методов.
2. Неблокирующий старт фоновых сервисов
Небольшое изменение в способе запуска BackgroundService в .NET 10. Вы могли заметить, что запуск фонового сервиса блокирует запуск приложения до тех пор, пока не будет запущен сервис. Это происходит из-за того, что метод StartAsync вызывается синхронно в реализации IHostedService. Вы можете использовать следующий трюк, чтобы обойти это:
public class MyService : BackgroundService
{
private IHostApplicationLifetime _lt;
public MyService(IHostApplicationLifetime lt)
{
_lt = lt;
}
protected override async Task
ExecuteAsync(CancellationToken ct)
{
await Task.Yield();
// Вся работа здесь
}
}
Или обернуть всё в Task.Run. Но это не очень хорошо и нелегко обнаружить. В .NET 10 это поведение будет заменено на реально асинхронное, и приложение не будет блокироваться при запуске.
3. Новый компаратор строк
Представьте, что вы хотите отсортировать следующие две строки: Windows 10 и Windows 7. Если рассматривать их исключительно как строки, Windows 10 будет идти перед Windows 7, потому что символ 1 идет перед 7. Но есть контексты, в которых вам нужно рассматривать некоторую часть строки как число и сортировать строки соответствующим образом. Вот тут и пригодится новый StringComparer. Он позволит вам сортировать строки как числа, поэтому Windows 10 будет идти после Windows 7.
var list = new List<string> { "Windows 10", "Windows 7" };
list.Sort(StringComparer.NumericOrdering);
Другой пример, упомянутый в предложении, - сортировка IP адресов.
Источники:
- https://steven-giesel.com/blogPost/82ebfd51-23c0-44b7-9602-628d1aba5f3c/linq-might-get-a-left-join-operator-in-net-10
- https://steven-giesel.com/blogPost/3a8c29a3-750a-40f0-aa43-c236b855813e/some-news-about-net-10-backgroundservices-and-new-string-comparer
👍29
День 2151. #ЗаметкиНаПолях
Публичные API в Модульных Монолитах. Начало
В каждой статье о модульных монолитах говорится, что нужно использовать публичные API между модулями. Но редко говорится, почему эти API существуют или как их правильно проектировать.
Модульный монолит организует приложение в независимые модули с чёткими границами. Границы модулей логичны и группируют связанные бизнес-возможности. Публичные API между ними — это не просто чистый код, это контроль хаоса. Они представляют собой преднамеренные точки связанности. Публичные API не устраняют связанность, они делают её явной и контролируемой.
Когда модулю A что-то нужно от модуля B, у вас есть три варианта:
1) Позволить модулю A читать напрямую из базы данных модуля B,
2) Позволить модулю A получать доступ к внутренним сервисам модуля B,
3) Создать публичный API, который явно определяет, что может делать модуль A.
Первые два варианта приводят к хаосу. Вся система может стать неподдерживаемой, если каждый модуль свободно обращается к данным и сервисам других модулей.
Публичные API служат следующим критически важным целям:
1) Определение контракта: они явно указывают, что могут и не могут делать другие модули,
2) Управление зависимостями: они заставляют вас думать о зависимостях модулей,
3) Управление изменениями: они предоставляют стабильный интерфейс, допуская при этом внутренние изменения.
Вот практический пример. Представьте, что у вас есть модули Orders и Shipping.
Этого мы хотели бы избежать:
А вот, чего бы мы хотели добиться вместо этого:
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/internal-vs-public-apis-in-modular-monoliths
Публичные API в Модульных Монолитах. Начало
В каждой статье о модульных монолитах говорится, что нужно использовать публичные API между модулями. Но редко говорится, почему эти API существуют или как их правильно проектировать.
Модульный монолит организует приложение в независимые модули с чёткими границами. Границы модулей логичны и группируют связанные бизнес-возможности. Публичные API между ними — это не просто чистый код, это контроль хаоса. Они представляют собой преднамеренные точки связанности. Публичные API не устраняют связанность, они делают её явной и контролируемой.
Когда модулю A что-то нужно от модуля B, у вас есть три варианта:
1) Позволить модулю A читать напрямую из базы данных модуля B,
2) Позволить модулю A получать доступ к внутренним сервисам модуля B,
3) Создать публичный API, который явно определяет, что может делать модуль A.
Первые два варианта приводят к хаосу. Вся система может стать неподдерживаемой, если каждый модуль свободно обращается к данным и сервисам других модулей.
Публичные API служат следующим критически важным целям:
1) Определение контракта: они явно указывают, что могут и не могут делать другие модули,
2) Управление зависимостями: они заставляют вас думать о зависимостях модулей,
3) Управление изменениями: они предоставляют стабильный интерфейс, допуская при этом внутренние изменения.
Вот практический пример. Представьте, что у вас есть модули Orders и Shipping.
Этого мы хотели бы избежать:
public class ShippingService
{
// Прямой доступ к БД
private OrdersDbContext _ordersDb;
public async Task ShipOrder(string id)
{
// Напрямую обращаемся к БД другого модуля
var order = await _ordersDb.Orders
.Include(o => o.Lines)
.FirstOrDefaultAsync(o => o.Id == id);
// Что, если модуль Orders изменит схему данных?
}
}
А вот, чего бы мы хотели добиться вместо этого:
public class ShippingService
{
// Доступ к публичному API
private IOrdersModule _orders;
public async Task ShipOrder(string id)
{
// Используем публичный API
var order = await
_orders.GetShippingOrder(id);
// Модуль Orders может изменять внутреннюю
// структуру, сохраняя внешний контракт
}
}
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/internal-vs-public-apis-in-modular-monoliths
👍16👎1
День 2152. #ЗаметкиНаПолях
Внутренние и Публичные API в Модульных Монолитах. Окончание
Начало
Раскрытие информации
Самая сложная часть проектирования публичных API — решить, что раскрывать:
1) Начните с того, что нет ничего публичного,
2) Открывайте только то, что другим модулям действительно нужно,
3) Проектируйте API вокруг вариантов использования, а не данных.
Вот как это выглядит на практике:
Защита данных модуля
Также нужно защитить данные модуля. Вот несколько советов.
1. Отдельные схемы: каждый модуль получает свою схему БД.
Также мы блокируем доступ пользователя к изменению схемы, разрешив только чтение и запись данных.
2. Различные строки подключения: каждый модуль получает своего пользователя БД с соответствующей строкой подключения.
См. также «Использование Нескольких Контекстов EF Core»
3. Модели для чтения: специальная модель только для чтения для использования из других модулей.
Итого
Открытые API в модульных монолитах предназначены не для предотвращения связанности, а для её контроля. Каждый открытый API — это контракт, который гласит: «Да, эти модули связаны, и именно так они зависят друг от друга».
Цель не в том, чтобы устранить зависимости между модулями. Цель в том, чтобы сделать их явными, контролируемыми и поддерживаемыми.
Источник: https://www.milanjovanovic.tech/blog/internal-vs-public-apis-in-modular-monoliths
Внутренние и Публичные API в Модульных Монолитах. Окончание
Начало
Раскрытие информации
Самая сложная часть проектирования публичных API — решить, что раскрывать:
1) Начните с того, что нет ничего публичного,
2) Открывайте только то, что другим модулям действительно нужно,
3) Проектируйте API вокруг вариантов использования, а не данных.
Вот как это выглядит на практике:
public interface IOrdersModule
{
// Не раскрываем CRUD-операции
// Раскрываем варианты использования
Task<ShippingOrder> GetShippingOrder(string id);
Task<PaymentOrder> GetPaymentOrder(string id);
Task<OrderSummary> GetOrderSummary(string id);
}
Защита данных модуля
Также нужно защитить данные модуля. Вот несколько советов.
1. Отдельные схемы: каждый модуль получает свою схему БД.
CREATE SCHEMA Orders;
CREATE SCHEMA Shipping;
-- Каждый модуль имеет доступ только к своей схеме
CREATE USER OrdersUser WITH DEFAULT_SCHEMA = Orders;
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA Orders TO OrdersUser;
-- … Аналогично для схемы Shipping
Также мы блокируем доступ пользователя к изменению схемы, разрешив только чтение и запись данных.
2. Различные строки подключения: каждый модуль получает своего пользователя БД с соответствующей строкой подключения.
builder.Services.AddDbContext<OrdersDbContext>(
opts =>
opts.UseSqlServer(
builder.Configuration
.GetConnectionString("OrdersConnection")));
builder.Services.AddDbContext<ShippingDbContext>(
opts =>
opts.UseSqlServer(
builder.Configuration
.GetConnectionString("ShippingConnection")));
См. также «Использование Нескольких Контекстов EF Core»
3. Модели для чтения: специальная модель только для чтения для использования из других модулей.
internal class Order
{
// Полная внутренняя модель
}
public class ShippingOrder
{
// Публичное DTO для модуля Shipping
public string Id { get; init; }
public Address ShippingAddress { get; init; }
public List<ShippingItem> Items { get; init; }
}
Итого
Открытые API в модульных монолитах предназначены не для предотвращения связанности, а для её контроля. Каждый открытый API — это контракт, который гласит: «Да, эти модули связаны, и именно так они зависят друг от друга».
Цель не в том, чтобы устранить зависимости между модулями. Цель в том, чтобы сделать их явными, контролируемыми и поддерживаемыми.
Источник: https://www.milanjovanovic.tech/blog/internal-vs-public-apis-in-modular-monoliths
👍15
День 2153. #УрокиРазработки
Уроки 50 Лет Разработки ПО
Урок 36. Как бы сильно на вас ни давили, не берите на себя обязательства, которые не сможете выполнить
Люди редко со всей серьёзностью относятся к обязательствам, которые им пришлось взять на себя под принуждением. Они также не берут на себя серьёзных обязательств, которые кто-то другой берет на себя от их имени без консультаций и переговоров. Если сотруднику навязать невыполнимое обязательство, это вызовет у него стресс, а не приведёт к чуду. Более того, люди могут даже снизить свои старания, зная, что всё равно не смогут достичь поставленной цели. Зачем убиваться, если дело и так обречено на провал?
Обязательство — это обещание выполнить некое действие или часть работы на определённом уровне за определённое время. Управление обязательствами — это компонент управления проектами. Идея не брать на себя обязательств, которые невозможно выполнить, — вопрос личной этики. Она также отражает правильное управление проектами и людьми.
Обязательства накапливаются в цепочках зависимостей, как показано на рисунке. Получивший обещание зависит от тех, кто взял на себя обязательства по его выполнению. Если все честно договариваются о достижимых обязательствах, то смогут с уверенностью положиться друг на друга. В противном случае цепочка обязательств рушится как карточный домик. Любые обязательства, невыполненные на нижних уровнях, рушат обязательства на верхних.
Обещайте меньше, а делайте больше. Возможно, из-за этого вы будете выглядеть чрезмерно осторожным, но это же делает вас надёжным. Один из способов не выбиться из графика — заложить в свои обязательства резерв времени на случай непредвиденных обстоятельств, чтобы учесть неопределённость оценок, изменения в требованиях и другие неожиданности. Наличие такого резерва страхует вас, если что-то пойдёт не так, как планировалось. Но перед собой лично ставьте более трудные цели, чем обязательства, которые даёте другим. Прикладывайте все силы, чтобы достичь своей внутренней цели, осознавая, однако, что если не добьётесь её, то всё равно не нарушите данного внешнего обязательства. Чаще всего вы будете достигать цели раньше, чем обязались. Такой результат всем нравится.
В жизни случается всякое
Люди берут на себя обязательства из лучших побуждений. Потом что-то происходит, и всё меняется. Может появиться новое задание или новая возможность, на которые приходится отвлекаться, или объём работы может превышать предполагаемый. Человек может просто потерять интерес к первоначальному обязательству и позволить ему отойти на второй план, надеясь, что никто не заметит. Но это замечают.
Поняв, что по какой-то причине вы не можете выполнить взятое на себя обязательство, как можно скорее сообщите об этом тем, кого это затрагивает, чтобы они могли скорректировать свои планы. Когда кто-то даёт мне обещание, я рассчитываю, что он его выполнит. Если мои первоначальные предположения не оправдались или что-то изменилось, то я предлагаю поговорить. Возможно, мы сможем достичь взаимоприемлемого соглашения. Но я также понимаю, что другой человек может не согласиться по разным причинам.
Если я говорю, что собираюсь что-то сделать, то либо делаю, либо объясняю, почему не могу или не успеваю это сделать, и приношу извинения. Этого же ожидаю от других. Все мы знаем, что ситуации и приоритеты могут меняться. Но, взяв на себя обязательство, человек должен сообщить, если не может выполнить его.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
Уроки 50 Лет Разработки ПО
Урок 36. Как бы сильно на вас ни давили, не берите на себя обязательства, которые не сможете выполнить
Люди редко со всей серьёзностью относятся к обязательствам, которые им пришлось взять на себя под принуждением. Они также не берут на себя серьёзных обязательств, которые кто-то другой берет на себя от их имени без консультаций и переговоров. Если сотруднику навязать невыполнимое обязательство, это вызовет у него стресс, а не приведёт к чуду. Более того, люди могут даже снизить свои старания, зная, что всё равно не смогут достичь поставленной цели. Зачем убиваться, если дело и так обречено на провал?
Обязательство — это обещание выполнить некое действие или часть работы на определённом уровне за определённое время. Управление обязательствами — это компонент управления проектами. Идея не брать на себя обязательств, которые невозможно выполнить, — вопрос личной этики. Она также отражает правильное управление проектами и людьми.
Обязательства накапливаются в цепочках зависимостей, как показано на рисунке. Получивший обещание зависит от тех, кто взял на себя обязательства по его выполнению. Если все честно договариваются о достижимых обязательствах, то смогут с уверенностью положиться друг на друга. В противном случае цепочка обязательств рушится как карточный домик. Любые обязательства, невыполненные на нижних уровнях, рушат обязательства на верхних.
Обещайте меньше, а делайте больше. Возможно, из-за этого вы будете выглядеть чрезмерно осторожным, но это же делает вас надёжным. Один из способов не выбиться из графика — заложить в свои обязательства резерв времени на случай непредвиденных обстоятельств, чтобы учесть неопределённость оценок, изменения в требованиях и другие неожиданности. Наличие такого резерва страхует вас, если что-то пойдёт не так, как планировалось. Но перед собой лично ставьте более трудные цели, чем обязательства, которые даёте другим. Прикладывайте все силы, чтобы достичь своей внутренней цели, осознавая, однако, что если не добьётесь её, то всё равно не нарушите данного внешнего обязательства. Чаще всего вы будете достигать цели раньше, чем обязались. Такой результат всем нравится.
В жизни случается всякое
Люди берут на себя обязательства из лучших побуждений. Потом что-то происходит, и всё меняется. Может появиться новое задание или новая возможность, на которые приходится отвлекаться, или объём работы может превышать предполагаемый. Человек может просто потерять интерес к первоначальному обязательству и позволить ему отойти на второй план, надеясь, что никто не заметит. Но это замечают.
Поняв, что по какой-то причине вы не можете выполнить взятое на себя обязательство, как можно скорее сообщите об этом тем, кого это затрагивает, чтобы они могли скорректировать свои планы. Когда кто-то даёт мне обещание, я рассчитываю, что он его выполнит. Если мои первоначальные предположения не оправдались или что-то изменилось, то я предлагаю поговорить. Возможно, мы сможем достичь взаимоприемлемого соглашения. Но я также понимаю, что другой человек может не согласиться по разным причинам.
Если я говорю, что собираюсь что-то сделать, то либо делаю, либо объясняю, почему не могу или не успеваю это сделать, и приношу извинения. Этого же ожидаю от других. Все мы знаем, что ситуации и приоритеты могут меняться. Но, взяв на себя обязательство, человек должен сообщить, если не может выполнить его.
Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 5.
👍12
День 2154. #ЧтоНовенького
Бесплатный GitHub Copilot в Visual Studio
Если вы ещё не слышали, GitHub анонсировал бесплатный план Copilot! И вы уже можете начать использовать Copilot прямо сейчас в Visual Studio и VS Code.
Copilot предлагает инструменты на базе ИИ, такие как умная отладка, сообщения о коммитах, сгенерированные ИИ, размещение точек останова с помощью ИИ, ИИ-завершения кода, чат и многое другое. Разработчики увидели увеличение продуктивности до 25% при использовании Copilot.
Чтобы попробовать, войдите в свой аккаунт на GitHub, и перейдите в настройки Copilot.
Бесплатная версия включает:
- 2000 интеллектуальных автодополнений кода в месяц: контекстно-зависимые предложения кода, которые черпают контекст из ваших проектов GitHub и рабочего пространства.
- 50 сообщений в чате Copilot в месяц: попросите Copilot помочь вам понять код, выполнить рефакторинг, написать тесты для класса или отладить проблему.
- Выбор модели ИИ Claude 3.5 Sonnet или OpenAI GPT-4o.
- Внесение изменений в несколько файлов с помощью Copilot Edits.
- Поддержка экосистемы Copilot Extensions: доступ к сторонним агентам, разработанным для таких задач, как запросы к Stack Overflow или поиск с помощью Perplexity.
На данный момент вы не получите уведомления, когда достигнете лимитов использования в месяц. Но это обещают исправить в новых версиях Visual Studio в январе, поэтому следите за обновлениями.
Источник: https://devblogs.microsoft.com/visualstudio/github-copilot-free-is-here-in-visual-studio/
Бесплатный GitHub Copilot в Visual Studio
Если вы ещё не слышали, GitHub анонсировал бесплатный план Copilot! И вы уже можете начать использовать Copilot прямо сейчас в Visual Studio и VS Code.
Copilot предлагает инструменты на базе ИИ, такие как умная отладка, сообщения о коммитах, сгенерированные ИИ, размещение точек останова с помощью ИИ, ИИ-завершения кода, чат и многое другое. Разработчики увидели увеличение продуктивности до 25% при использовании Copilot.
Чтобы попробовать, войдите в свой аккаунт на GitHub, и перейдите в настройки Copilot.
Бесплатная версия включает:
- 2000 интеллектуальных автодополнений кода в месяц: контекстно-зависимые предложения кода, которые черпают контекст из ваших проектов GitHub и рабочего пространства.
- 50 сообщений в чате Copilot в месяц: попросите Copilot помочь вам понять код, выполнить рефакторинг, написать тесты для класса или отладить проблему.
- Выбор модели ИИ Claude 3.5 Sonnet или OpenAI GPT-4o.
- Внесение изменений в несколько файлов с помощью Copilot Edits.
- Поддержка экосистемы Copilot Extensions: доступ к сторонним агентам, разработанным для таких задач, как запросы к Stack Overflow или поиск с помощью Perplexity.
На данный момент вы не получите уведомления, когда достигнете лимитов использования в месяц. Но это обещают исправить в новых версиях Visual Studio в январе, поэтому следите за обновлениями.
Источник: https://devblogs.microsoft.com/visualstudio/github-copilot-free-is-here-in-visual-studio/
👍9
День 2155. #ЗаметкиНаПолях
3 Основных Способа Управления Транзакциями в EF Core. Начало
Транзакции помогают безопасно обновлять связанные данные, не оставляя состояние БД несогласованным. Рассмотрим, как EF Core предоставляет механизм упаковки операций с БД в транзакции.
Транзакция — это набор операций с БД, рассматриваемых как единица работы. Если одна из операций завершается неудачей, вся транзакция завершается неудачей, и все предыдущие успешные операции откатываются, чтобы сохранить согласованность базы.
Вот основные способы работы с транзакциями в EF Core:
1. Автоматически. Метод SaveChangesAsync() класса DbContext фиксирует все изменения в транзакции.
2. Вручную. Использование команд begin, commit и rollback для транзакций.
3. Стратегия выполнения транзакций. Может иметь несколько вызовов SaveChangesAsync, но они не фиксируются, пока транзакция не фиксирует их с помощью метода transaction.CommitAsync().
1. Автоматические транзакции
Предположим, что нам нужно добавить несколько зданий.
Каждый вызов SaveChangesAsync автоматически запускает новую транзакцию, если она ещё не запущена. Т.е. все изменения, внесённые в контекст до этого момента, сохраняются в БД как единое целое, что обеспечивает согласованность данных.
Плюсы
- Самый простой способ, не требуется никаких дополнительных методов.
- Выполняет транзакции асинхронно, улучшая отзывчивость приложения.
Минусы
- Имеет ограниченную область действия транзакции, поскольку обрабатывает каждую операцию как транзакцию.
- Нет контроля над транзакциями.
- Не может применяться для взаимозависимых операций.
2. Ручные транзакции
Здесь каждый вызов SaveChangesAsync рассматривается как завершение одной операции. Несколько вызовов заключены в транзакцию, которая начинается с Database.BeginTransaction. После успешного выполнения всех операций метод transaction.Commit() фиксирует все изменения как одну транзакцию.
Плюсы
- Полный контроль над транзакцией. Можно вручную фиксировать и откатывать транзакцию.
- Лучше обработка ошибок с перехватом исключений и свободой обрабатывать различные ошибки по-разному.
- Подходит для сложных сценариев, где необходимо выполнять разные операции с БД.
Минусы
- Усложняет код из-за дополнительного кода обработки транзакций.
Окончание следует…
Источник: https://blog.elmah.io/3-essential-techniques-for-managing-transactions-in-ef-core/
3 Основных Способа Управления Транзакциями в EF Core. Начало
Транзакции помогают безопасно обновлять связанные данные, не оставляя состояние БД несогласованным. Рассмотрим, как EF Core предоставляет механизм упаковки операций с БД в транзакции.
Транзакция — это набор операций с БД, рассматриваемых как единица работы. Если одна из операций завершается неудачей, вся транзакция завершается неудачей, и все предыдущие успешные операции откатываются, чтобы сохранить согласованность базы.
Вот основные способы работы с транзакциями в EF Core:
1. Автоматически. Метод SaveChangesAsync() класса DbContext фиксирует все изменения в транзакции.
2. Вручную. Использование команд begin, commit и rollback для транзакций.
3. Стратегия выполнения транзакций. Может иметь несколько вызовов SaveChangesAsync, но они не фиксируются, пока транзакция не фиксирует их с помощью метода transaction.CommitAsync().
1. Автоматические транзакции
Предположим, что нам нужно добавить несколько зданий.
csharp
public record Building(int Id, string Name, string Address);
using var ctx = new ApplicationDbContext();
var bld1 = new
Building(1, "First", "1st Street, 42");
ctx.Buildings.Add(bld1);
// Транзакция используется автоматически
ctx.SaveChangesAsync();
var bld2 = new
Building(2, "Second", "2nd Street, 69");
ctx.Buildings.Add(bld2);
// Транзакция используется автоматически
ctx.SaveChangesAsync();
Каждый вызов SaveChangesAsync автоматически запускает новую транзакцию, если она ещё не запущена. Т.е. все изменения, внесённые в контекст до этого момента, сохраняются в БД как единое целое, что обеспечивает согласованность данных.
Плюсы
- Самый простой способ, не требуется никаких дополнительных методов.
- Выполняет транзакции асинхронно, улучшая отзывчивость приложения.
Минусы
- Имеет ограниченную область действия транзакции, поскольку обрабатывает каждую операцию как транзакцию.
- Нет контроля над транзакциями.
- Не может применяться для взаимозависимых операций.
2. Ручные транзакции
Здесь каждый вызов SaveChangesAsync рассматривается как завершение одной операции. Несколько вызовов заключены в транзакцию, которая начинается с Database.BeginTransaction. После успешного выполнения всех операций метод transaction.Commit() фиксирует все изменения как одну транзакцию.
public class BuildingRepo: IBuildingRepo
{
private AppDbContext _context;
public BuildingRepo(AppDbContext ctx)
{
_ctx = ctx;
}
public async Task<bool> CreateAsync(
List<Building> buildings)
{
using (var trans = ctx.Database.BeginTransaction())
{
try
{
foreach (var bld in buildings)
{
_ctx.Buildings.Add(bld);
_ctx.SaveChangesAsync();
}
// Если всё ОК, фиксируем транзакцию
trans.Commit();
return true;
}
catch (Exception ex)
{
// В случае ошибки, откатываем
trans.Rollback();
// Обработка исключения…
return false;
}
}
}
}
Плюсы
- Полный контроль над транзакцией. Можно вручную фиксировать и откатывать транзакцию.
- Лучше обработка ошибок с перехватом исключений и свободой обрабатывать различные ошибки по-разному.
- Подходит для сложных сценариев, где необходимо выполнять разные операции с БД.
Минусы
- Усложняет код из-за дополнительного кода обработки транзакций.
Окончание следует…
Источник: https://blog.elmah.io/3-essential-techniques-for-managing-transactions-in-ef-core/
👍16
День 2156. #ЗаметкиНаПолях
3 Основных Способа Управления Транзакциями в EF Core. Окончание
Начало
3. Стратегия выполнения транзакций
В этом способе создаётся стратегия выполнения, в которой управляются транзакции. Она продолжает пытаться выполнить операции с БД указанное количество раз, если транзакция не удаётся из-за временной ошибки. Это итеративное поведение гарантирует, что незначительные проблемы не повлияют на фактические операции.
Добавим к зданиям различные помещения в зданиях:
Создадим DTO:
И, наконец, сценарий обработки:
Весь блок работает как транзакция. При временном сбое стратегия выполнения повторяет всю операцию в ExecuteAsync.
Плюсы
- Стратегия может обрабатывать временные сбои, что повышает отзывчивость и надёжность приложения.
- Идеально подходит для сложных сценариев и взаимозависимых операций.
- Предлагает настройку транзакции вместе с устойчивостью к сбоям сети.
Минусы
- Ещё больше усложняет код. Множество блоков и областей влияют на читаемость кода.
- Транзакция на основе стратегии может снизить производительность приложения, если она неправильно настроена.
Источник: https://blog.elmah.io/3-essential-techniques-for-managing-transactions-in-ef-core/
3 Основных Способа Управления Транзакциями в EF Core. Окончание
Начало
3. Стратегия выполнения транзакций
В этом способе создаётся стратегия выполнения, в которой управляются транзакции. Она продолжает пытаться выполнить операции с БД указанное количество раз, если транзакция не удаётся из-за временной ошибки. Это итеративное поведение гарантирует, что незначительные проблемы не повлияют на фактические операции.
Добавим к зданиям различные помещения в зданиях:
public class Unit
{
public int Id { get; set; }
public string Number { get; set; }
// Office, Apartment, Storage, и т.п.
public UnitType Type { get; set; }
public int Floor { get; set; }
public int BuildingId { get; set; }
public Building Building { get; set; }
}
Создадим DTO:
public record UnitDto(
string Number, UnitType Type, int Floor);
public class BuildingDto
{
public string Name { get; set; }
public string Address { get; set; }
public List<UnitDto> Units { get; set; }
= new List<UnitDto>();
}
И, наконец, сценарий обработки:
public class BuildingRepo: IBuildingRepo
{
private AppDbContext _ctx;
public BuildingRepo(AppDbContext ctx)
{
_ctx = ctx;
}
public async Task<bool> CreateAsync(BuildingDto input)
{
// Создаём стратегию
var strategy = _ctx.Database
.CreateExecutionStrategy();
return await strategy.ExecuteAsync(async () =>
{
// Запускаем транзакцию
using (var trans =
await _ctx.Database.BeginTransactionAsync())
{
try
{
var bld = new Building()
{
Name = input.Name,
Address = input.Address
};
// Сохраняем Building
_ctx.Buildings.Add(bld);
await _ctx.SaveChangesAsync();
foreach (var unit in input.Units)
{
_ctx.Add(new Unit()
{
// Добавляем внешний ключ здания
BuildingId = bld.Id,
Number = unit.Number,
Type = unit.Type,
Floor = unit.Floor
});
}
await _ctx.SaveChangesAsync();
await trans.CommitAsync();
return true;
}
catch (Exception ex)
{
// Откатываем, транзакцию при ошибке
await trans.RollbackAsync();
// Выбрасываем исключение,
// чтобы стратегия его обработала
throw;
}
}
}
});
}
Весь блок работает как транзакция. При временном сбое стратегия выполнения повторяет всю операцию в ExecuteAsync.
Плюсы
- Стратегия может обрабатывать временные сбои, что повышает отзывчивость и надёжность приложения.
- Идеально подходит для сложных сценариев и взаимозависимых операций.
- Предлагает настройку транзакции вместе с устойчивостью к сбоям сети.
Минусы
- Ещё больше усложняет код. Множество блоков и областей влияют на читаемость кода.
- Транзакция на основе стратегии может снизить производительность приложения, если она неправильно настроена.
Источник: https://blog.elmah.io/3-essential-techniques-for-managing-transactions-in-ef-core/
👍13