Pull to refresh

Comments 51

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

Хороший вопрос. Касаемо деплоя - как мне кажется опыт будет напоминать деплой через Vercel - да, вроде как есть другие облака, можно настроить по-своему CI-CD, но при этом тебе вообще ничего настраивать не нужно, не нужно шарить в инфре. Как минимум для раскатки и тестирования MVP звучит как очень удобная штука

По поводу телеметрии - в целом мне кажется дашборд как раз и предназначен для локальной разработки, и преследует 3 цели:

1. Не надо настраивать докер-копоузы
2. Не надо поднимать достаточно жирные коллекторы и вьюверы телеметрии, Aspire делает все в хост процессе без поднятия считай 3-4 контейнеров
3. Автоматически настроенные, базовые, но +- полезные дашборды.

Вроде уже релиз был? А то в статье написано , что ток ревью.

aggregation join например от 2x api за 1 запрос из коробки завезли?

никто так и не ответил, походу не завезли )

Кажется никто не понял о чём речь, 2 разных запроса от разных сервисов, пишешь ручку, она дёргает запросы, аггрегирует и возвращает результат

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

Оркестрация на уровне - запустить всё. А если мне надо например 3 проекта из 10?

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

Отдельно сервис не перезапустишь.

Тут согласен. Но разработка ведется прям оч активно

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

Оркестрация на уровне - запустить всё. А если мне надо например 3 проекта из 10?

Касаемо оркестрации, самое простое что можно сделать - это например комментить все проекты кроме трех нужных. А еще, если у тебя например есть 2 разных частых конфигурации запуска (конкретных 3 проекта и конкретных 5 проектов) - то можно сделать два разных AppHost проекта под разные конфигурации

Или через args получать нужные проекты и настроить конфигурацию запуска с нужными args

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

таки вкорячили, но в студию v17.10. или вы о чём-то другом? 🤔

классная конечно штука ,но я не понимаю как мне обращаться извне к своему api которое запустил через Aspire,он чисто на localhost запускает и что бы я не писал в конфиге он не переключается на локальное ip компа,или так и задумано?

Да, так и задумано. Это набор хаков для разработки с опциональной возможностью деплоиться в Azure и генерировать манифесты для k8s

На этот случай у Майкрософта тоже ответ имеется в лице Dev Tunnels. Если в двух словах, утилита для создания тунеля между компьютером разработчика и условным заказчиком, чтобы показать проект прям на машинке разраба.

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

Каждый раз убеждаюсь, что у них там ядрёная дурь. Ядрёная, но хорошая. Иначе я не могу объяснить их проекты от сокращателя ссылок до взаимного интеропа NodeJS с .NET или TypeScript и .NET с полным циклом преобразования в машинные коды прошивки микроконтроллеров типа Ардуионо. Или eBPF для винды.

Определённо они там что-то употребляют.

Подними реверс прокси, через него принимай внешние запросы. Тот же YARP можно прикрутить. По идее должно сработать, но я еще не пробовал)

Трепещите, жависты!!

Не понял, с чего бы это?
Ну появилась у вас какая-то полезная Ынтырпрайз дот шляпа, рады за вас. Но «трепетать»???
У вас имена методов с прописной буквы начинаются, а имя типа string со строчной.

Если это всего лишь превью, то мне даже страшно представить чего ждать от релиза.

Однажды я уже встречал очень восторженного человека. Потом оказалось, что он на антидепрессантах.

потому что имя функции и тип объекта это разные все же вещи, и string это алиас от String

Я до сих пор не могу понять , кто придумал кейс , где самое важное слово в методе - ГЛАГОЛ , пишется с маленькой буквы. Из-за такой и подобных мелочей и выбрал дотнет, а не Джаву.

Трепещите, жависты!!
Не понял, с чего бы это?

Да ладно вам, это всего лишь шутка была, не воспринимайте это всерьёз :)

У вас имена методов с прописной буквы начинаются, а имя типа string со строчной.


Очень странная претензия - если писал код на 3-4 языках, то на синтаксис не обращаешь внимания, а просто к нему привыкаешь и пишешь по конвенции. У разных языков разные конвенции, в этом ничего плохого нет

кроме блоков которые обозначаются отступами.

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

@MagMagals

потому что имя функции и тип объекта это разные все же вещи, и string это алиас от String

