12
Karma
0
Rating
Александр Гилевич @Dobby007

Разработчик .NET

Самая дорогая ошибка в моей жизни: подробно об атаке на порт SIM-карты

0

Входящие СМС от банков, как мне говорили. Не от всех. Гугл под вопросом.

Улучшения диагностики в .NET Core 3.0

Как глубока кроличья нора? CLRium #5: Garbage Collector

Graceful degradation. Доклад Яндекс.Такси

0

А на каком этапе происходит откат до фолбэка в случае ошибочного запроса? Эта логика зашита в клиентское приложение или каждый запрос клиента сначала идет в определенный прокси с конкретным внешним урлом, а прокси, глядя на статистику, выбирает к кому перенаправить запрос для данного конкретного клиента (причем во время наличия тыквы он отправляет запрос сразу в два места и нагрузка на него возрастает в два раза)? Если у вас второй вариант (что мне кажется более простым в реализации), то еще один вопрос в догонку: у вас есть отдельный прокси для каждого вашего микросервиса с фолбэком со своей логикой включения/выключения фолбэка? Или это какое-то более универсальное решение за которым прячутся все микросервисы и их фолбэки?

Оператор робомобиля Uber, сбившего велосипедистку, в момент столкновения смотрела шоу «Голос»

+1

Имхо, это обычная дорога с двумя полосами. Я сейчас на секунду оставлю в стороне способность предсказывать развитие событий. Соблюдал пешеход правила дорожного движения или нет, здесь не имеет значения. В наших реалиях тем более. Я это к тому, что машина сбила "неопределенное препятствие", когда велосипедистка находилась прямо перед ней, даже не замедляя скорости. Т.е. будь это кусок арматуры, мирно катившееся колесо или танк она бы повела себя точно также? Ну как ни крути, даже восприняв объект как неподвижный шесть секунд назад, этот самый объект через какое-то время оказался около бортика авто, а потом и вовсе прямо перед ним. Ну замедлить скорость машина же должна была, видя перед собой препятствие вовсе немаленького размера.

Оператор робомобиля Uber, сбившего велосипедистку, в момент столкновения смотрела шоу «Голос»

0

Ну она же двигалась по направлению к полосе движения автомобиля. При этом относительно траектории движения авто оставалась неподвижной. Насколько я понял, было целых 6 секунд, чтобы понять, что то самое "неопределенное препятствие" движется и что столкновение с ним неизбежно, если сохранять текущие параметры. Даже за секунду она проделывала какую то пути. И вовсе она не кидалась, судя по видео. Так что алгоритм — кривой.

GitHub теперь официально принадлежит Microsoft

0

Одно дело — интегрироваться, а совсем другое — рекламировать и продвигать свой продукт

GitHub теперь официально принадлежит Microsoft

Как мы в Тинькофф использовали Windows Hello для аутентификации пользователя

0

Получается, у microsoft в очередной раз неудачное решение с windows hello получилось. По идее надо какой то хэш вычислять по биоданным пользователя и класть в passwordvault пин код, уже зашифрованный с помощью этого хэша. Тогда по идее даже при сливе приватной области пин узнать не получится.

Самая сложная программа

Самая сложная программа

0

Ну я спорить с вами не буду. Может быть дешевле (читайте надежнее), может быть не дешевле. Я лишь предположил возможный вариант.


По поводу уязвимостей. Были и будут. Вопрос в качестве кода и его тестировании. А что касается вашего нинтендо… Кто его знает? Может и аудировали вовсе?..

Самая сложная программа

0
Если вы верите, что ядро Windows в сотни раз надёжнее и безопаснее… ну верьте…

А вы точно на мой комментарий ответили?) Я вроде не сравнивал ядра различных ОС. Глядя на то, какие баги фиксятся в очередном обновлении, я с уверенностью могу сказать, что не считаю Windows безопасной системой (как впрочем и любую систему, так как уязвимости есть везде).


Невозможно протестировать код на уязвимости

Есть достаточно много фирм, которые делают аудит кода за деньги. Вы это к чему?

Самая сложная программа

0

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


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


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


А может то и другое одновременно?.. Но это так просто мысли вслух :)


P.S. Кстати, все мы знаем, что в Microsoft QA-отдел не пользуется особым уважением. Так что я не думаю, что у них там в принципе весь код всегда тестируется на все уязвимости. Ну может есть там в процессе у них что-то такое, но точно там люди сидят не с уровнем знаний, описанном в статье.

Самая сложная программа

+1

Отбрасывая теорию заговора, можно предположить, что где-то с начала 2000-х в Microsoft сидел рецидивист под видом junior'а и время от времени делал баги в ядре. А потом тот же самый рецидивист перешел работать в реалтек. После опыта то работы над ядром операционки они его охотно взяли к себе. После этого ему оставалось лишь вставить флэшку в чужой комп, чтобы найти нужный файл приватного ключа на какой-нибудь билд-машине, используя свои же собственные баги.

