День 1568. #Книги
Сегодня мне пришла книга, над переводом которой я работал совместно с сообществом DotNetRu. Кристиан Венц «Безопасность ASP.NET Core» — М.: ДМК Пресс, 2023.
Я уже участвовал в переводе нескольких книг, эта стала третьей. В этот раз, к сожалению, не получилось вычитать всё, как в случае с книгой "Entity Framework Core в действии", поэтому отложил её в очередь для чтения.
Сегодня мне пришла книга, над переводом которой я работал совместно с сообществом DotNetRu. Кристиан Венц «Безопасность ASP.NET Core» — М.: ДМК Пресс, 2023.
Я уже участвовал в переводе нескольких книг, эта стала третьей. В этот раз, к сожалению, не получилось вычитать всё, как в случае с книгой "Entity Framework Core в действии", поэтому отложил её в очередь для чтения.
👍41
День 1569. #ЗаметкиНаПолях
Избегайте Распространения DbContext или IQueryable в Приложениях. Начало
Большинство приложений .NET используют EF Core и DbContext для доступа к данным, но удобство сопровождения может пострадать, если использование DbContext или производного от него IQueryable распространяется по всему приложению.
Интерфейсы IQueryable и IQueryable<T> в .NET позволяют описывать запросы в виде деревьев выражений, которые при выполнении преобразуются провайдером в запросы к БД. В EF IQueryable используется, чтобы создавать динамические SQL-запросы, что позволяет выполнять детальные и эффективные запросы к базе данных, а не извлекать больше данных, чем необходимо, в память приложения, а затем фильтровать результат в памяти.
Ниже создаётся набор заказов, отфильтрованных по дате. В первом примере все заказы из БД передаются в приложение, а затем фильтруются. Во втором используется динамический SQL-запрос, позволяющий БД возвращать только совпадающие записи:
Можно создать выражение IQueryable с помощью серии операторов, даже в разных функциях, классах или проектах. Когда об этом было впервые объявлено, в Microsoft высоко оценили эту возможность, т.к. разработчики могли создавать нужный запрос «по требованию», где бы им это ни требовалось, гарантируя, что при окончательном выполнении запроса будут возвращены только необходимые данные. У вас может быть сервис, возвращающий «чистые» данные:
Окончание следует…
Источник: https://ardalis.com/avoid-dbcontext-iqueryable-proliferation/
Избегайте Распространения DbContext или IQueryable в Приложениях. Начало
Большинство приложений .NET используют EF Core и DbContext для доступа к данным, но удобство сопровождения может пострадать, если использование DbContext или производного от него IQueryable распространяется по всему приложению.
Интерфейсы IQueryable и IQueryable<T> в .NET позволяют описывать запросы в виде деревьев выражений, которые при выполнении преобразуются провайдером в запросы к БД. В EF IQueryable используется, чтобы создавать динамические SQL-запросы, что позволяет выполнять детальные и эффективные запросы к базе данных, а не извлекать больше данных, чем необходимо, в память приложения, а затем фильтровать результат в памяти.
Ниже создаётся набор заказов, отфильтрованных по дате. В первом примере все заказы из БД передаются в приложение, а затем фильтруются. Во втором используется динамический SQL-запрос, позволяющий БД возвращать только совпадающие записи:
var since = new DateTime(2023,1,1);Очевидно, что скорость и эффективность второго подхода почти всегда делают его предпочтительным методом.
// фильтрация в памяти
var all = dbContext.Orders.ToList();
var recent1 = all
.Where(o.Date > since)
.ToList();
// фильтрация в БД
var recent2 = dbContext.Orders
.Where(o.Date > since)
.ToList();
Можно создать выражение IQueryable с помощью серии операторов, даже в разных функциях, классах или проектах. Когда об этом было впервые объявлено, в Microsoft высоко оценили эту возможность, т.к. разработчики могли создавать нужный запрос «по требованию», где бы им это ни требовалось, гарантируя, что при окончательном выполнении запроса будут возвращены только необходимые данные. У вас может быть сервис, возвращающий «чистые» данные:
public class DataServiceСервис бизнес-логики, который накладывает некоторые ограничения на выборку:
{
public async
Task<IQueryable<Order>> List()
{
return await
_dbContext.Orders.AsQueryable();
}
}
public class OrderServiceЗатем в контроллере добавляется фильтр текущего пользователя:
{
// сервис данных внедряется в _dataService
public async
Task<IQueryable<Order>> ActiveOrders()
{
var all = await _dataService.List();
return await all
.Where(o => !o.Canceled)
.AsQueryable();
}
}
var viewModel =Наконец, на странице в коде Razor мы генерируем окончательный список:
await _orderSvc.ActiveOrders()
.Where(o => o.CreatedBy = username)
.AsQueryable();
foreach(var ord inВ итоге у нас получается следующий запрос, который будет выполнен:
model.Orders.Where(o => o.Shipped()))
{
// список в HTML
}
_dbContext.OrdersЭто здорово, если сравнивать с наивной реализацией, в которой сервис данных просто возвращал бы все заказы, а последующие правила фильтровали данные в памяти. Но это странное решение, есть лучшие способы организовать этот код, сохраняя при этом эффективность запросов.
.Where(o => !o.Canceled &&
o.CreatedBy == username &&
o.Shipped);
Окончание следует…
Источник: https://ardalis.com/avoid-dbcontext-iqueryable-proliferation/
👍15
День 1570. #ЗаметкиНаПолях
Избегайте Распространения DbContext или IQueryable в Приложениях. Окончание
Начало
Когда вы везде передаёте IQueryable, вы позволяете логике доступа к данным распространяться по всей кодовой базе. Нет никакой инкапсуляции логики и правил доступа к данным. Приложение не следует принципу разделения ответственности, поскольку позволяет логике данных «протекать» в каждую часть системы.
Более того, код за пределами уровня данных может даже не знать, что он имеет дело с IQueryable, потому что IQueryable наследует IEnumerable. Методы могут работать с IEnumerable, ожидая поведения только в памяти, но на самом деле манипулируя деревом выражений IQueryable. Это может привести к неожиданным исключениям во время выполнения, особенно если результаты фильтруются с использованием кода, который EF не может преобразовать в SQL (например, пользовательской функции). Страдает понимание кода, а также отладка, устранение неполадок и тестирование. Место IQueryable - на уровне данных. В репозитории допустимо использование IQueryable, при условии, что он не является частью абстракции или публичного интерфейса типа.
Поскольку DbContext или DbSet<T> можно использовать для получения IQueryable в любое время, передача их за пределы уровня данных имеет такое же (негативное) влияние на разделение ответственности и инкапсуляцию, что и передача IQueryable<T>.
Какая есть альтернатива?
Во-первых, вы можно передавать дерево выражений в сервис данных и использовать его:
Ещё лучше использовать паттерн Спецификация. В этом случае вместо передачи LINQ-выражения вы передаёте экземпляр спецификации, а выражение строится в ней:
Итого
Распространение IQueryable по всему приложению позволяет расширять запросы к БД из любого места. Это и хорошо, и плохо, и соответствует определению антипаттерна, поскольку сначала кажется чем-то стоящим, но на практике приводит к проблемам. Решение состоит не в том, чтобы получать нефильтрованные данные и затем фильтровать их на сервере приложений, а в том, чтобы идентифицировать конкретные запросы, которые потребуются отдельным страницам или конечным точкам, и определять их как первоклассные абстракции в модели предметной области приложения. Паттерны Спецификация и Репозиторий прекрасно подходят для достижения такого дизайна и обеспечивают гораздо более удобный и тестируемый результат.
Источник: https://ardalis.com/avoid-dbcontext-iqueryable-proliferation/
Избегайте Распространения DbContext или IQueryable в Приложениях. Окончание
Начало
Когда вы везде передаёте IQueryable, вы позволяете логике доступа к данным распространяться по всей кодовой базе. Нет никакой инкапсуляции логики и правил доступа к данным. Приложение не следует принципу разделения ответственности, поскольку позволяет логике данных «протекать» в каждую часть системы.
Более того, код за пределами уровня данных может даже не знать, что он имеет дело с IQueryable, потому что IQueryable наследует IEnumerable. Методы могут работать с IEnumerable, ожидая поведения только в памяти, но на самом деле манипулируя деревом выражений IQueryable. Это может привести к неожиданным исключениям во время выполнения, особенно если результаты фильтруются с использованием кода, который EF не может преобразовать в SQL (например, пользовательской функции). Страдает понимание кода, а также отладка, устранение неполадок и тестирование. Место IQueryable - на уровне данных. В репозитории допустимо использование IQueryable, при условии, что он не является частью абстракции или публичного интерфейса типа.
Поскольку DbContext или DbSet<T> можно использовать для получения IQueryable в любое время, передача их за пределы уровня данных имеет такое же (негативное) влияние на разделение ответственности и инкапсуляцию, что и передача IQueryable<T>.
Какая есть альтернатива?
Во-первых, вы можно передавать дерево выражений в сервис данных и использовать его:
public IOrderRepositoryВы создаёте фильтр заранее, он исполняется в сервисе данных, а возвращаемый результат – данные в памяти.
{
List<Order> List(
Expression<Func<Order,bool>> filter);
}
Ещё лучше использовать паттерн Спецификация. В этом случае вместо передачи LINQ-выражения вы передаёте экземпляр спецификации, а выражение строится в ней:
public IOrderRepositoryВ вызывающем коде вы определяете необходимую спецификацию как часть модели предметной области, а затем используете её в том месте, где вам нужны данные:
{
List<Order> List(
Specification<Order> spec);
}
public class ShippedOrdersForUserSpec :Таким образом запрос по-прежнему выполняется в базе данных, но IQueryable больше не используется нигде за пределами реализации репозитория. Вы можете посмотреть на использование этого паттерна в примере eShopOnWeb (см. папку /src/ApplicationCore/Specifications/).
Specification<Order>
{
public ShippedOrdersForUserSpec(
string username)
{
Query.Where(o => !o.Canceled &&
o.CreatedBy == username &&
o.Shipped);
}
}
// в контроллере/на странице
var spec = new ShippedOrdersForUserSpec(username);
var viewModel = await _repo.ListAsync(spec);
Итого
Распространение IQueryable по всему приложению позволяет расширять запросы к БД из любого места. Это и хорошо, и плохо, и соответствует определению антипаттерна, поскольку сначала кажется чем-то стоящим, но на практике приводит к проблемам. Решение состоит не в том, чтобы получать нефильтрованные данные и затем фильтровать их на сервере приложений, а в том, чтобы идентифицировать конкретные запросы, которые потребуются отдельным страницам или конечным точкам, и определять их как первоклассные абстракции в модели предметной области приложения. Паттерны Спецификация и Репозиторий прекрасно подходят для достижения такого дизайна и обеспечивают гораздо более удобный и тестируемый результат.
Источник: https://ardalis.com/avoid-dbcontext-iqueryable-proliferation/
👍13
День 1571. #ЧтоНовенького
Новинки для Разработки API в .NET 8
В .NET 8 превью 4 представлены несколько новинок, которые могут упростить жизнь при разработке API.
1. Расширена поддержка привязки форм в минимальных API
Параметры отправленной формы выводятся без необходимости использования атрибута FromForm. Поддержка включает: IFormCollection, IFormFile и IFormFileCollection. Метаданные OpenAPI для параметров формы также выводятся автоматически для поддержки интеграции со Swagger UI.
В приведённом ниже примере кода демонстрируется реализация минимального API, который обрабатывает загрузку файлов, используя выведение параметра типа IFormFile:
Примечание: При реализации форм в приложении важно защищаться от XSRF-атак. В этом расширенном примере показано, как использовать сервисы ASP.NET для создания и проверки маркеров защиты от подделки межсайтовых запросов в минимальных API.
2. Шаблон проекта API включает файл .http
Шаблон проекта API (созданный с помощью
Источник: https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-4/#api-authoring
Новинки для Разработки API в .NET 8
В .NET 8 превью 4 представлены несколько новинок, которые могут упростить жизнь при разработке API.
1. Расширена поддержка привязки форм в минимальных API
Параметры отправленной формы выводятся без необходимости использования атрибута FromForm. Поддержка включает: IFormCollection, IFormFile и IFormFileCollection. Метаданные OpenAPI для параметров формы также выводятся автоматически для поддержки интеграции со Swagger UI.
В приведённом ниже примере кода демонстрируется реализация минимального API, который обрабатывает загрузку файлов, используя выведение параметра типа IFormFile:
var app = WebApplication.Create();Эта функция поддерживается как в минимальных API, использующих генерацию кода во время выполнения, так и в минимальных API, использующих новую генерацию кода во время компиляции для сценариев Native AOT.
string GetPath(
string fileName,
string dir = "uploads")
{
var dirPath = Path.Combine(
app.Environment.ContentRootPath,
dir);
Directory.CreateDirectory(dirPath);
return Path.Combine(dirPath, fileName);
}
async Task Upload(
IFormFile file,
string fileName)
{
var filePath = GetPath(fileName);
await using var stream =
new FileStream(filePath, FileMode.Create);
await file.CopyToAsync(stream);
}
app.MapPost("/upload", async (IFormFile file) =>
{
var fileName = Guid.NewGuid().ToString("N")
+ Path.GetExtension(file.FileName);
await Upload(file, fileName);
return TypedResults.Ok("Uploaded successfully!");
});
app.Run();
Примечание: При реализации форм в приложении важно защищаться от XSRF-атак. В этом расширенном примере показано, как использовать сервисы ASP.NET для создания и проверки маркеров защиты от подделки межсайтовых запросов в минимальных API.
2. Шаблон проекта API включает файл .http
Шаблон проекта API (созданный с помощью
dotnet new api
) теперь включает файл .http, который можно использовать для отправки запросов на конечные точки, определённые в приложении, из нового редактора HTTP в Visual Studio.@MyApi_HostAddress = https://localhost:5233Коротко про редактор HTTP в Visual Studio рассказывается в этом видео.
GET {{MyApi_HostAddress}}/todos/
Accept: application/json
###
GET {{MyApi_HostAddress}}/todos/1
Accept: application/json
###
Источник: https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-4/#api-authoring
👍11
День 1572. #Карьера
3 Фразы, Которые Помогут Справиться с Эмоциями и Улучшить Отношения
Эмоциональные моменты могут заставить вас сказать или сделать то, о чём вы потом пожалеете. Сегодня рассмотрим три фразы, которые могут помочь.
Вы замечали за собой, что вы не всегда можете быть приятным собеседником? Были пассивно-агрессивны, позволяли негативному мышлению взять верх и говорили или делали то, о чём потом сожалели? Такие ошибки могут стоить очень дорого даже в финансовом плане, не говоря уже о влиянии на личную жизнь. Чаще всего они возникают из-за неспособности справиться с собственными эмоциями.
Важно работать над формированием эмоционального интеллекта, способности понимать эмоции и управлять. Вот несколько фраз, которые помогут вернуться в нужное русло в эмоциональные моменты.
1. Как противостоять пассивно-агрессивному поведению
Пассивная агрессия — это проявление негативных чувств, обиды и агрессии в неуверенной или «пассивной» манере. Это может проявляться в том, что человек заявляет, что с ним всё в порядке (когда очевидно, что это не так), начинает «играть в молчанку» или избегает конфронтации только для того, чтобы позже втихую саботировать планы. Необходимо противостоять пассивно-агрессивному поведению. С этим поможет фраза «Атакуйте проблему, а не человека.»
Ваше пассивно-агрессивное поведение вредно для другого человека, и вам нужно сосредоточиться на решении проблемы. Если же вы имеете дело с кем-то, кто ведёт себя пассивно-агрессивно, это должно говорить вам, что человек использует его как механизм выживания. Если вы сосредоточитесь на имеющейся проблеме, а не на плохом общении вашего партнера, человек оценит ваши попытки двигаться вперёд.
2. Как относиться к критике
Если вы всегда воспринимаете критику «в штыки», обычно вы испытываете одно из двух чувств: либо желание защитить себя, либо подавленность. Ни одно из них не является продуктивным, т.к. они мешают извлечь пользу из критики. Иногда критика оправдана, иногда нет, но критика ценна, потому что даёт вам представление о том, как вас воспринимают другие.
Здесь поможет вторая фраза: «Не чувствуйте себя атакованным.»
Эта фраза заставляет вас сделать паузу, чтобы справиться с первоначальными эмоциями и сосредоточиться на анализе и решении проблемы, а также даст возможность извлечь выгоду из критики.
3. Как перестать думать и начать двигаться вперед
Если вы слишком много думаете, легко впасть в аналитический паралич. Вы можете потратить кучу времени, беспокоясь о вещах, которые никогда не произойдут, что мешает вам двигаться вперед. Это не только ограничивает вас, но и вредит отношениям, потому что люди видят в вас человека, который боится принимать решения.
Чтобы справиться с этой проблемой, вы должны напомнить себе: «Проведите эксперимент.»
Это включает следующие шаги:
1. Исследуйте тему. Найдите разумное время, чтобы изучить ситуацию. Стремитесь рассмотреть вещи с разных сторон и познакомиться с разными точками зрения.
2. Определите основную проблему. Это то, что вы контролируете? Если нет, идите дальше. Если да, составьте список вариантов решения.
3. Сузьте список. Три варианта — хорошо, два - лучше.
4. Взвесьте все за и против. Составьте список положительных и отрицательных сторон, если это поможет увидеть вещи более ясно.
5. Установите дедлайн.
6. Выберите вариант и запустите эксперимент. Рассматривая это как эксперимент, вы напоминаете себе, что это не окончательное решение. Это выбор двигаться вперёд, а не стоять на месте.
Помните, что, если эксперимент пойдет не так, вы (почти) всегда можете передумать. Ведь время – деньги. Во многих случаях отказ двигаться вперёд может оказаться даже более дорогостоящим, чем необходимость сменить курс.
Эмоции – это то, делает нас людьми. Ключ к эмоциональному интеллекту — заставить эмоции работать на вас, а не против вас.
Источник: https://www.inc.com/justin-bariso/emotional-intelligence-how-to-cope-communicate-improve-relationships.html
3 Фразы, Которые Помогут Справиться с Эмоциями и Улучшить Отношения
Эмоциональные моменты могут заставить вас сказать или сделать то, о чём вы потом пожалеете. Сегодня рассмотрим три фразы, которые могут помочь.
Вы замечали за собой, что вы не всегда можете быть приятным собеседником? Были пассивно-агрессивны, позволяли негативному мышлению взять верх и говорили или делали то, о чём потом сожалели? Такие ошибки могут стоить очень дорого даже в финансовом плане, не говоря уже о влиянии на личную жизнь. Чаще всего они возникают из-за неспособности справиться с собственными эмоциями.
Важно работать над формированием эмоционального интеллекта, способности понимать эмоции и управлять. Вот несколько фраз, которые помогут вернуться в нужное русло в эмоциональные моменты.
1. Как противостоять пассивно-агрессивному поведению
Пассивная агрессия — это проявление негативных чувств, обиды и агрессии в неуверенной или «пассивной» манере. Это может проявляться в том, что человек заявляет, что с ним всё в порядке (когда очевидно, что это не так), начинает «играть в молчанку» или избегает конфронтации только для того, чтобы позже втихую саботировать планы. Необходимо противостоять пассивно-агрессивному поведению. С этим поможет фраза «Атакуйте проблему, а не человека.»
Ваше пассивно-агрессивное поведение вредно для другого человека, и вам нужно сосредоточиться на решении проблемы. Если же вы имеете дело с кем-то, кто ведёт себя пассивно-агрессивно, это должно говорить вам, что человек использует его как механизм выживания. Если вы сосредоточитесь на имеющейся проблеме, а не на плохом общении вашего партнера, человек оценит ваши попытки двигаться вперёд.
2. Как относиться к критике
Если вы всегда воспринимаете критику «в штыки», обычно вы испытываете одно из двух чувств: либо желание защитить себя, либо подавленность. Ни одно из них не является продуктивным, т.к. они мешают извлечь пользу из критики. Иногда критика оправдана, иногда нет, но критика ценна, потому что даёт вам представление о том, как вас воспринимают другие.
Здесь поможет вторая фраза: «Не чувствуйте себя атакованным.»
Эта фраза заставляет вас сделать паузу, чтобы справиться с первоначальными эмоциями и сосредоточиться на анализе и решении проблемы, а также даст возможность извлечь выгоду из критики.
3. Как перестать думать и начать двигаться вперед
Если вы слишком много думаете, легко впасть в аналитический паралич. Вы можете потратить кучу времени, беспокоясь о вещах, которые никогда не произойдут, что мешает вам двигаться вперед. Это не только ограничивает вас, но и вредит отношениям, потому что люди видят в вас человека, который боится принимать решения.
Чтобы справиться с этой проблемой, вы должны напомнить себе: «Проведите эксперимент.»
Это включает следующие шаги:
1. Исследуйте тему. Найдите разумное время, чтобы изучить ситуацию. Стремитесь рассмотреть вещи с разных сторон и познакомиться с разными точками зрения.
2. Определите основную проблему. Это то, что вы контролируете? Если нет, идите дальше. Если да, составьте список вариантов решения.
3. Сузьте список. Три варианта — хорошо, два - лучше.
4. Взвесьте все за и против. Составьте список положительных и отрицательных сторон, если это поможет увидеть вещи более ясно.
5. Установите дедлайн.
6. Выберите вариант и запустите эксперимент. Рассматривая это как эксперимент, вы напоминаете себе, что это не окончательное решение. Это выбор двигаться вперёд, а не стоять на месте.
Помните, что, если эксперимент пойдет не так, вы (почти) всегда можете передумать. Ведь время – деньги. Во многих случаях отказ двигаться вперёд может оказаться даже более дорогостоящим, чем необходимость сменить курс.
Эмоции – это то, делает нас людьми. Ключ к эмоциональному интеллекту — заставить эмоции работать на вас, а не против вас.
Источник: https://www.inc.com/justin-bariso/emotional-intelligence-how-to-cope-communicate-improve-relationships.html
👍16
День 1573. #ЗаметкиНаПолях
Генерация Больших Файлов с Помощью PowerShell
Сегодня очень короткая заметка, которую захотел сохранить, чтобы найти её в ленте, когда понадобится.
Если вам нужно создать большой файл со случайными данными для целей тестирования (например, мне как-то нужно было протестировать работу полосы загрузки файла на сайте), вы можете использовать PowerShell, чтобы быстро его создать.
Генерация Больших Файлов с Помощью PowerShell
Сегодня очень короткая заметка, которую захотел сохранить, чтобы найти её в ленте, когда понадобится.
Если вам нужно создать большой файл со случайными данными для целей тестирования (например, мне как-то нужно было протестировать работу полосы загрузки файла на сайте), вы можете использовать PowerShell, чтобы быстро его создать.
# Здесь $pwd – текущий путьЕсли вам нужен пустой файл (заполненный нулями), то в Windows можно просто использовать fsutil, что намного быстрее:
$path = Join-Path $pwd "test.txt"
$size = 1GB
$content = New-Object byte[] $size
(New-Object System.Random).NextBytes($content)
# Set-Content очень медленный, поэтому
# используем метод .NET напрямую
[System.IO.File]::WriteAllBytes($path, $content)
$size = 1GBИсточник: https://www.meziantou.net/generate-large-files-using-powershell.htm
fsutil file createNew test.txt $size
👍23
День 1574. #DevOps #ProjectManagement
Без Паники! Пособие по Управлению Любым Инцидентом в Продакшене. Начало
Независимо от того, насколько сильна ваша организация, насколько тщательно планирование и развертывание… всё когда-нибудь ломается. Системы выходят из строя, ключевые функции перестают работать, и в какой-то момент карьеры каждого разработчика возникает проблема.
Природа этих проблем меняется с течением времени, но некоторые вещи остаются неизменными в том, как вы смотрите на проблемы и как люди могут работать, чтобы убедиться, что вы надёжно их исправите. И чтобы было ясно, мы не говорим о серийных багах в продакшене, мы говорим о проблемах, которые являются большими и объёмными, но в то же время деликатными. Следующие шаги применимы к людям на всех уровнях и могут дать некоторое представление о том, через что проходят люди на разных ролях в компании.
Шаг 1. Не паникуйте и определите проблему
В один прекрасный день базовая функциональность приложения перестаёт работать. Команда разработчиков собирается в совещательной комнате, чтобы найти решение проблемы. Инстинктивная реакция: «Быстрее, откатывай всё назад!» Это понятное чувство, мы создали проблемы, и, естественно, есть желание от них избавиться. Но с быстрыми действиями приходят и быстрые ошибки, и более опытные разработчики здесь резонно зададут вопрос: «А почему не работает?». Да, вашей реакцией может быть: «Кого это волнует? Наша ошибка видна всему миру!» Но спокойный характер и аналитическая манера поведения успокоят команду и убедят, что то, что происходит в этой комнате, правильно: надо задавать вопросы и исследовать.
Шаг 2. Диагностика и понимание источника проблемы
Это звучит как очевидная вещь, но из-за беспокойства и паники никто может не задаться этим вопросом. Оставьте проблему, чтобы убедиться, что вы знаете, почему это не работает. Перепроверьте журналы исключений, отдельные рабочие процессы или даже не было ли чего-то странного на системном уровне. Воспроизведите ошибку (здесь очень поможет, если ваши среды разработки настроены максимально идентично производственной среде). После того, как вы поймёте, что сделали не так, и наберётесь достаточно уверенности для следующего выпуска, начинайте откат. Это тонкий момент, но учитесь всегда использовать все возможности для поиска природы ошибки, прежде чем откатиться и потерять свой лучший источник информации: реальную проблему в дикой природе.
Также важно найти кого-то, кто займётся техническими вопросами и сможет помочь координировать усилия по исправлению (обычно это более старший разработчик), и кого-то, кто будет отвечать за «пиар для внешней среды» и «прикрытие с воздуха» тех, кто может захотеть потратить время на изучение ошибки (обычно это директор или технический руководитель). Это делается для защиты самого ценного ресурса во время кризиса: времени и внимания тех, кто действительно может реализовать план исправления.
Более технический специалист нужен, чтобы помочь разбить решение на этапы и делегировать или разделить работу, которую необходимо выполнить. А лидер инцидента (как его часто иронически называют) должен помогать, но не диктовать. Лучшие лидеры инцидентов задают два вопроса: «На каком этапе мы находимся?» и «Что вам нужно?», а также могут держать рассерженных пользователей подальше от специалистов, решающих проблему.
Окончание следует…
Источник: https://stackoverflow.blog/2023/05/03/dont-panic-a-playbook-for-managing-any-production-incident/
Без Паники! Пособие по Управлению Любым Инцидентом в Продакшене. Начало
Независимо от того, насколько сильна ваша организация, насколько тщательно планирование и развертывание… всё когда-нибудь ломается. Системы выходят из строя, ключевые функции перестают работать, и в какой-то момент карьеры каждого разработчика возникает проблема.
Природа этих проблем меняется с течением времени, но некоторые вещи остаются неизменными в том, как вы смотрите на проблемы и как люди могут работать, чтобы убедиться, что вы надёжно их исправите. И чтобы было ясно, мы не говорим о серийных багах в продакшене, мы говорим о проблемах, которые являются большими и объёмными, но в то же время деликатными. Следующие шаги применимы к людям на всех уровнях и могут дать некоторое представление о том, через что проходят люди на разных ролях в компании.
Шаг 1. Не паникуйте и определите проблему
В один прекрасный день базовая функциональность приложения перестаёт работать. Команда разработчиков собирается в совещательной комнате, чтобы найти решение проблемы. Инстинктивная реакция: «Быстрее, откатывай всё назад!» Это понятное чувство, мы создали проблемы, и, естественно, есть желание от них избавиться. Но с быстрыми действиями приходят и быстрые ошибки, и более опытные разработчики здесь резонно зададут вопрос: «А почему не работает?». Да, вашей реакцией может быть: «Кого это волнует? Наша ошибка видна всему миру!» Но спокойный характер и аналитическая манера поведения успокоят команду и убедят, что то, что происходит в этой комнате, правильно: надо задавать вопросы и исследовать.
Шаг 2. Диагностика и понимание источника проблемы
Это звучит как очевидная вещь, но из-за беспокойства и паники никто может не задаться этим вопросом. Оставьте проблему, чтобы убедиться, что вы знаете, почему это не работает. Перепроверьте журналы исключений, отдельные рабочие процессы или даже не было ли чего-то странного на системном уровне. Воспроизведите ошибку (здесь очень поможет, если ваши среды разработки настроены максимально идентично производственной среде). После того, как вы поймёте, что сделали не так, и наберётесь достаточно уверенности для следующего выпуска, начинайте откат. Это тонкий момент, но учитесь всегда использовать все возможности для поиска природы ошибки, прежде чем откатиться и потерять свой лучший источник информации: реальную проблему в дикой природе.
Также важно найти кого-то, кто займётся техническими вопросами и сможет помочь координировать усилия по исправлению (обычно это более старший разработчик), и кого-то, кто будет отвечать за «пиар для внешней среды» и «прикрытие с воздуха» тех, кто может захотеть потратить время на изучение ошибки (обычно это директор или технический руководитель). Это делается для защиты самого ценного ресурса во время кризиса: времени и внимания тех, кто действительно может реализовать план исправления.
Более технический специалист нужен, чтобы помочь разбить решение на этапы и делегировать или разделить работу, которую необходимо выполнить. А лидер инцидента (как его часто иронически называют) должен помогать, но не диктовать. Лучшие лидеры инцидентов задают два вопроса: «На каком этапе мы находимся?» и «Что вам нужно?», а также могут держать рассерженных пользователей подальше от специалистов, решающих проблему.
Окончание следует…
Источник: https://stackoverflow.blog/2023/05/03/dont-panic-a-playbook-for-managing-any-production-incident/
👍10
День 1575. #DevOps #ProjectManagement
Без Паники! Пособие по Управлению Любым Инцидентом в Продакшене. Окончание
Начало
Шаг 3. Исправление: начнём работать над проблемой
Мы знаем, что у нас есть проблема, мы знаем источник проблемы, теперь давайте составим план и исправим её. Мы все любим переходить к этому шагу, сразу приступать к исправлению. И иногда у нас есть такая роскошь для простых вопросов, когда проблема настолько очевидна, что подтверждение и понимание источника проблемы — быстрые шаги. Но если проблема зашла далеко или она серьезная, нужно поступать более обдуманно.
Тут координатор поможет расставить приоритеты в работе, выяснить, где находятся самые важные шаги по смягчению последствий, и убедиться, что у всех заинтересованных сторон есть чёткие ожидания относительно того, что надо делать и какой будет результат. Разработчик, работающий над проблемой, обязан привлечь этого человека, убедиться, что он предоставит ему ресурсы, необходимые для решения проблемы. Это может быть время, доступ или другие люди, у которых есть специфические знания. Это важная тема на данном этапе: дать инженерам то, что им нужно, чтобы исправить ситуацию. Возможно, это должно волновать всех инженеров-руководителей не только тогда, когда что-то пошло не так, и жизненно важные рабочие процессы встали.
Больше всего во время кризиса не хватает не информации или помощи других разработчиков, а возможности сфокусироваться. Это может показаться странным, но это чувство знакомо любому, кто был в одной лодке с лидерами, которые паникуют или никогда не понимали заблуждений мифического человеко-месяца. Они с нетерпением ждут новостей о ходе работы, и что может быть лучше, чем собирать всех на митинги четыре раза в день, чтобы узнать, как продвигаются дела. А это постоянные отвлечения, переключения контекста и обновления багтрекеров. Способность сосредоточиться и избавиться от отвлекающих факторов - самый важный фактор для решения проблемы.
Шаг 4. Проверка и обучение
Если все пойдёт хорошо, тесты подтвердятся, и вся ценная информация, полученная на шагах 1 и 2, даст вам уверенность в новых планах тестирования, вы можете развернуть исправление. Как только оно будет опубликовано, дайте время команде на всех уровнях, чтобы изучить его и подтвердить, что всё работает как надо. Если инженерам в начале этих инцидентов даются время и свобода, то они более уверенно и спокойно относятся к последующим релизам и исправлениям.
Однако, публикация исправления и уверенность команды в его правильности – лишь половина дела. Теперь нужно сделать так, чтобы болезненный и возможно дорогостоящий опыт этой проблемы способствовал развитию команды. Люди часто воспринимают крупные кризисы, как проблему, которая никогда больше не повторится, что совершенно неразумно. Часто лучшее обучение — это учиться справляться с проблемами, а не притворяться, будто мы можем их избежать.
В конце концов, чаще всего всё сводится к элементарной человеческой ошибке. Поэтому техническому руководителю нужно быть больше сосредоточенным не на предотвращении ошибок, а на оттачивании способности команды справляться с ними. Да, важна работа по предотвращению будущих подобных ошибок. Но часто есть больше возможностей для улучшения того, как команда реагирует на ошибку. Как дать инженерам больше возможностей для концентрации? Как можно ускорить расследование инцидента? Или даже кто лучше всего справляется с коммуникацией между разными специалистами или командами и какая информация им нужна?
Источник: https://stackoverflow.blog/2023/05/03/dont-panic-a-playbook-for-managing-any-production-incident/
Без Паники! Пособие по Управлению Любым Инцидентом в Продакшене. Окончание
Начало
Шаг 3. Исправление: начнём работать над проблемой
Мы знаем, что у нас есть проблема, мы знаем источник проблемы, теперь давайте составим план и исправим её. Мы все любим переходить к этому шагу, сразу приступать к исправлению. И иногда у нас есть такая роскошь для простых вопросов, когда проблема настолько очевидна, что подтверждение и понимание источника проблемы — быстрые шаги. Но если проблема зашла далеко или она серьезная, нужно поступать более обдуманно.
Тут координатор поможет расставить приоритеты в работе, выяснить, где находятся самые важные шаги по смягчению последствий, и убедиться, что у всех заинтересованных сторон есть чёткие ожидания относительно того, что надо делать и какой будет результат. Разработчик, работающий над проблемой, обязан привлечь этого человека, убедиться, что он предоставит ему ресурсы, необходимые для решения проблемы. Это может быть время, доступ или другие люди, у которых есть специфические знания. Это важная тема на данном этапе: дать инженерам то, что им нужно, чтобы исправить ситуацию. Возможно, это должно волновать всех инженеров-руководителей не только тогда, когда что-то пошло не так, и жизненно важные рабочие процессы встали.
Больше всего во время кризиса не хватает не информации или помощи других разработчиков, а возможности сфокусироваться. Это может показаться странным, но это чувство знакомо любому, кто был в одной лодке с лидерами, которые паникуют или никогда не понимали заблуждений мифического человеко-месяца. Они с нетерпением ждут новостей о ходе работы, и что может быть лучше, чем собирать всех на митинги четыре раза в день, чтобы узнать, как продвигаются дела. А это постоянные отвлечения, переключения контекста и обновления багтрекеров. Способность сосредоточиться и избавиться от отвлекающих факторов - самый важный фактор для решения проблемы.
Шаг 4. Проверка и обучение
Если все пойдёт хорошо, тесты подтвердятся, и вся ценная информация, полученная на шагах 1 и 2, даст вам уверенность в новых планах тестирования, вы можете развернуть исправление. Как только оно будет опубликовано, дайте время команде на всех уровнях, чтобы изучить его и подтвердить, что всё работает как надо. Если инженерам в начале этих инцидентов даются время и свобода, то они более уверенно и спокойно относятся к последующим релизам и исправлениям.
Однако, публикация исправления и уверенность команды в его правильности – лишь половина дела. Теперь нужно сделать так, чтобы болезненный и возможно дорогостоящий опыт этой проблемы способствовал развитию команды. Люди часто воспринимают крупные кризисы, как проблему, которая никогда больше не повторится, что совершенно неразумно. Часто лучшее обучение — это учиться справляться с проблемами, а не притворяться, будто мы можем их избежать.
В конце концов, чаще всего всё сводится к элементарной человеческой ошибке. Поэтому техническому руководителю нужно быть больше сосредоточенным не на предотвращении ошибок, а на оттачивании способности команды справляться с ними. Да, важна работа по предотвращению будущих подобных ошибок. Но часто есть больше возможностей для улучшения того, как команда реагирует на ошибку. Как дать инженерам больше возможностей для концентрации? Как можно ускорить расследование инцидента? Или даже кто лучше всего справляется с коммуникацией между разными специалистами или командами и какая информация им нужна?
Источник: https://stackoverflow.blog/2023/05/03/dont-panic-a-playbook-for-managing-any-production-incident/
👍8
День 1576. #ЗаметкиНаПолях
Загрузка Больших Файлов в ASP.NET Core. Начало
Недавно мы рассмотрели, как создавать большие файлы для тестов, сегодня посмотрим, как обрабатывать загрузку больших файлов в ASP.NET Core.
Потоки, как правило, лучше, чем использование byte[] или MemoryStream при обработке больших файлов по нескольким причинам:
- Потоки могут значительно сократить использование памяти, т.к. обрабатывают файл блоками, обеспечивая более эффективное управление памятью.
- Использование потоков также может повысить скорость обработки, позволяя одновременно читать и записывать файл.
Для поддержки больших файлов нам нужно сделать несколько вещей:
- настроить Kestrel,
- добавить атрибуты валидации,
- добавить метод обработки и сервис загрузки файлов (об этом в следующем посте).
1. Настройка Kestrel
Нужно настроить Kestrel в файле Program.cs, чтобы разрешить загрузку больших файлов:
2. Атрибуты валидации
Определим 2 атрибута фильтров действия для валидации контента.
1) MultipartFormDataAttribute проверит, что способом отправки является "multipart/form-data":
Источник: https://code-maze.com/aspnetcore-upload-large-files/
Загрузка Больших Файлов в ASP.NET Core. Начало
Недавно мы рассмотрели, как создавать большие файлы для тестов, сегодня посмотрим, как обрабатывать загрузку больших файлов в ASP.NET Core.
Потоки, как правило, лучше, чем использование byte[] или MemoryStream при обработке больших файлов по нескольким причинам:
- Потоки могут значительно сократить использование памяти, т.к. обрабатывают файл блоками, обеспечивая более эффективное управление памятью.
- Использование потоков также может повысить скорость обработки, позволяя одновременно читать и записывать файл.
Для поддержки больших файлов нам нужно сделать несколько вещей:
- настроить Kestrel,
- добавить атрибуты валидации,
- добавить метод обработки и сервис загрузки файлов (об этом в следующем посте).
1. Настройка Kestrel
Нужно настроить Kestrel в файле Program.cs, чтобы разрешить загрузку больших файлов:
builder.WebHost.ConfigureKestrel(opts =>Здесь long.MaxValue приведено для примера и позволяет загружать файлы практически любого размера. В реальности задайте значение, которое нужно вам. Также можно использовать атрибут RequestSizeLimit на отдельном методе действия.
{
opts.Limits.MaxRequestBodySize
= long.MaxValue;
});
2. Атрибуты валидации
Определим 2 атрибута фильтров действия для валидации контента.
1) MultipartFormDataAttribute проверит, что способом отправки является "multipart/form-data":
public class MultipartFormDataAttribute2) Также нужно отключить проверку модели, чтобы связыватели модели не проверяли тело и не загружали его в память или на диск:
: ActionFilterAttribute
{
public override void
OnActionExecuting(
ActionExecutingContext ctx)
{
var r = ctx.HttpContext.Request;
if (r.HasFormContentType
&& r.ContentType
.StartsWith("multipart/form-data"))
return;
ctx.Result = new
StatusCodeResult(
StatusCodes.Status415UnsupportedMediaType);
}
}
public class DisableModelBindingAttribute :Окончание следует…
Attribute, IResourceFilter
{
public void OnResourceExecuting(
ResourceExecutingContext ctx)
{
var f = ctx.ValueProviderFactories;
f.RemoveType<FormValueProviderFactory>();
f.RemoveType<FormFileValueProviderFactory>();
f.RemoveType<JQueryFormValueProviderFactory>();
}
}
Источник: https://code-maze.com/aspnetcore-upload-large-files/
👍17
День 1577. #ЗаметкиНаПолях
Загрузка Больших Файлов в ASP.NET Core. Окончание
Начало
3. Теперь посмотрим на метод действия контроллера и сервис для загрузки файлов:
Метод вызывает UploadAsync из сервиса FileService, который показан ниже:
Полный и более подробный код проекта на GitHub.
Посмотрим, как отправлять файлы с помощью Postman:
Нужно выбрать опцию form-data и добавить пары ключ-значение, где ключом будет имя файла, а значением - сам файл. Также проверьте, что установлен заголовок Content-Type со значением «
Итого
Загрузка больших файлов может быть сложной задачей, но использование потоков значительно упрощает этот процесс. Благодаря потокам мы можем эффективно читать и записывать данные небольшими порциями, сводя к минимуму использование памяти и позволяя обрабатывать большие файлы без проблем с производительностью.
Источник: https://code-maze.com/aspnetcore-upload-large-files/
Загрузка Больших Файлов в ASP.NET Core. Окончание
Начало
3. Теперь посмотрим на метод действия контроллера и сервис для загрузки файлов:
[HttpPost("upload")]Здесь у нас есть метод действия HTTP POST, который имеет атрибуты, созданные в предыдущем посте, гарантирующие, что входящий запрос имеет правильный тип содержимого "multipart/form-data" и отключающие проверку модели.
[MultipartFormData]
[DisableModelBinding]
public async Task<IActionResult> Upload()
{
var len = await _fileSvc
.UploadAsync(
HttpContext.Request.Body,
Request.ContentType);
return CreatedAtAction(nameof(Upload), len);
}
Метод вызывает UploadAsync из сервиса FileService, который показан ниже:
public async Task<long> UploadAsync(Метод UploadAsync считывает составные данные из входного потока и сохраняет каждый файл на диск. Файлы должны быть разделены границей, определённой в заголовке Content-Type. Мы извлекаем эту границу в переменную bound, затем читаем каждый файл в цикле. Также вычисляем общий размер загруженных файлов.
Stream file, string contentType)
{
long size = 0;
var bound =
HeaderUtilities.RemoveQuotes(
MediaTypeHeaderValue
.Parse(contentType).Boundary)
.Value;
var reader =
new MultipartReader(bound, file);
var sect =
await reader.ReadNextSectionAsync();
while (sect != null)
{
var fileSec = sect.AsFileSection();
if (fileSec is null) continue;
var path = Path.Combine("uploads",
fileSec.FileName);
await using var stream =
new FileStream(path,
FileMode.Create,
FileAccess.Write,
FileShare.None,
1024);
await fileSec.FileStream?
.CopyToAsync(stream);
size += fileSec.FileStream.Length;
sect = await
reader.ReadNextSectionAsync();
}
return size;
}
Полный и более подробный код проекта на GitHub.
Посмотрим, как отправлять файлы с помощью Postman:
Нужно выбрать опцию form-data и добавить пары ключ-значение, где ключом будет имя файла, а значением - сам файл. Также проверьте, что установлен заголовок Content-Type со значением «
multipart/form-data; border=…
» на вкладке заголовков.Итого
Загрузка больших файлов может быть сложной задачей, но использование потоков значительно упрощает этот процесс. Благодаря потокам мы можем эффективно читать и записывать данные небольшими порциями, сводя к минимуму использование памяти и позволяя обрабатывать большие файлы без проблем с производительностью.
Источник: https://code-maze.com/aspnetcore-upload-large-files/
👍16
День 1578. #Testing
Проверяем Юнит-Тесты с Помощью Мутационного Тестирования
Когда-то давно (практически на заре существования канала 😊) я уже писал про мутационное тестирование и как оно помогает проверить, правильно ли ваши юнит-тесты проверяют ваш код.
Недавно на канале JetBrains вышло видео, в котором Stefan Pölz, старший разработчик в Tryport, Microsoft MVP и контрибутор в JetBrains, подробно рассказывает, что такое мутационное тестирование, и как его интегрировать в Azure Pipelines или GitHub Actions.
https://youtu.be/9BoKyeZapLs
Проверяем Юнит-Тесты с Помощью Мутационного Тестирования
Когда-то давно (практически на заре существования канала 😊) я уже писал про мутационное тестирование и как оно помогает проверить, правильно ли ваши юнит-тесты проверяют ваш код.
Недавно на канале JetBrains вышло видео, в котором Stefan Pölz, старший разработчик в Tryport, Microsoft MVP и контрибутор в JetBrains, подробно рассказывает, что такое мутационное тестирование, и как его интегрировать в Azure Pipelines или GitHub Actions.
https://youtu.be/9BoKyeZapLs
👍3
День 1579. #Карьера
Как Пережить Плохой День на Работе
Когда у вас плохой день, ваш разум зацикливается на неудачах. Вы теряете самообладание или плохо реагируете даже на незначительные неудобства. Может показаться, что все хотят вас достать, а мелкие конфликты перерастают в серьёзные проблемы. Хотя трудно искать светлую сторону вещей, когда разум забит негативом, есть четыре вещи, которые нужно сделать, чтобы плохой день не превратился в плохую неделю.
Шаг 1. Определите, чем это спровоцировано
Чем больше вы откладываете решение или признание того, что что-то не так, тем хуже становится. Психологи называют это эмоциональным избеганием. Избегать негативных эмоций вполне естественно, но вместо этого научитесь их принимать. Эмоции немного похожи на прогноз погоды. Их важно знать, учитывать и понимать, но они не являются решающим фактором в ваших жизненных планах. Не нужно отрицать плохую погоду или сосредоточивать на ней всё внимание, нужно её принять и скорректировать свои планы. Принятие эмоции позволяет превратить размышления в продуктивность, проблему в решение, а препятствие в возможность.
- Подумайте, что пошло не так.
- Не вините никого, не жалуйтесь. Определите, что можно сделать в следующий раз, чтобы этого не повторилось.
- Если другой человек является источником ваших страданий, не принимайте это на свой счёт. Чужое плохое поведение не отражает того, кем вы являетесь как личность.
Шаг 2. Позвольте себе замедлиться
Плохой день на работе не заставит ваши планы исчезнуть. Но разум не может сосредоточиться на работе. Большинство людей в этой ситуации либо:
- Уходят в самокритику, т.к не могут сделать запланированное.
- Заставляют себя действовать «через не могу».
Ругая себя за свои недостатки, вы только больше демотивируете себя. А превозмогание стресса может повлиять на психическое здоровье и личное благополучие. Вместо этого, проявите сочувствие к себе. Остановитесь, чтобы сказать себе: «сейчас мне действительно трудно», как я могу себе помочь? Исследования показывают, что сочувствие к себе тесно связано с эмоциональной устойчивостью и психологическим благополучием. Будьте добры к себе и отложите принятие важных решений или сделайте что-нибудь, что очистит ваш разум. Заботиться о себе, когда вы расстроены, важнее, чем быть продуктивным.
Шаг 3. Возродите позитивные связи
В плохой день всё, что заряжает вас энергией, обязательно изменит ваше настроение и поможет увидеть, что всё не так плохо, как казалось сначала. Сделайте паузу и определите, что вас заряжает энергией. Не обязательно пункт из списка дел и результат деятельности не имеет значения. Смысл в самоощущении. Небольшое позитивное действие разорвет негативный цикл размышлений и заменит его позитивными мыслями. Чтобы сохранить это чувство, подумайте о своих сильных сторонах и навыках, прошлых достижениях или обо всём, что вы сделали хорошо. Это вдохновит вас переключиться с деструктивных мыслей на созидательные действия. Вы всё ещё можете быть разочарованы событиями дня, но это разочарование не приведёт к ощущению безнадёжности и беспомощности.
Шаг 4: Работа на будущее
Взлеты и падения – то, что делает жизнь нескучной. Но в плохой день, легко поддаться негативу. Разум поглощен неприятностями, вы зацикливаетесь на вещах, которые даже не имеют значения в долгосрочной перспективе. Вместо этого спроецируйте плохой день на будущее:
- Как то, что произошло сегодня, влияет на ваши цели?
- Что это будет значить для вас через неделю, месяц, год?
- Это в вашей власти? Что вы можете сделать, чтобы этого не повторилось?
Так вы поймете, что тратите время и энергию на мелочи или заботы, которые в долгосрочной перспективе не будут иметь значения. Даже если это что-то важное, найти решение гораздо продуктивнее, чем погружаться в гнев и разочарование.
В следующий раз, когда у вас будет плохой день, не тоните в страданиях. Воспринимайте это как возможность понять свои эмоции, не торопиться, заняться чем-нибудь весёлым и переоценить свои приоритеты.
Источник: https://betterprogramming.pub/how-to-deal-with-a-bad-day-at-work-89d85ecc57bb
Как Пережить Плохой День на Работе
Когда у вас плохой день, ваш разум зацикливается на неудачах. Вы теряете самообладание или плохо реагируете даже на незначительные неудобства. Может показаться, что все хотят вас достать, а мелкие конфликты перерастают в серьёзные проблемы. Хотя трудно искать светлую сторону вещей, когда разум забит негативом, есть четыре вещи, которые нужно сделать, чтобы плохой день не превратился в плохую неделю.
Шаг 1. Определите, чем это спровоцировано
Чем больше вы откладываете решение или признание того, что что-то не так, тем хуже становится. Психологи называют это эмоциональным избеганием. Избегать негативных эмоций вполне естественно, но вместо этого научитесь их принимать. Эмоции немного похожи на прогноз погоды. Их важно знать, учитывать и понимать, но они не являются решающим фактором в ваших жизненных планах. Не нужно отрицать плохую погоду или сосредоточивать на ней всё внимание, нужно её принять и скорректировать свои планы. Принятие эмоции позволяет превратить размышления в продуктивность, проблему в решение, а препятствие в возможность.
- Подумайте, что пошло не так.
- Не вините никого, не жалуйтесь. Определите, что можно сделать в следующий раз, чтобы этого не повторилось.
- Если другой человек является источником ваших страданий, не принимайте это на свой счёт. Чужое плохое поведение не отражает того, кем вы являетесь как личность.
Шаг 2. Позвольте себе замедлиться
Плохой день на работе не заставит ваши планы исчезнуть. Но разум не может сосредоточиться на работе. Большинство людей в этой ситуации либо:
- Уходят в самокритику, т.к не могут сделать запланированное.
- Заставляют себя действовать «через не могу».
Ругая себя за свои недостатки, вы только больше демотивируете себя. А превозмогание стресса может повлиять на психическое здоровье и личное благополучие. Вместо этого, проявите сочувствие к себе. Остановитесь, чтобы сказать себе: «сейчас мне действительно трудно», как я могу себе помочь? Исследования показывают, что сочувствие к себе тесно связано с эмоциональной устойчивостью и психологическим благополучием. Будьте добры к себе и отложите принятие важных решений или сделайте что-нибудь, что очистит ваш разум. Заботиться о себе, когда вы расстроены, важнее, чем быть продуктивным.
Шаг 3. Возродите позитивные связи
В плохой день всё, что заряжает вас энергией, обязательно изменит ваше настроение и поможет увидеть, что всё не так плохо, как казалось сначала. Сделайте паузу и определите, что вас заряжает энергией. Не обязательно пункт из списка дел и результат деятельности не имеет значения. Смысл в самоощущении. Небольшое позитивное действие разорвет негативный цикл размышлений и заменит его позитивными мыслями. Чтобы сохранить это чувство, подумайте о своих сильных сторонах и навыках, прошлых достижениях или обо всём, что вы сделали хорошо. Это вдохновит вас переключиться с деструктивных мыслей на созидательные действия. Вы всё ещё можете быть разочарованы событиями дня, но это разочарование не приведёт к ощущению безнадёжности и беспомощности.
Шаг 4: Работа на будущее
Взлеты и падения – то, что делает жизнь нескучной. Но в плохой день, легко поддаться негативу. Разум поглощен неприятностями, вы зацикливаетесь на вещах, которые даже не имеют значения в долгосрочной перспективе. Вместо этого спроецируйте плохой день на будущее:
- Как то, что произошло сегодня, влияет на ваши цели?
- Что это будет значить для вас через неделю, месяц, год?
- Это в вашей власти? Что вы можете сделать, чтобы этого не повторилось?
Так вы поймете, что тратите время и энергию на мелочи или заботы, которые в долгосрочной перспективе не будут иметь значения. Даже если это что-то важное, найти решение гораздо продуктивнее, чем погружаться в гнев и разочарование.
В следующий раз, когда у вас будет плохой день, не тоните в страданиях. Воспринимайте это как возможность понять свои эмоции, не торопиться, заняться чем-нибудь весёлым и переоценить свои приоритеты.
Источник: https://betterprogramming.pub/how-to-deal-with-a-bad-day-at-work-89d85ecc57bb
👍15
День 1580. #ЧтоНовенького
.NET 8 Расширяет Возможности Blazor и WebAssembly
Microsoft работает над повышением производительности веб-приложений с помощью рендеринга Blazor на стороне сервера и потокового рендеринга, а также улучшений среды выполнения Blazor WebAssembly.
На прошлой неделе Microsoft подробно изложили планы будущей среды разработки .NET 8. Для веб-разработки .NET 8 будет сочетать сильные стороны рендеринга на стороне сервера и на стороне клиента в компонентной модели Blazor.
Теперь доступный в версии превью 4 .NET 8 использует отрисовку на стороне сервера с компонентами Blazor, улучшенную навигацию и обработку форм, а также потоковую отрисовку. По словам Microsoft, потоковая отрисовка, при которой обновления контента передаются в поток ответов, может улучшить взаимодействие с пользователем для страниц, генерируемых на стороне сервера, которым необходимо выполнять длительные асинхронные задачи для полной визуализации.
Например, чтобы отобразить страницу, вам может потребоваться выполнить длительный запрос к базе данных или вызов API. Обычно все асинхронные задачи, выполняемые как часть рендеринга страницы, должны быть завершены до отправки обработанного ответа, что может привести к задержке загрузки страницы. Потоковая визуализация изначально отображает всю страницу с содержимым-заполнителем во время выполнения асинхронных операций. После завершения асинхронных операций обновленное содержимое отправляется клиенту по тому же ответному соединению, а затем Blazor вносит исправления в DOM. Преимущество такого подхода заключается в том, что основной макет приложения отображается максимально быстро, а страница обновляется, как только контент готов.
Разработчики смогут добавлять клиентскую интерактивность для каждого компонента или страницы в отдельности, а также выбирать режим рендеринга во время выполнения. Рендеринг на стороне сервера и потоковый рендеринг стали доступны в .NET 8 Preview 3 и .NET 8 Preview 4 соответственно. Дополнительные механизмы будут добавлены в следующих предварительных версиях.
В .NET 8 разработчики также могут взять компонент Blazor и отобразить его полностью вне контекста HTTP-запроса. Компонент может отображаться через HTML как строка или поток, независимо от среды размещения (серверной или WebAssembly). Это полезно для создания фрагментов HTML, таких как автоматическое электронное письмо. В Microsoft заявляют, что в будущем это позволит генерировать статический контент сайта для Blazor.
Microsoft также работает над улучшением производительности .NET в браузерах с помощью WebAssembly. Jiterpreter в .NET 8 предлагает частичную поддержку JIT и повышает производительность среды выполнения .NET WebAssembly. Microsoft сообщает, что рендеринг пользовательского интерфейса в тестах стал на 20% быстрее благодаря jiterpreter, а сериализация и десериализация JSON выполняются в два раза быстрее. Последние спецификации WebAssembly, такие как SIMD для предварительной (AOT) компиляции, наряду с улучшениями горячей перезагрузки, также используются для WebAssembly.
Также для приложений Blazor WebAssembly используется новый удобный для Интернета формат упаковки Webcil. Webcil представляет собой веб-ориентированную упаковку сборок .NET, которая удаляет всё содержимое, относящееся к нативному выполнению Windows, чтобы избежать проблем при развертывании в средах, которые блокируют загрузку или использование DLL-файлов.
Источники:
- https://www.infoworld.com/article/3697728/microsoft-net-8-boosts-blazor-webassembly.html
- https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-4/
.NET 8 Расширяет Возможности Blazor и WebAssembly
Microsoft работает над повышением производительности веб-приложений с помощью рендеринга Blazor на стороне сервера и потокового рендеринга, а также улучшений среды выполнения Blazor WebAssembly.
На прошлой неделе Microsoft подробно изложили планы будущей среды разработки .NET 8. Для веб-разработки .NET 8 будет сочетать сильные стороны рендеринга на стороне сервера и на стороне клиента в компонентной модели Blazor.
Теперь доступный в версии превью 4 .NET 8 использует отрисовку на стороне сервера с компонентами Blazor, улучшенную навигацию и обработку форм, а также потоковую отрисовку. По словам Microsoft, потоковая отрисовка, при которой обновления контента передаются в поток ответов, может улучшить взаимодействие с пользователем для страниц, генерируемых на стороне сервера, которым необходимо выполнять длительные асинхронные задачи для полной визуализации.
Например, чтобы отобразить страницу, вам может потребоваться выполнить длительный запрос к базе данных или вызов API. Обычно все асинхронные задачи, выполняемые как часть рендеринга страницы, должны быть завершены до отправки обработанного ответа, что может привести к задержке загрузки страницы. Потоковая визуализация изначально отображает всю страницу с содержимым-заполнителем во время выполнения асинхронных операций. После завершения асинхронных операций обновленное содержимое отправляется клиенту по тому же ответному соединению, а затем Blazor вносит исправления в DOM. Преимущество такого подхода заключается в том, что основной макет приложения отображается максимально быстро, а страница обновляется, как только контент готов.
Разработчики смогут добавлять клиентскую интерактивность для каждого компонента или страницы в отдельности, а также выбирать режим рендеринга во время выполнения. Рендеринг на стороне сервера и потоковый рендеринг стали доступны в .NET 8 Preview 3 и .NET 8 Preview 4 соответственно. Дополнительные механизмы будут добавлены в следующих предварительных версиях.
В .NET 8 разработчики также могут взять компонент Blazor и отобразить его полностью вне контекста HTTP-запроса. Компонент может отображаться через HTML как строка или поток, независимо от среды размещения (серверной или WebAssembly). Это полезно для создания фрагментов HTML, таких как автоматическое электронное письмо. В Microsoft заявляют, что в будущем это позволит генерировать статический контент сайта для Blazor.
Microsoft также работает над улучшением производительности .NET в браузерах с помощью WebAssembly. Jiterpreter в .NET 8 предлагает частичную поддержку JIT и повышает производительность среды выполнения .NET WebAssembly. Microsoft сообщает, что рендеринг пользовательского интерфейса в тестах стал на 20% быстрее благодаря jiterpreter, а сериализация и десериализация JSON выполняются в два раза быстрее. Последние спецификации WebAssembly, такие как SIMD для предварительной (AOT) компиляции, наряду с улучшениями горячей перезагрузки, также используются для WebAssembly.
Также для приложений Blazor WebAssembly используется новый удобный для Интернета формат упаковки Webcil. Webcil представляет собой веб-ориентированную упаковку сборок .NET, которая удаляет всё содержимое, относящееся к нативному выполнению Windows, чтобы избежать проблем при развертывании в средах, которые блокируют загрузку или использование DLL-файлов.
Источники:
- https://www.infoworld.com/article/3697728/microsoft-net-8-boosts-blazor-webassembly.html
- https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-4/
👍14
День 1581. #ЗаметкиНаПолях
Мультитенантные Приложения с EF Core. Начало
Сегодня большинство программ основано на концепции мультитенантости, т.е. обслуживания нескольких клиентов, сохраняя при этом их данные изолированными. Это можно реализовать двумя способами:
1. Единая база данных и логическая изоляция,
2. Несколько баз данных и физическая изоляция.
1. Мультитенантость в единой базе данных
Для реализации мультитенантости понадобятся две вещи:
- Узнать текущего клиента,
- Отфильтровать данные только для этого клиента.
Типичный подход к мультитенантости в одной базе данных — наличие столбца TenantId в таблицах. А затем фильтрация по этому столбцу при запросе к базе данных. В EF Core мы можем использовать глобальный фильтр запросов. Внутри метода OnModelCreating мы настраиваем фильтр запросов для объекта Order:
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core
Мультитенантные Приложения с EF Core. Начало
Сегодня большинство программ основано на концепции мультитенантости, т.е. обслуживания нескольких клиентов, сохраняя при этом их данные изолированными. Это можно реализовать двумя способами:
1. Единая база данных и логическая изоляция,
2. Несколько баз данных и физическая изоляция.
1. Мультитенантость в единой базе данных
Для реализации мультитенантости понадобятся две вещи:
- Узнать текущего клиента,
- Отфильтровать данные только для этого клиента.
Типичный подход к мультитенантости в одной базе данных — наличие столбца TenantId в таблицах. А затем фильтрация по этому столбцу при запросе к базе данных. В EF Core мы можем использовать глобальный фильтр запросов. Внутри метода OnModelCreating мы настраиваем фильтр запросов для объекта Order:
public class OrdersContext : DbContextМы используем класс TenantProvider для получения текущего клиента:
{
private string _tenantId;
public OrdersContext(
DbContextOptions<OrdersContext> opt,
TenantProvider tp) : base(opt)
{
_tenantId = tp.TenantId;
}
protected override void
OnModelCreating(ModelBuilder mb)
{
mb.Entity<Order>
.HasQueryFilter(o =>
o.TenantId == _tenantId);
}
}
public class TenantProviderВ этом примере TenantId получается из заголовка HTTP-запроса. Также его можно извлекать из строки запроса, JWT Claim, ключа API и т.п. Последние два варианта более безопасны.
{
private IHttpContexAccessor _hca;
public TenantProvider(IHttpContexAccessor hca)
{
_hca = hca;
}
public string TenantId => _hca
.HttpContext.Request.Headers["X-TenantId"];
}
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core
👍15
День 1582. #ЗаметкиНаПолях
Мультитенантные Приложения с EF Core. Окончание
Начало
2. Мультитенантность в раздельных базах данных с помощью EF Core
В некоторых отраслях, таких как здравоохранение, требуется высокая степень изоляции данных, и использование базы данных для каждого клиента является обязательным. Если мы хотим изолировать каждого клиента в отдельной базе данных, нам нужно:
- Применить разные строки подключения для каждого клиента,
- Каким-то образом определять строку подключения для каждого клиента.
Здесь нельзя использовать фильтры запросов, так как мы работаем с разными базами. Поэтому нужно где-то хранить информацию о клиенте и строке подключения. Простым примером (если клиентов относительно немного) может быть сохранение их в настройках приложения:
Также нужно изменить класс TenantProvider, чтобы он возвращал строку подключения для текущего клиента:
Итого
Это, конечно, базовая реализация, которую можно улучшить, чтобы сделать более надёжной и безопасной. Построение мультитенантных систем — дело непростое, но, если вы понимаете основные принципы, это не должно быть слишком сложно.
Источник: https://www.milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core
Мультитенантные Приложения с EF Core. Окончание
Начало
2. Мультитенантность в раздельных базах данных с помощью EF Core
В некоторых отраслях, таких как здравоохранение, требуется высокая степень изоляции данных, и использование базы данных для каждого клиента является обязательным. Если мы хотим изолировать каждого клиента в отдельной базе данных, нам нужно:
- Применить разные строки подключения для каждого клиента,
- Каким-то образом определять строку подключения для каждого клиента.
Здесь нельзя использовать фильтры запросов, так как мы работаем с разными базами. Поэтому нужно где-то хранить информацию о клиенте и строке подключения. Простым примером (если клиентов относительно немного) может быть сохранение их в настройках приложения:
"Tenants": {Затем можно зарегистрировать экземпляр IOptions со списком объектов Tenant. Вот здесь подробнее про паттерн Options.
{ "Id": "tenant-1", "ConnectionString":
"Host=tenant1.db;Database=tenant1" },
{ "Id": "tenant-2", "ConnectionString":
"Host=tenant2.db;Database=tenant2" }
}
Также нужно изменить класс TenantProvider, чтобы он возвращал строку подключения для текущего клиента:
public sealed class TenantProviderИ последняя часть — это регистрация DbContext для динамического разрешения строки подключения для текущего клиента:
{
private IHttpContexAccessor _hca;
private TenantSettings _ts;
public TenantProvider(
IHttpContexAccessor hca,
IOptions<TenantSettings> opt)
{
_hca = hca;
_ts = opt.Value;
}
public string TenantId => _hca
.HttpContext.Request
.Headers["X-TenantId"];
public string GetConnectionString()
{
return _ts.Tenants
.Single(t => t.Id == TenantId);
}
}
builder.ServicesПри каждом запросе мы создаём новый OrdersContext и подключаемся к соответствующей базе данных для этого клиента. Обязательно следует хранить строки подключения клиента в безопасном месте, таком как Azure Key Vault.
.AddDbContext<OrdersContext>((sp, o) =>
{
var tp = sp.GetRequiredService<TenantProvider>();
var cs = tp.GetConnectionString();
o.UseSqlServer(cs);
});
Итого
Это, конечно, базовая реализация, которую можно улучшить, чтобы сделать более надёжной и безопасной. Построение мультитенантных систем — дело непростое, но, если вы понимаете основные принципы, это не должно быть слишком сложно.
Источник: https://www.milanjovanovic.tech/blog/multi-tenant-applications-with-ef-core
👍11
День 1583. #ЗаметкиНаПолях #TipsAndTricks
Интересные Вещи, Которые Можно Делать с Кортежами
Сегодня рассмотрим, что такое кортежи и некоторые вещи, которые можно сделать с ними.
Кортежи (ValueTuple) в C# — это упрощённый изменяемый тип-значение, который позволяет группировать несколько значений или связанных данных вместе для различных целей, таких как возврат нескольких значений из метода, создание структурированных данных и т.п. Он обеспечивает более высокую производительность по сравнению с традиционными ссылочными типами, поскольку не требует аллокации на куче.
1. Поменять местами два значения
Допустим, мы хотим поменять местами значения двух переменных:
А также простой способ сравнения двух объектов или получения хэш-кода:
Кортежи позволяют писать элегантный и выразительный код:
Кортежи позволяют легко разбить тип на отдельные переменные:
Источник: https://steven-giesel.com/blogPost/bcbb602f-4080-4e89-9929-019bb4e1cb58
Интересные Вещи, Которые Можно Делать с Кортежами
Сегодня рассмотрим, что такое кортежи и некоторые вещи, которые можно сделать с ними.
Кортежи (ValueTuple) в C# — это упрощённый изменяемый тип-значение, который позволяет группировать несколько значений или связанных данных вместе для различных целей, таких как возврат нескольких значений из метода, создание структурированных данных и т.п. Он обеспечивает более высокую производительность по сравнению с традиционными ссылочными типами, поскольку не требует аллокации на куче.
(string Name, int Age) person = ("Jon Smith", 42);Что же можно делать с помощью кортежей?
person.Name; // "Jon Smith"
person.Age; // 42
static (string Name, int Age) GetPerson()
=> ("Jon Smith", 42);
1. Поменять местами два значения
Допустим, мы хотим поменять местами значения двух переменных:
int a = 1;2. Простая реализация IEquatable
int b = 2;
// Замена
(a, b) = (b, a);
А также простой способ сравнения двух объектов или получения хэш-кода:
public class Dimension : IEquatable<Dimension>3. Сопоставление по шаблону
{
public Dimension(int width, int height)
=> (Width, Height) = (width, height);
public int Width { get; }
public int Height { get; }
public bool Equals(Dimension d)
=> (Width, Height) == (d?.Width, d?.Height);
public override bool Equals(object o)
=> o is Dimension d && Equals(d);
public override int GetHashCode()
=> (Width, Height).GetHashCode();
}
Кортежи позволяют писать элегантный и выразительный код:
(string Name, int Age) person = ("Alice", 25);4. Деконструкция пользовательских типов
string desc = person switch
{
("Alice", >= 0 and < 13) => "Alice ребёнок.",
("Alice", >= 13 and < 20) => "Alice подросток.",
("Alice", _) => "Alice взрослая.",
(_, >= 0 and < 13) => "Это ребёнок.",
(_, >= 13 and < 20) => "Это подросток.",
_ => "Это взрослый."
};
Кортежи позволяют легко разбить тип на отдельные переменные:
public class StudentСм. подробнее о деконструкции
{
public string Name { get; set; }
public int Age { get; set; }
public void Deconstruct(out string name, out int age)
{
name = Name;
age = Age;
}
}
var student = new Student { Name = "John", Age = 21 };
var (studentName, studentAge) = student;
Источник: https://steven-giesel.com/blogPost/bcbb602f-4080-4e89-9929-019bb4e1cb58
👍23
День 1584.
Папки Против Пространств Имён
Что, если ваша структура папок не будет соответствовать структуре пространств имён?
Поскольку для новичков большинство вещей впервой, иногда они делают что-то не так, как мы обычно делаем. Например, они знают про пространства имён, но могут не понимать, что структура файлов и папок должна отражать структуру пространств имён. Компилятору все равно, но я всегда делал это так. Для этого даже есть правило статического анализатора. Но в самом деле, что будет, если нарушить это соглашение?
Инструменты и шаблоны часто подталкивают вас к организации кода в соответствии с техническими проблемами: контроллеры, модели, представления и т. д. Код организован в папки, такие как Controllers, Models, DataAccess и т. п. Вы кладёте все контроллеры в папку Controllers и убеждаетесь, что пространство имён совпадает иерархии папок. Распространённой критикой является то, что это неправильный способ организации кода. Но это подразумевает, что есть правильный способ. Например, файлы должны быть организованы по папкам в соответствии с функциональностью, а не с техническим предназначением.
Однако если вы решите игнорировать соглашение о том, что структура пространств имён должна отражать структуру папок, у вас появится вторая ось вариативности. Например, если оставить организацию файлов по папкам в соответствии с техническим предназначением, но организовать пространства имён в соответствии с функциями: Users, Orders, Reservations и т.д., то открыв в IDE окно Class View, можно заметить, что иерархия классов там отличается от иерархии в Обозревателе Решений (Solution Explorer), классы организованы по функциям.
Этот пост не является рекомендацией. Это не что иное, как первоначальное исследование идеи. Несмотря на то, что это даёт две оси вариативности, вам всё равно придётся идти на компромиссы. С контроллерами всё понятно, но куда вы поместите сквозные задачи или общую логику предметной области?
Кроме того, это не уберегает от случаев, когда одна функция может зависеть от другой и импортировать её пространство имён. Вы можете возразить, что это не проблема пространств имён, а скорее запах кода, указывающий на то, что надо было организовать код по-другому.
Может быть и так, но тогда подразумевается более глубокая проблема: размещение файлов в иерархии может, в конце концов, не очень помогать. Кажется, что вещи организованы, но если распределение вещей по группам осуществляется без предсказуемой системы, то какая от этого польза? Облегчает ли это поиск вещей или ощущение порядка в основном иллюзорно?
Итого
Теоретически структура пространства имён может не следовать структуре каталогов. Вы можете реорганизовать кодовую базу так, чтобы файловая структура соответствовала деталям реализации, а иерархия пространств имен — функциям (или наоборот). Я это попробовал в своём проекте, и после нескольких часов реорганизации кода, не могу сказать, что меня пугает эта идея. Хотя, возможно, в более крупной базе кода она столкнётся с проблемами. С другой стороны, я все ещё не убежден, что навязывание иерархии сложному дизайну программного обеспечения как-то особенно выгодно.
Источник: https://blog.ploeh.dk/2023/05/15/folders-versus-namespaces/
Автор оригинала: Марк Симанн
Папки Против Пространств Имён
Что, если ваша структура папок не будет соответствовать структуре пространств имён?
Поскольку для новичков большинство вещей впервой, иногда они делают что-то не так, как мы обычно делаем. Например, они знают про пространства имён, но могут не понимать, что структура файлов и папок должна отражать структуру пространств имён. Компилятору все равно, но я всегда делал это так. Для этого даже есть правило статического анализатора. Но в самом деле, что будет, если нарушить это соглашение?
Инструменты и шаблоны часто подталкивают вас к организации кода в соответствии с техническими проблемами: контроллеры, модели, представления и т. д. Код организован в папки, такие как Controllers, Models, DataAccess и т. п. Вы кладёте все контроллеры в папку Controllers и убеждаетесь, что пространство имён совпадает иерархии папок. Распространённой критикой является то, что это неправильный способ организации кода. Но это подразумевает, что есть правильный способ. Например, файлы должны быть организованы по папкам в соответствии с функциональностью, а не с техническим предназначением.
Однако если вы решите игнорировать соглашение о том, что структура пространств имён должна отражать структуру папок, у вас появится вторая ось вариативности. Например, если оставить организацию файлов по папкам в соответствии с техническим предназначением, но организовать пространства имён в соответствии с функциями: Users, Orders, Reservations и т.д., то открыв в IDE окно Class View, можно заметить, что иерархия классов там отличается от иерархии в Обозревателе Решений (Solution Explorer), классы организованы по функциям.
Этот пост не является рекомендацией. Это не что иное, как первоначальное исследование идеи. Несмотря на то, что это даёт две оси вариативности, вам всё равно придётся идти на компромиссы. С контроллерами всё понятно, но куда вы поместите сквозные задачи или общую логику предметной области?
Кроме того, это не уберегает от случаев, когда одна функция может зависеть от другой и импортировать её пространство имён. Вы можете возразить, что это не проблема пространств имён, а скорее запах кода, указывающий на то, что надо было организовать код по-другому.
Может быть и так, но тогда подразумевается более глубокая проблема: размещение файлов в иерархии может, в конце концов, не очень помогать. Кажется, что вещи организованы, но если распределение вещей по группам осуществляется без предсказуемой системы, то какая от этого польза? Облегчает ли это поиск вещей или ощущение порядка в основном иллюзорно?
Итого
Теоретически структура пространства имён может не следовать структуре каталогов. Вы можете реорганизовать кодовую базу так, чтобы файловая структура соответствовала деталям реализации, а иерархия пространств имен — функциям (или наоборот). Я это попробовал в своём проекте, и после нескольких часов реорганизации кода, не могу сказать, что меня пугает эта идея. Хотя, возможно, в более крупной базе кода она столкнётся с проблемами. С другой стороны, я все ещё не убежден, что навязывание иерархии сложному дизайну программного обеспечения как-то особенно выгодно.
Источник: https://blog.ploeh.dk/2023/05/15/folders-versus-namespaces/
Автор оригинала: Марк Симанн
👍8
День 1585. #ЧтоНовенького
Единые Настройки в Visual Studio
Разработчики Visual Studio решили упростить настройку IDE для всех ваших рабочих сред, независимо от того, работаете ли вы на ноутбуке дома, на компьютере в офисе или используете Dev Box или виртуальную машину Azure. Единые Настройки (Unified Settings) – прототип, который ещё находится в стадии разработки, призванный переосмыслить то, как вы персонализируете свою IDE и совместно использовать настройки между различными рабочими средами и установками Visual Studio.
Единые настройки помогают настроить среду как индивидуальными параметрами, так и параметрами группы/рабочей области. Настройки синхронизируются с облаком, поэтому настройка новой среды может занять минуты, а не часы. У вас будет доступ ко всем вашим настройкам в файле JSON на случай, если вы захотите просмотреть их или поделиться ими с товарищем по команде. На форуме сообщества создана тема, посвящённая прототипу единых настроек, где разработчики утилиты собирают мнения и отзывы по мере её реализации. В этом коротком видео поясняется суть утилиты и её отличие от текущего UI настроек.
Сегодня опыт настройки IDE под свои предпочтения полон препятствий и боли. Это приводит к тому, что многие варианты кастомизации никогда не используются или даже не обнаруживаются. Единые настройки призваны решить некоторые распространённые проблемы:
1. Последовательность
Сегодня каждая страница в параметрах инструментов имеет собственный UI. Поэтому часто параметры не отражают текущую тему, непоследовательно масштабируются под разрешение монитора или используют разный UI для похожих настроек и т.п.
2. Область применения
Сейчас настройки обычно меняют поведение этой конкретной установки VS. Но иногда может потребоваться управлять настройками, которые лучше всего применять к целым репозиториям. В Единых Настройках представлены «области действия», чтобы предоставить больше гибкости и контроля над вашей IDE. Предполагаются следующие области применения:
- Пользовательская (User): применяется ко всем проектам и решениям для данной установки Visual Studio. Как правило, это личные настройки: тема, шрифты и цвета, параметры отладки.
- Рабочей области (Workspace): применяется к конкретному проекту или репозиторию. Может включать специальные настройки отладки, настраиваемый внешний вид вкладки и т.п.
3. Общий доступ и синхронизация настроек
Единые настройки синхронизируются с облаком и хранятся в удобочитаемом файле JSON, поэтому вы сможете поделиться ими с товарищем по команде или вручную изменить значения настроек. Вы также сможете выбрать синхронизацию всех или отдельных настроек.
4. Возможность обнаружения
В текущих параметрах множество вкладок настроек, поэтому часто бывает трудно найти нужный параметр. Поиск не всегда показывает полные результаты, и их трудно анализировать. В единых настройках при поиске термина все результаты поиска будут отображаться в одном представлении. Вы сможете редактировать каждый параметр непосредственно в этом представлении. Также будет добавлена возможность фильтрации, чтобы просматривать категории параметров, такие как «Производительность» и «Специальные возможности». Также изменение настройки по умолчанию будет видимо с возможностью легко откатиться назад.
Итого
Разработчики утилиты включили в обсуждение несколько открытых вопросов по утилите и ждут ваших мнений или, возможно, вопросов, которые они не рассмотрели.
Источник: https://devblogs.microsoft.com/visualstudio/unifiedsettings/
Единые Настройки в Visual Studio
Разработчики Visual Studio решили упростить настройку IDE для всех ваших рабочих сред, независимо от того, работаете ли вы на ноутбуке дома, на компьютере в офисе или используете Dev Box или виртуальную машину Azure. Единые Настройки (Unified Settings) – прототип, который ещё находится в стадии разработки, призванный переосмыслить то, как вы персонализируете свою IDE и совместно использовать настройки между различными рабочими средами и установками Visual Studio.
Единые настройки помогают настроить среду как индивидуальными параметрами, так и параметрами группы/рабочей области. Настройки синхронизируются с облаком, поэтому настройка новой среды может занять минуты, а не часы. У вас будет доступ ко всем вашим настройкам в файле JSON на случай, если вы захотите просмотреть их или поделиться ими с товарищем по команде. На форуме сообщества создана тема, посвящённая прототипу единых настроек, где разработчики утилиты собирают мнения и отзывы по мере её реализации. В этом коротком видео поясняется суть утилиты и её отличие от текущего UI настроек.
Сегодня опыт настройки IDE под свои предпочтения полон препятствий и боли. Это приводит к тому, что многие варианты кастомизации никогда не используются или даже не обнаруживаются. Единые настройки призваны решить некоторые распространённые проблемы:
1. Последовательность
Сегодня каждая страница в параметрах инструментов имеет собственный UI. Поэтому часто параметры не отражают текущую тему, непоследовательно масштабируются под разрешение монитора или используют разный UI для похожих настроек и т.п.
2. Область применения
Сейчас настройки обычно меняют поведение этой конкретной установки VS. Но иногда может потребоваться управлять настройками, которые лучше всего применять к целым репозиториям. В Единых Настройках представлены «области действия», чтобы предоставить больше гибкости и контроля над вашей IDE. Предполагаются следующие области применения:
- Пользовательская (User): применяется ко всем проектам и решениям для данной установки Visual Studio. Как правило, это личные настройки: тема, шрифты и цвета, параметры отладки.
- Рабочей области (Workspace): применяется к конкретному проекту или репозиторию. Может включать специальные настройки отладки, настраиваемый внешний вид вкладки и т.п.
3. Общий доступ и синхронизация настроек
Единые настройки синхронизируются с облаком и хранятся в удобочитаемом файле JSON, поэтому вы сможете поделиться ими с товарищем по команде или вручную изменить значения настроек. Вы также сможете выбрать синхронизацию всех или отдельных настроек.
4. Возможность обнаружения
В текущих параметрах множество вкладок настроек, поэтому часто бывает трудно найти нужный параметр. Поиск не всегда показывает полные результаты, и их трудно анализировать. В единых настройках при поиске термина все результаты поиска будут отображаться в одном представлении. Вы сможете редактировать каждый параметр непосредственно в этом представлении. Также будет добавлена возможность фильтрации, чтобы просматривать категории параметров, такие как «Производительность» и «Специальные возможности». Также изменение настройки по умолчанию будет видимо с возможностью легко откатиться назад.
Итого
Разработчики утилиты включили в обсуждение несколько открытых вопросов по утилите и ждут ваших мнений или, возможно, вопросов, которые они не рассмотрели.
Источник: https://devblogs.microsoft.com/visualstudio/unifiedsettings/
👍9
День 1586. #Карьера
Работа Требует Внимания. Постоянные Оповещения Крадут Его
Сложные проблемы требуют сосредоточенного и постоянного внимания со стороны разработчиков. Это внимание — время и свобода концентрации — самый ценный ресурс команды.
Мы часто описываем сосредоточенную работу как состояние потока. Оно позволяет человеку полностью погрузиться в работу, что приводит к лучшим результатам. Но это может произойти только тогда, когда ваше внимание полностью сосредоточено на том, что лежит перед вами.
Современное рабочее пространство требует вашего внимания. У нас есть чаты, почта и приложения для управления проектами - и все присылают уведомления. В офисах люди отвлекают вас и создают общий шум. Работая удалённо, вы перекладываете всю коммуникационную нагрузку на чаты и почту. Приложения обещают асинхронную связь, но на практике это не всегда происходит.
Мы регулярно совмещаем несколько задач. Состояние потока требует постоянного внимания в течение долгого времени. Однако переключение между задачами сопряжено с умственными затратами, и эти затраты приводят к тому, что на выполнение задач уходит до 40% больше времени. Проскальзывают мелкие ошибки, опечатки, забываются детали. Даже попытка делать только два дела одновременно может означать, что вы делаете оба плохо.
Все эти переключения могут привести к большему стрессу и беспокойству. Производительность может не страдать, но переключения могут заставлять работать быстрее, что приводит к дефициту времени, разочарованию и стрессу, а в долгосрочной перспективе - к снижению удовлетворённости работой и выгоранию.
Чтобы хорошо работать в течение дня, нужно какое-то время, когда вы не работаете. Время простоя необходимо для снижения стресса, предотвращения эмоционального выгорания и поддержания здоровья мозга. Поскольку мы всё больше работаем из дома, работа проникает в нашу домашнюю жизнь. Наши телефоны заполнены уведомлениями, как и наши рабочие компьютеры, но телефон всегда при нас. Привычка быть «всегда на связи» не позволяет игнорировать уведомления, даже в нерабочее время. Вы можете — и, вероятно, должны — отключать звук и игнорировать эти уведомления в нерабочее время. Некоторые чат-программы устанавливают рабочее время, в течение которого будут отправляться уведомления. В течение рабочего дня вы можете контролировать статусы и настройки уведомлений, указывая, когда вы доступны, а когда нет.
Но можно переосмыслить, зачем нам вообще уведомления, как и собрания. Письмо или запись в чате — это приглашение к сотрудничеству и обмену информацией. Отлично! Но уведомления синхронны; они требуют внимания прямо сейчас. Сотрудничество эффективнее, когда все заинтересованные стороны собирались и готовы, либо когда оно асинхронно, чтобы у них было время уделить внимание проблеме.
Нам нужно оставаться продуктивными, работая так, чтобы приносить пользу. Одна из причин, по которой чаты и, в меньшей степени, почта отнимают так много нашего внимания, в том, что они стали центральным приложением в нашем рабочем процессе. Они хотят вашего внимания прямо сейчас.
Менять рабочие процессы сложно. В конечном счёте проблемы утечки внимания имеют культурные решения. У вас могут быть правильные инструменты для реализации этого, но в конечном счёте есть два вопроса, на которые организация должна ответить: (а) Как вы сотрудничаете? и (б) Как вы делитесь знаниями? До тех пор, пока ответы на них включают аналоговую или цифровую версию «похлопывания коллеги по плечу», чтобы привлечь его внимание, мы будем отвлекаться и постоянно пытаться вернуться в контекст, который у нас был до того, как нас отвлекли.
Источник: https://stackoverflow.blog/2023/05/22/modern-work-requires-attention-constant-alerts-steal-it/
Работа Требует Внимания. Постоянные Оповещения Крадут Его
Сложные проблемы требуют сосредоточенного и постоянного внимания со стороны разработчиков. Это внимание — время и свобода концентрации — самый ценный ресурс команды.
Мы часто описываем сосредоточенную работу как состояние потока. Оно позволяет человеку полностью погрузиться в работу, что приводит к лучшим результатам. Но это может произойти только тогда, когда ваше внимание полностью сосредоточено на том, что лежит перед вами.
Современное рабочее пространство требует вашего внимания. У нас есть чаты, почта и приложения для управления проектами - и все присылают уведомления. В офисах люди отвлекают вас и создают общий шум. Работая удалённо, вы перекладываете всю коммуникационную нагрузку на чаты и почту. Приложения обещают асинхронную связь, но на практике это не всегда происходит.
Мы регулярно совмещаем несколько задач. Состояние потока требует постоянного внимания в течение долгого времени. Однако переключение между задачами сопряжено с умственными затратами, и эти затраты приводят к тому, что на выполнение задач уходит до 40% больше времени. Проскальзывают мелкие ошибки, опечатки, забываются детали. Даже попытка делать только два дела одновременно может означать, что вы делаете оба плохо.
Все эти переключения могут привести к большему стрессу и беспокойству. Производительность может не страдать, но переключения могут заставлять работать быстрее, что приводит к дефициту времени, разочарованию и стрессу, а в долгосрочной перспективе - к снижению удовлетворённости работой и выгоранию.
Чтобы хорошо работать в течение дня, нужно какое-то время, когда вы не работаете. Время простоя необходимо для снижения стресса, предотвращения эмоционального выгорания и поддержания здоровья мозга. Поскольку мы всё больше работаем из дома, работа проникает в нашу домашнюю жизнь. Наши телефоны заполнены уведомлениями, как и наши рабочие компьютеры, но телефон всегда при нас. Привычка быть «всегда на связи» не позволяет игнорировать уведомления, даже в нерабочее время. Вы можете — и, вероятно, должны — отключать звук и игнорировать эти уведомления в нерабочее время. Некоторые чат-программы устанавливают рабочее время, в течение которого будут отправляться уведомления. В течение рабочего дня вы можете контролировать статусы и настройки уведомлений, указывая, когда вы доступны, а когда нет.
Но можно переосмыслить, зачем нам вообще уведомления, как и собрания. Письмо или запись в чате — это приглашение к сотрудничеству и обмену информацией. Отлично! Но уведомления синхронны; они требуют внимания прямо сейчас. Сотрудничество эффективнее, когда все заинтересованные стороны собирались и готовы, либо когда оно асинхронно, чтобы у них было время уделить внимание проблеме.
Нам нужно оставаться продуктивными, работая так, чтобы приносить пользу. Одна из причин, по которой чаты и, в меньшей степени, почта отнимают так много нашего внимания, в том, что они стали центральным приложением в нашем рабочем процессе. Они хотят вашего внимания прямо сейчас.
Менять рабочие процессы сложно. В конечном счёте проблемы утечки внимания имеют культурные решения. У вас могут быть правильные инструменты для реализации этого, но в конечном счёте есть два вопроса, на которые организация должна ответить: (а) Как вы сотрудничаете? и (б) Как вы делитесь знаниями? До тех пор, пока ответы на них включают аналоговую или цифровую версию «похлопывания коллеги по плечу», чтобы привлечь его внимание, мы будем отвлекаться и постоянно пытаться вернуться в контекст, который у нас был до того, как нас отвлекли.
Источник: https://stackoverflow.blog/2023/05/22/modern-work-requires-attention-constant-alerts-steal-it/
👍6
День 1587. #ЗаметкиНаПолях #DevOps
Создаём Конвейер CI/CD в GitHub Actions
Благодаря CI/CD вы можете значительно сократить объем ручных операций и больше сосредоточиться на создании ПО, обеспечивая более быстрые и надёжные развёртывания.
CI/CD — это метод автоматизации рабочего процесса разработки и развёртывания ПО. Непрерывная интеграция (CI) - это процесс автоматизации синхронизации нового кода с репозиторием. Любые изменения в коде приложения немедленно собираются, тестируются и объединяются. Непрерывная доставка или развёртывание (CD) обеспечивает развёртывание изменений в производственную (или другую) среду.
Если вы используете GitHub, вы можете использовать GitHub Actions, чтобы создавать рабочие процессы сборки и тестирования каждого коммита в вашем репозитории или развёртывания в рабочую среду при создании нового тега.
Нужно создать рабочий процесс, который будет запускаться, когда в вашем репозитории происходит какое-либо событие. Примеры событий: коммит в основной ветке, создание тега или запуск рабочего процесса вручную. Например, для сборки и тестирования:
- Определяем событие для запуска рабочего процесса (при коммите в ветку main)
- Настраиваем.NET SDK с версией из
Добавив это действие в свой репозиторий GitHub, вы начнёте получать мгновенную обратную связь после каждого коммита. При сбое выполнения рабочего процесса из-за ошибки сборки или неудачного теста вы получите уведомление на email.
Непрерывная доставка - реальная ценность процесса CI/CD. Вы делаете изменение, и уже через несколько минут ваш код собран, протестирован и выложен в рабочую среду. Вот пример сценария развёртывания:
- Добавление шага публикации и настройка выходного пути
- Использование действия azure/webapps-deploy@v2 для развёртывания в Azure.
Если вам нужно безопасно и надёжно использовать секретные данные в рабочих процессах, вы можете определить секреты GitHub и использовать их в действиях, не добавляя их в систему управления версиями. В примере выше использован
Источник: https://www.milanjovanovic.tech/blog/build-ci-cd-pipeline-with-github-actions-and-dotnet
Создаём Конвейер CI/CD в GitHub Actions
Благодаря CI/CD вы можете значительно сократить объем ручных операций и больше сосредоточиться на создании ПО, обеспечивая более быстрые и надёжные развёртывания.
CI/CD — это метод автоматизации рабочего процесса разработки и развёртывания ПО. Непрерывная интеграция (CI) - это процесс автоматизации синхронизации нового кода с репозиторием. Любые изменения в коде приложения немедленно собираются, тестируются и объединяются. Непрерывная доставка или развёртывание (CD) обеспечивает развёртывание изменений в производственную (или другую) среду.
Если вы используете GitHub, вы можете использовать GitHub Actions, чтобы создавать рабочие процессы сборки и тестирования каждого коммита в вашем репозитории или развёртывания в рабочую среду при создании нового тега.
Нужно создать рабочий процесс, который будет запускаться, когда в вашем репозитории происходит какое-либо событие. Примеры событий: коммит в основной ветке, создание тега или запуск рабочего процесса вручную. Например, для сборки и тестирования:
name: Build & TestЗдесь мы:
on:
push:
branches:
- main
env:
DOTNET_VERSION: "7.0.x"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Install dependencies
run: dotnet restore WebApi
- name: Build
run: dotnet build WebApi --configuration Release --no-restore
- name: Test
run: dotnet test WebApi --configuration Release --no-build
- Определяем событие для запуска рабочего процесса (при коммите в ветку main)
- Настраиваем.NET SDK с версией из
env.DOTNET_VERSION
- Восстанавливаем зависимости, затем собираем и тестируем проект с помощью команд dotnet CLIДобавив это действие в свой репозиторий GitHub, вы начнёте получать мгновенную обратную связь после каждого коммита. При сбое выполнения рабочего процесса из-за ошибки сборки или неудачного теста вы получите уведомление на email.
Непрерывная доставка - реальная ценность процесса CI/CD. Вы делаете изменение, и уже через несколько минут ваш код собран, протестирован и выложен в рабочую среду. Вот пример сценария развёртывания:
name: PublishОн очень похож на предыдущий, со следующими отличиями:
on:
push:
branches:
- main
env:
AZURE_WEBAPP_NAME: web-api
AZURE_WEBAPP_PACKAGE_PATH: "./publish"
DOTNET_VERSION: "7.0.x"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Build and Publish
run: |
dotnet restore WebApi
dotnet build WebApi -c Release --no-restore
dotnet publish WebApi -c Release --no-build
--output '${{ env.AZURE_WEBAPP_PACKAGE_PATH }}'
- name: Deploy to Azure
uses: azure/webapps-deploy@v2
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
package: '${{ env.AZURE_WEBAPP_PACKAGE_PATH }}'
- Добавление шага публикации и настройка выходного пути
- Использование действия azure/webapps-deploy@v2 для развёртывания в Azure.
Если вам нужно безопасно и надёжно использовать секретные данные в рабочих процессах, вы можете определить секреты GitHub и использовать их в действиях, не добавляя их в систему управления версиями. В примере выше использован
secrets.AZURE_PUBLISH_PROFILE
для доступа к профилю публикации в экземпляре App Service.Источник: https://www.milanjovanovic.tech/blog/build-ci-cd-pipeline-with-github-actions-and-dotnet
👍14
День 1588. #ЗаметкиНаПолях
Полезные Расширения для Task<T>
Сегодня рассмотрим 5 полезных методов расширения для Task.
1. Запустил и забыл
Иногда нужно начать задачу и не ждать её завершения. Например, для некритических задач, когда не важен результат. Создадим метод расширения FireAndForget. При желании можно передать методу обработчик ошибок, который будет вызываться, когда задача выдаёт исключение:
Чтобы повторять задачу определённое количество раз, создадим метод расширения Retry. Он будет повторять задачу до тех пор, пока она не завершится успешно или не будет достигнуто максимальное количество попыток. Можно передать задержку между попытками:
Выполняется при возникновении исключения в задаче:
Установка тайм-аута для задачи полезна, когда вы хотите, чтобы задача не выполнялась слишком долго (подойдёт, если задача не принимает токена отмены):
5. Результат по умолчанию
Иногда нужно вернуть результат по умолчанию при сбое задачи:
Полезные Расширения для Task<T>
Сегодня рассмотрим 5 полезных методов расширения для Task.
1. Запустил и забыл
Иногда нужно начать задачу и не ждать её завершения. Например, для некритических задач, когда не важен результат. Создадим метод расширения FireAndForget. При желании можно передать методу обработчик ошибок, который будет вызываться, когда задача выдаёт исключение:
public static void FireAndForget(Использование:
this Task task,
Action<Exception> errorHandler = null)
{
task.ContinueWith(t =>
{
if (t.IsFaulted && errorHandler != null)
errorHandler(t.Exception);
},
TaskContinuationOptions.OnlyOnFaulted);
}
SendEmailAsync().FireAndForget(2. Повтор
e => Console.WriteLine(e.Message));
Чтобы повторять задачу определённое количество раз, создадим метод расширения Retry. Он будет повторять задачу до тех пор, пока она не завершится успешно или не будет достигнуто максимальное количество попыток. Можно передать задержку между попытками:
public static async Task<TResult>Использование:
Retry<TResult>(
this Func<Task<TResult>> taskFactory,
int maxRetries,
TimeSpan delay)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
return await taskFactory()
.ConfigureAwait(false);
}
catch
{
if (i == maxRetries - 1)
throw;
await Task.Delay(delay)
.ConfigureAwait(false);
}
}
// не должно достигать этого места
return default(TResult);
}
var result = await (3. Действие при сбое
() => GetResultAsync())
.Retry(3, TimeSpan.FromSeconds(1));
Выполняется при возникновении исключения в задаче:
public static async TaskИспользование:
OnFailure(this Task task,
Action<Exception> onFailure)
{
try
{
await task.ConfigureAwait(false);
}
catch (Exception ex)
{
onFailure(ex);
}
}
await GetResultAsync()4. Тайм-аут
.OnFailure(ex => Console.WriteLine(ex.Message));
Установка тайм-аута для задачи полезна, когда вы хотите, чтобы задача не выполнялась слишком долго (подойдёт, если задача не принимает токена отмены):
public static async TaskИспользование:
WithTimeout(this Task task,
TimeSpan timeout)
{
var delayTask = Task.Delay(timeout);
var completedTask = await
Task.WhenAny(task, delayTask)
.ConfigureAwait(false);
if (completedTask == delayTask)
throw new TimeoutException();
await task;
}
await GetResultAsync()Замечание: Начиная с .NET 6 для этой цели можно использовать WaitAsync.
.WithTimeout(TimeSpan.FromSeconds(1));
5. Результат по умолчанию
Иногда нужно вернуть результат по умолчанию при сбое задачи:
public static async Task<TResult>Использование:
Fallback<TResult>(
this Task<TResult> task,
TResult fallbackValue)
{
try
{
return await task.ConfigureAwait(false);
}
catch
{
return fallbackValue;
}
}
var result = await GetResultAsync()Источник: https://steven-giesel.com/blogPost/d38e70b4-6f36-41ff-8011-b0b0d1f54f6e
.Fallback("fallback");
👍26