Тут было противопоставление с Жабой, т.к. автор зачем-то предложил «трепетать», а не между любовью к Pascal Case и абсолютно нелогичным решением назвать один из непримитивных типов не по конвенции.

@Hovanella

Я до сих пор не могу понять , кто придумал кейс , где самое важное слово в методе - ГЛАГОЛ , пишется с маленькой буквы.

Знаем-знаем, известные глаголы «is» и «when» как, например, в String.IsNullOrEmpty() или Task.WhenAny() ;)

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

Так что ваше замечание по поводу глаголов совершенно не понятно.

А ответ на вопрос "кто?" можно найти в Википедии.

Из-за такой и подобных мелочей и выбрал дотнет, а не Джаву.

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

@default_g00se

Да ладно вам, это всего лишь шутка была, не воспринимайте это всерьёз :)

Скажите это отважным защитникам Империи, развившим успешное контрнаступление на мой комментарий ;)

У разных языков разные конвенции, в этом ничего плохого нет

Но межгалактический холивар, как показывает практика, это развивает на ура.

@posledam

А когда в Java завезут async/await на уровне языка?

Надею, что никогда.
Я бы предпочёл, чтобы напротив, вывезли весь тот синтаксический мусор, что уже наввозили (var, static import или там безымянные классы) и отказались от идей наввозить ещё (строковая интерполяция та же).

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

О, когда работал с SOAP в Java 8, так не хватало 'var'. Прям выворачивало писать всякие ArrayOfElementsTypeFoo и т.п.

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

Сразу после ваших "свистоперделок" можно не продолжать какую-либо дискуссию, ибо осмысленного тут мало. Вообще человечеству на изобретении огня стоило бы остановиться и не изобретать какие-то "перделки". Понятно, что сила привычки у вас сильнее разума. Это конечно ваше личное дело, но не пытайтесь говорить за всех, язык c# прекрасен, лаконичен, удобен и отлично читается. В нем, как и в любых других языках есть свои недостатки и свои приколы. Но работать на нем комфортно. Асинхронный код писать удовольствие.

Я до сих пор не пониимаю, почему в джаве сохраняется вот эта разница между Integer и int. По-моему решение на уровне компилятора. Но тогда, о чём будут спрашивать джуна на собесе?

Хотя, они и перегрузку операторов ==, +, - никогда не введут. Так и будут формулы в джаве писаться через методы, превращая их в нечто от лиспа.

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

Про клоунаду с типом для даты/времени - и упоминать не стоит.

@posledam

язык c# прекрасен, лаконичен, удобен и отлично читается.

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

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

А ещё после огня человечество изобрело 100500 религий, каждая из которых была «единственно верной», научилось навешивать ярлыки, прямо как вы в процитированном фрагменте и продолжает регулярно развлекаться охотой на ведьм и религиозными войнами.

@xxxDef

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

Не вижу ничего поразительного в желании видеть хорошо читаемый код вместо кода, который нравится вчерашнему выпускнику шестимесячных курсов «Вкатись в IT».

Если бы длина кода была так критична, то все бы до сих пор однострочники на Perl писали.

@DieSlogan

О, когда работал с SOAP в Java 8, так не хватало 'var'. Прям выворачивало писать всякие ArrayOfElementsTypeFoo и т.п.

В IntelliJ IDEA уже тысячу лет есть постфиксное автодополнение, которое преобразует ваше getFoo().var в ArrayOfElementsTypeFoo foo = getFoo(); после нажатия кнопки Tab.
А возможность набрать AOETF и получить в автодополнении ваш вожделенный ArrayOfElementsTypeFoo появилась ещё раньше. Стоит знать инструмент, которым пользуешься.

Я до сих пор не пониимаю, почему в джаве сохраняется вот эта разница между Integer и int.

Потому что это не одно и то же?
В первом случае объект, который умеет много того, что примитивный тип не умеет, в том числе может иметь значение null , во втором -- примитивный тип.

По-моему решение на уровне компилятора.

Значение типа int в памяти занимает 32 бита, экземпляр класса Integer -- в несколько раз больше. Один заголовок объекта будет больше, чем полезная нагрузка. Бесконечное ОЗУ у вас тоже на уровне компилятора есть?

А ждуниора всегда можно попросить написать сортировку пузырьком или развернуть массив. Даже не список, заметьте. И всё равно всегда будут завалившиеся на этом с воплями «да кому это надо, я Spring учил!».