Как мы игру «Камень – ножницы – бумага» на блокчейне Ethereum делали. Ч.2 Техническая

0

Интерес игроков в чем тут? Заплатить комиссию, чтобы потом сказать себе, мол, да, эту игру можно сделать с помощью эфириума?

Как мы игру «Камень – ножницы – бумага» на блокчейне Ethereum делали. Ч.2 Техническая

0

Прочитал обе части статьи и так и не понял, какой стимул в нее играть? Что получит победитель в итоге? И кто платит за газ? Вы написали в первой части, что комиссия может меняться и от нее зависит длительность хода (чем выше, тем быстрее), но кто и как ее в итоге устанавливает? По мне так как раз такие моменты прежде всего и надо было осветить, а не заполнять статью интерфейсами контракта, которые ни о чем сами по себе не говорят, и инфой о том, как же плохо, что нельзя использовать числа вместо строк при хэшировании.

Как именно работает Meltdown

0

А мне может кажется или ваш цикл на шаге 2 нужно поставить после 4-го пункта? Ведь смысл от цикла — измерить время доступа к данным массива, чтобы получить значение байта по "невалидному адресу", а измеряем время доступа мы только после того, как поймаем исключение. На шаге 2 нужен другой цикл, ИМХО. Цикл, который будет читать последовательно байты из памяти ядра, чтобы, собственно, и получить интересующий нас пароль к почте Клинтон.
P.S. А так за объяснение плюс. Стало намного понятнее все.

Простая реализация Token для взаимодействия мобильного приложения с WebAPI

+1
Оказывается пока приложение активно в App.Current.Properties могут хранится любые объекты, в том числе и объекты с данными собственных классов, но при «убиении» процесса если там было что-то отличное от «простых» объектов — содержимое App.Current.Properties отчищается, но если там хранить только простые объекты — string, bool, int и т.п. то всё останется сохраненным!

Я не работал с Xamarin, но мне кажется, что тут дело в возможности сериализации объектов. Вы не пробовали пометить свои кастомные классы атрибутом Serializable?

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Даже в начале главы книги, которую вы привели в качестве примера, говорится, что correlation token используется в асинхронных методах общения клиента и сервера (в очередях). Протокол HTTP — синхронный. Здесь не нужно сопоставлять запрос и ответ между браузером и сервером. Собственно, там так и написано прямым текстом только про старый RPI:


image

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

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

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0
В вашей архитектуре такого нет и легко реализовать не получится (гибкость?). Моя оценка: не только архитектурное решение несовершенно

Не делайте поспешных выводов. Можно просто поместить этот ваш correlation token в HttpContext.Items и логировать его вместе с url с помощью специального layout renderer'а. Или можно логин пользователя туда добавлять. Собственно говоря, можно сделать, что угодно, было бы желание делать и понять.


DI контейнер не обязан быть глобальным и а может быть per session

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


Кроме того, вам придется изобрести велосипед механизм для добавления ваших сервисов в режиме "per session", поскольку ASP.NET Core такого режима не поддерживает.

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Роман, это и есть сообщение из провайдера: DoJob method is ending


Посмотрите уже, наконец, код на гитхабе: https://github.com/Dobby007/aspnetcore-longtask/blob/master/AspNetCoreApp/Services/LongRespondingService.cs


Да и в сообщении же явно видно откуда оно логируется: AspNetCoreApp.Services.LongRespondingService+d__3.MoveNext


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


Прокидывать не через interface кончено (т.е. уродовать API не будет) а через реализации.

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


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

Откровенно говоря, я даже и не понял, про какой контейнер вы говорите

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Решение есть. Я вам его рассказал.


У вас ошибка в вашем коде. Код будет работать пока к серверу обращается всего один клиент (и то не всегда). Никто не гарантирует, что таска будет выполняться в экслюзивном режиме. Если начнут выполняться одновременно две таски, то неизвестно какой делегат в вашем свойстве AuditOnResult останется жить, а какой затрется другим. Я даже знаю, какое будет ваше следующее решение — создавать dataProvider создается каждый раз новый при очередном запросе. Я не буду даже упомянать про GC и производительность (хотя вы кстати говорили об этом в вашем комментарии выше). Подумайте хотя бы, что будет, если вам нужно будет сделать некоторое преобразование данных в слое бизнес-логики. dataProvider будет вызываться из другого сервиса, а не из контроллера, как сейчас. Вам придется прокидывать ваш AuditOnResult глубже и глубже и делать это для каждого сервиса.

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

