Как стать автором
Обновить
4
0

Пользователь

Отправить сообщение

Хорошая новость, давно пора

С 1995 года

Java-апплет — прикладная программа, чаще всего написанная на языке программирования Java в форме байт-кода. Java-апплеты выполняются в веб-обозревателе с использованием виртуальной Java машины (JVM)

Шутка для настоящего специалиста, если что :)

JSON экранировать надо.

Вместо

var content = new StringContent(
  "{\"model\": \"" + SelectedModel + "\", \"prompt\": \"" + message + "\",\"temperature\": 1,\"max_tokens\": 1000}",
  Encoding.UTF8, "application/json");
// ...
var response = await _client.PostAsync("https://api.openai.com/v1/completions", content);

делайте

_client.PostAsJsonAsync("https://api.openai.com/v1/completions", new { model = SelectedModel, prompt = message, temperature = 1, max_tokens = 1000 });

Не пробовали PostgreSQL заменять на SQLite in-memory?
Тесты получаются не совсем "честными", зато быстро, просто и контейнеров не надо.

>> если вам в ваших проектах профита нет, то не знаю, зачем вам доказывать профит :)

А если профит есть, то и доказывать ничего не надо :)

Но если серьезно, используем его уже давно, а профита всё не вижу, поэтому нахожусь в постоянном поиске оного.

Спасибо, что поделились со мной :)

Что-то я совсем запутался. Сначала вы пишете, что: "Конечно, можно сохранять события и в БД, но тогда нам придется самим переизобретать то, что уже умеет RabbitMQ."

Затем, отвечая на мои возражения вы пишете про: "идиома transactional outbox - информация о событии создаётся и сохраняется в локальную БД" ... "Далее отдельный поток извлекает такие события из БД и кладёт в RabbitMQ".

Разве это не то самое переизобретение из комента выше?

Т.е было:

producer ➡ rabbitmq ➡ consumer

стало

producer ➡ DB ➡ inter-producer ➡ rabbitmq ➡ consumer

Точка отказа сместилась, но осталась, система усложнилась. Непонимаю где профит? Мы можем добавлять промежуточные звенья в систему, но это не сделает её лучше.

>> Если упал процесс

Какой именно процесс? producer или consumer?

  1. Давайте представим, что успал producer.

    1. С RabbitMQ: MQ сервер не получит сообщения, оно не встанет в очередь и не дойдет до получателя.

    2. Без RabbitMQ: сообщение так же не дойдет.

  2. Давайте представим, что упал consumer.

    1. С RabbitMQ: RabbitMQ сохранит сообщение в очереди и доставит его, когда consumer будет готов.

    2. Без RabbitMQ: оно всё равно дойдет при следующем "try", ведь контекст сохранен в producer'е. Но есть одно НО, если во время retry producer упадет, мы потеряем сообщение. (гол в пользу Rabbit)

  3. Давайте представим, что упал сам RabbitMQ.

    1. С RabbitMQ: consumer не получит сообщения

    2. Без RabbitMQ: ситуация невозможна (гол против Rabbit)

Итого счёт 1:1.

Но "если брюки выглядят одинаково, зачем платить больше?" ©

Я не вижу реальной выгоды от Рэббита, хотя может я что-то упустил в своем анализе?

>> если сервис упал и не успел сделать ACK, то произойдёт retry

Retry можно делать и без посредников в виде RabbitMQ обычным циклом, которму передается делегат или использовать Polly

Скорее всего вам пришло письмо с просьбой активации, которое вы открыли.

Активируется кликом по ссылке.

Ваш email клиент отправил на нее GET запрос, пытаясь посмотреть, что ж там такое и, таким образом, активировал :)

ZeroSSL лишь притворяется бесплатным.

Когда бдительность усыплена, вам сообщяют, что "You have reached the maximum amount of 90-day certificates allowed on the Free Plan" и требуют 10$ в месяц.

Взвесив все возможности и ресурсы, я решил сделать ставку на карьеру в IT, а музыку оставить хобби.

Музыка, это вам не IT. Тут учиться надо ;)

Фейк?
Гербалайф?
Искусственное раздувание стоимости группой заинтересованных лиц?
Или революция?!!!
Наши эксперты всё выяснили: <здесь могла быть ваша реклама, которая выглядит совсем как не реклама>

Смотрю на картинку "synchronous / asynchronous" и складывается впечатление, что вы путаете синхронный и асинхронный ввод/вывод с последовательным/параллельным выполнением

Подход микросервисов позволяет постепенно деградировать функциональность приложения.

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


CatalogPage ShowCatalog(User user) {
  var isUserAuthorized;

  try {
    isUserAuthorized = Authorize(user);
  }
  catch {
    LogError("Authorization broken!");
    return GetGuestCatalog();
  }

   return isUserAuthorized ? GetUserCatalog(user) : GetGuestCatalog();
}

Здесь не видно, что именно делает ф-ия Authorize: вызывает микросервис или авторизирует с помощью подключенного модуля/библиотеки/пакета внутри процесса.
Но, на самом деле, какая разница? Приложение будет вести себя одинакового.

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

Говнокод внутри процесса валит процесс.
Говнокод внутри микросервиса валит микросервис и все микросервисы, которые с ним работают.
Так или иначе, но приложение перестает работать.
Разве нет?

Вам, на самом деле не нужны эти костыли, ReSharper или что-то еще.
Все гораздо проще


enum MyEnum { A, B, C }

var e = (MyEnum)new Random().Next(0, 2);
Console.WriteLine(e switch
{
    MyEnum.A => "A",
    MyEnum.B => "B"
});

Здесь появляется warning


CS8509 The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern 'ConsoleApp1.Program.MyEnum.C' is not covered

В .editorconfig'е переводите этот warning в ошибку.
Профит!

ежегодно во всем мире запускается более 100 миллионов стартапов. То есть это примерно 3 стартапа в секунду.

тогда ≈ 2.99 должно умирать/поглощаться, иначе случится StartupOverflow

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

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


  1. Пишите лишний код, ведь теперь вам теперь нужна проверка валидности значения, юнит тесты для разных значений.
  2. Усложняете разработку, т.к. вам теперь надо держать в уме и проверять, что код работает с разными значениями.
  3. Тратите время коллег. Им нужно будет понять: зачем это настраивается, т.к. "константа является признаком дурного тона" не самое очевидное правило.
  4. Делаете ваш софт менее предсказуемым, ведь значения в конфиге могут меняться. (забыли обновить конфиг на продакшене, "но на моей машине работает!" ©)
  5. Делаете некоторые типы рефакторинга более трудными.
  6. "Замусориваете" конфиг, усложняя жизнь тем, кто будет разверывать и сопровождать ваш софт
Такие политики работают как обёртка над стандартным HttpClient’ом.

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

Информация

В рейтинге
Не участвует
Откуда
Таганрог, Ростовская обл., Россия
Дата рождения
Зарегистрирован
Активность