Если бы вместо того, чтобы фонтанировать эмоциями

Я живой человек, с эмоциями, и горжусь этим. Хотите общения с роботом, специально для вас изобрели ChatGPT :)

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

Религиозные войны в ИТ это хорошо. Это придаёт дополнительный стимул в спорах и нахождении истины, приводит человечество к развитию и переосмыслению.

Не вижу ничего поразительного в желании видеть хорошо читаемый код вместо кода, который нравится вчерашнему выпускнику шестимесячных курсов «Вкатись в IT».

А вот и эмоциональное навешивание глупых ярлыков пошло. Что вы там абзацем ранее говорили?

Если бы длина кода была так критична, то все бы до сих пор однострочники на Perl писали.

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

В IntelliJ IDEA уже тысячу лет есть постфиксное автодополнение, которое преобразует ваше getFoo().var в ArrayOfElementsTypeFoo foo = getFoo(); после нажатия кнопки Tab.

А в Rider (на базе той же IDEA) уже тысячу лет есть хинты, которые показывают выводимый тип. Можно писать var и всё равно прекрасно видеть что там за тип получается. Если кому-то это очень нужно. И никаких Tab нажимать не надо, просто не надо генерировать лишний код там, где он совсем не нужен. Мусор в коде есть мусор, как бы вы не пытались доказать его ценность.

В первом случае объект, который умеет много того, что примитивный тип не умеет, в том числе может иметь значение null , во втором -- примитивный тип.

Я считаю, это костылём и косяком дизайна языка. Ибо в C# Int32, int -- это одно и тоже, примитивный тип всегда, который при этом наделён семантикой объекта и может размещаться в куче, а вам не приходится городить огород между двумя разными типами, которые имеют один и тот же смысл. И есть Nullable (int?, long?, DateTime?....), поэтому вам не придётся для каждого примитива создавать отдельный тип "для размещения в куче". И вы можете создавать сколько угодно значимых типов, не заталкивая их в кучу, чтобы получить заветный null :)

Да, при разработке C# опирались в первую очередь именно на опыт Java и сразу этот жёсткий косяк пофиксили.

Не вижу ничего поразительного в желании видеть хорошо читаемый код вместо кода, который нравится вчерашнему выпускнику шестимесячных курсов «Вкатись в IT».

Если бы длина кода была так критична, то все бы до сих пор однострочники на Perl писали.

с каких то пор более многословный но такой же код стал "хорошо читаемый"?

public string Name { get; set; }

vs

string name;
public string getName() 
{ 
    return name; 
}
public string setName(string value) 
{ 
    name = value; 
}

и так штук двадцать свойств...

и это тольок самый простейший пример

Значение типа int в памяти занимает 32 бита, экземпляр класса Integer
-- в несколько раз больше. Один заголовок объекта будет больше, чем
полезная нагрузка. Бесконечное ОЗУ у вас тоже на уровне компилятора
есть?

В том-то и дело, поэтому расход памяти я должен всеми силами оберегать. А тут на ровном месте вместо примитива у меня объект, а если к нему прибавлю примитив, а потом ещё equals, а там object на входе и привет боксинг/анбоксинг. Вроде ничего не делали, а к нам уже GC напрашивается.

На этом фоне читаешь .NET рекомендации, когда даже для StringBuilder лучше использовать ObjectPool настроить пуллинг под свои нужды, чтобы данный объект не пересоздавать при каждом вызове и опять же, экономить память.

Поэтому:
`int` == `Integer`

Чтобы не тратить память в рантайме попусту.
Кстати, получается, что разница сохраняется только лишь затем, чтобы установить NULL? А зачем он нужен, чтобы кидать потом NullPointerException? А 0 чем на эту роль не годился в ситуации, когда все давно уже говорят о проблемах с этим NULL?

А ждуниора всегда можно попросить написать сортировку пузырьком или развернуть массив.


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

А вот с перегрузкой операторов и датами вы проигнорировали, почему-то.

с каких то пор более многословный но такой же код стал "хорошо читаемый"?

Читаемость не синоним обилия.

Насколько это читабельно по-вашему?