У меня запрос-ответ логируется через основное сообщение (в конфигурации за это отвечает ${message}), которое я отправляю в логгер. Запрос-ответ я с легкостью могу получить в самом методе провайдера данных, так как именно из него я отправляю запрос к АПИ. Именно оттуда я их и логирую вместе с данными из HttpContext'а. А вот как вы планируете получать данную информацию вне провайдера данных в "колбэке" можно только догадываться. Должно быть, в момент исполнения делегата в ContinueWith вы должны получить недавно исполненный запрос (а может и несколько запросов) и всю сопутствующую ему информацию из какого-то хранилища...

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Подождите, вы меня не понимаете почему-то. Где у вас логируется запрос/ответ от АПИ. Т.е. сейчас вы логируете только query string, controller и action. А где полный текст HTTP запроса и ответа (или хотя бы его тело)? Мне не нужен код, расскажите просто принцип, как и где вы будете отлавливать эту информацию и куда сохранять для будущего логирования. Т.е. задача — сопоставить данные, которые вы сейчас залогировали, с запросом к АПИ (пусть для простоты это будет REST интерфейс)

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0
Давайте не сводить меня с ума

Вы предлагаете вам не отвечать?)


Во-вторых колбек почему-то в «провайдер данных» уложили…

Это не я, а компилятор так разбивает метод, помеченный как async. Давайте все-таки уйдем с абстрактного понятия колбэк и перейдем на общепринятые async-await. Так мне будет легче вас понять.


поле «место вызова»… Туда и положите контроллер с акшином. А не при МВЦ другой идентификатор места вызова

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


ContinueWith(()=>{ logger.Log(«bla,bla» + controllerText )});

Я еще раз хочу заметить, что основной моей целью было залогировать запрос-ответ от АПИ. Если вы вместо "bla,bla" как раз и имеете в виду запрос-ответ, то было бы здорово услышать от вас подробное объяснение, как именно вы хотите их вытаскивать вне провайдера, т.е. внутри frontend-приложения (с учетом моей просьбы про async выше).

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0
Под «собрать строчки»я имел ввиду просто передать колбеку параметры со значениями нужными вам в логе ${aspnet-mvc-controller}/${aspnet-mvc-action}

А вот теперь мой любимый вопрос… А что если вы должны будете переиспользовать этот же самый сервис или провайдер данных (с колбеком) в приложении совсем никак не связанном с MVC архитектурой? Не будет там action'ов, контроллеров и т.п. Насколько теперь кажется хорошей идея вынести параметры action-controller в метод интерфейса данного сервиса?


NLog уже умеет через appsettigns.json конфигурироваться?

Пока еще нет: https://github.com/NLog/NLog/issues/1588. Ребята очень заняты и трудятся над новым релизом :)

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0
вы восстанавливаете контекст, чтобы LoggerProvider имел что залогить.

Контекст не восстанавливается при вызове колбека (я говорю только про свой код сейчас). Контекст сохраняется до вызова метода АПИ. Дальше за меня всю работу делает AsyncLocal (т.е. .NET).


Надежность, утечки, скорость, GC?

Надежность я проверил на "функционально-нагрузочном" тесте. Все отработало как часы. Исходники теста на гитхабе. Утечек памяти не будет так как это управляемый код (я понимаю, что можно назвать утечкой, когда создаются очень много объектов, с которыми потом мучается GC, но это не мой кейс). Та дельта скорости, которой я жертвую, "бесконечно" мала по сравнению со временем выполнения запроса. GC тоже много лишней работы не проделает, так как те новые пять-десять объектов создаются только при вызове АПИ, а с учетом .NET графа в GC объектов для обработки становится еще меньше.


Вы бы в колбек передали нужные строчки и оттуда их и залоггили бы

Не понимаю вас. Про какие строчки идет речь? Можете пояснить на более живом примере, используя async-await?

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0
Если это о клиентской части то разве в вашем решении клиент не просто держит соединение

Нет, конечно. В статье я как раз описываю, что так делать не получается в нашей инфраструктуре. Ограничение на запрос — 5 секунд.


В моем решении — крутит запросы циклом, пока получает «ответ ждите» (возможно с подсказкой сколько секунд).