// value - ValueHolder class
// measureMorning, measureDay, measureEvening - variables of type BigDecimal
BigDecimal result = (value.getMeasureMorning().add( value.getMeasureDay().add( value.getMeasureEvening())).divide(3);

Ну серьёзно. Про float/double не вспоминайте, расчёты должны быть точными. Против этого:

// decimal MeasureMorning, MeasureDay, MeasureEvening
var result = ( value.MeasureMorning + value.MeasureDay + value.MeasureEvening ) / 3;

И потом.

Никто не запрещает тем, кто пишет на C#, вместо авто свойств использовать такую форму:

private string _name;
public string Name
{
get { return _name }
set { _name = value; }
}

Но почему-то охотников так писать - мало.

И если он так классно читаем, то почему же тогда в JSP при обращении к полям класса мы не должны писать get/set? Почему в одном месте так, а в другом иначе?

Да и вообще, сейчас народ вообще обленился и пишет вот так:

public record Person(string Name);

А когда в Java завезут async/await на уровне языка? :)

А когда в дотнет завезут green threads?

https://github.com/dotnet/runtimelab/issues/2398

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

В dotnet всё на уровне языка, платформы, core-библиотек и всех современных библиотек поддерживает единый асинхронный API, а также кооперативную отмену, это всё работает очень быстро и эффективно.

Также есть Channels (как в Go). Есть F# для ФП. Довольно сложно что-то такое найти, чего нет в dotnet или чего не умеет делать dotnet.

Ну т.е. у ms пока не получается да?

  1. Вообще async/await это можно сказать костыль для языков и платформ, которые не смогли в обозримое десятилетие завести green thread и переписали свои библиотеки под async await.

  2. Единообразия кмк мало в Task/ValueTask, да и вы забыли написать что написание асинхронного кода сложнее, и часто провоцирует ошибки, да и само разделения кода на синхронный асинхронный - лишняя сущность.

  3. как в Go нет- go каналы на уровне языка.

На кой чёрт вообще нужны каналы на уровне языка, если каналы на уровне библиотеки гораздо более настраиваемы и расширяемы?

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

Нет, просто это не нужно в dotnet, там есть инструменты гораздо лучше, те же Task

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

https://github.com/dotnet/runtimelab/blob/bec51070f1071d83f686be347d160ea864828ef8/docs/design/features/greenthreads.md

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

Именно async/await практически нивелирует сложность для рядового разработчика, так как по сути, код выглядит и ведёт себя как синхронный, но парочкой потоков может выполнять сотни, тысячи задач. Мы можете спокойно запускать огромное количество тасков, и не париться за производительность, или что потоков не хватит.

Разделение кода на синхронный/асинхронный происходит очевидным образом, если вам нужно использовать вызов асинхронного метода, значит ваша функция становится асинхронной. Это ни какая-то скрытая лютая магия, всё прозрачно, при этом сложностей не добавляет, только несколько лишних букв. Стоит признать, что это приводит к засилью async/await слов в коде.

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

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

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

По сути это как раз async/await костыль. Да, лучше иметь async/await, чем не иметь ничего, но гринтреды(по крайней мере в том виде, в котором они реализованы в жаве и голанге) мощнее, чем async/await.

То что это "Proposal Champion", который пилится оч активно, а по факту - это еще одна супер бесполезная фича которая сильнее засахаривает язык. Сахар ради сахара, вместо того чтобы делать полезные фичи которые ждет комьюнити (например те же трейты "shapes and extensions")

Это вовсе не бесполезная фича.
Из-за того, что в дотнете каждый объект может служить мьютексом, приходится выделять дополнительные байты в заголовке каждого объекта для обслуживающей информации: номер потока, держащего блокировку, и текущее количество рекурсивных блокировок (подробнее тут). Чтобы изгнать эту в обычном случае ненужную информацию из объекта, нужно для начала запилить специальный тип объекта, который таки будет служить мьютексом.
Вот этим и занимается данный proposal.

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

На самом деле это не всегда так, тут зависит от компании, есть компании где есть отдельные devops, есть компании, где команда должна сама настраивать выкатку своего сервиса от и до

Как я понял - в случае, когда у нас у каждого сервиса свой реп и солюшен - Aspire будет бесполезен?

Я бы так не сказал. Во первых, можно сделать по AppHost'у на каджый сервис в репе - можно будет хотя бы для 1 сервиса, получать плюхи аспайра, например для поднятия инфраструктуры

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

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

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

В дизайне Aspire закралась одна вещь, которая очень не нравится:

Зачем было добавлять зависимость ProjectReference от сервисов?

Sign up to leave a comment.

Articles