У меня также и зацикливается запрос. И в качестве ответа "ждите" сначала приходит id, а потом код 204. Я совсем не эту задачу решаю в моей статье. Перечитайте еще раз. Решается задача логирования детальной информации о запросе пользователя, а не задача обработки запроса.

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Извиняюсь за поздний ответ. Увидел ваш комментарий только сейчас. Генерирование ID на клиенте в JS — дело не очень благодарное, ведь нужно гарантировать его уникальность — клиентов то у нас много. Во-вторых, клиентский JavaScript (я сейчас не про node.js) не предназначен для такого. Возможно, есть какие-то библиотечки для специфических задач, которые могут составлять GUID-подобные ID'шники, но я никогда не встречал такого (и не встречал тех, кто бы мог их использовать). В-третьих, разница между тем, что описываю я в статье, и тем, что описываете вы, всего лишь в том, что вы предлагаете генерировать ID на клиенте. Все остальное — ajax обертки и код "ждите" — остается ровным счетом таким же. Сервер также должен понимать эти ID и искать их в своем хранилище ответов, и логика их обработки никуда не исчезнет. А в таком случае стоит ли игра свеч?

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Значит, вы считаете, что лучше логировать информацию о запросе отдельно, логировать запрос/ответ от АПИ, а потом это всё сопоставлять вручную по идентификатору при инцидентах. Понятно :)

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Нет-нет, конечно. Это я показал как это внутри .NET реализовано. Т.е. это то, чем там оборачиваются наши вызовы Task.Run и т.п.

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

-1

Немного вас не понял. ExecutionContext двигается с нами, да. Но чтобы какую-то инфу двигать, нужно же вызывать как раз методы LogicalSetData/LogicalGetData.

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

0

Quartz.NET — это планировщик задач, так? Тогда у меня получится то же самое, что и способ с сохранением ID из статьи, только здесь еще и добавляется внешний инструмент. Планировщики задач это нужная штука при больших задачах, требующих последовательности/консистентности. А при таких маленьких задачах, как получение данных о пользователе, я считаю, это лишнее. Насчет нелогичности — спорный момент. Запрос к АПИ начинается во время запроса пользователя к сайту. Здесь же выигрыш в том, что в логе мы видим сразу всю инфу, а не ковыряем разные источники в ее поисках.

Работаем с долгими API в ASP.NET Core правильно или тонкости переезда на новую платформу

-1
System.Threading.SynchronizationContext в .NET Core никуда не делся и нормально поддерживается всей инфраструктурой TPL, включая async/await.

Хорошее замечание.


Но он этого и на полном фреймворке не делает.

Не делает. Сайт из примера крутится на полном фреймворке (Target Framework у него — .NET Framework 4.6.2).

Создаем микросервисную архитектуру вместе с Apache Kafka и .NET Core 2.0

0

Да, Вы меня не поняли немного. Переформулирую: как вы отдадите случайное имя JS-скрипту, который обратился к вашему бэкенду? Вы либо будете писать в тело каждого сообщения для Kafka какой-то идентификатор, а потом этот идентификатор отдавать клиенту (то что я описал выше). Вариант второй: Вы поставите в паузу текущий поток общения клиента с сервером и будете ждать, пока другой поток не запишет результат в Ваше хранилище (при этом потребность в идентификаторах никуда не уходит, потому что вам нужно как-то различать одинаковые топики). В первом варианте клиент может оставить в покое сокет и сделать еще несколько запросов, дожидаясь результата на своей стороне. Во втором варианте сокет между браузером и приложением же будет висеть, поток для обработки тоже будет в повисшем состоянии, и вскоре сервер поднимет лапки (если мы говорим о более менее нагруженном сайте). Прибавьте к этому горизонтальное расширение бэкенд-серверов и распределение нагрузки между ними, и вы получите какую-то кашу.

Создаем микросервисную архитектуру вместе с Apache Kafka и .NET Core 2.0

+2
Одно но: cейчас если мы, например, запустим 5 штук NameService, то в MainApp придет 5 имен, а не одно. Это из-за настроек Apache Kafka, прописанных в файле server.properties. В рамках туториала я этого намеренно не касаюсь, чтобы не усложнять материал.

У вас получается по коду, что делая запрос из клиента MainApp, мы сразу выходим из цикла и пишем ответ уже в другом потоке. При этом получается, что будь это веб-приложение, нам бы пришлось поддерживать на стороне бэкенда свою очередь тоже (т.е. пользователь нажимает на кнопку "Сгенерировать имя", мы сопоставляем этому запросу некий идентификатор, сохраняем его, а потом клиент через какое-то время достает ответ отдельным запросом к бэкенду, имея на руках этот идентификатор). Это, как известно, имеет свои последствия (в частности, возникает вопрос о масштабируемости такого решения). Но я всегда считал, что Message Broker должен позволять это сделать без всяких самописных очередей. Разве протокол Kafka не позволяет сделать нечто подобное?


var response = await msgBus.SendMessage(topic: gTopicNameCmd, message: gMessage);
Console.WriteLine(response);

Здесь подразумевается, что запрос и ответ имеют одинаковый topic gTopicNameCmd. Следовательно, Kafka сама разруливает кому какой ответ отдать, а мы ждем от нее ответ и никуда не уходим, пока он не прилетит.

История о том, как мы перевели проект в почти четверть миллиона строк на TypeScript и остались в живых

История о том, как мы перевели проект в почти четверть миллиона строк на TypeScript и остались в живых

1 There