Re[15]: Язык Go - слабые стороны
От: Pzz Россия https://github.com/alexpevzner
Дата: 21.02.22 22:22
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Здравствуйте, Pzz, Вы писали:


S>>>man онтогенез

Pzz>>No manual entry for онтогенез
Pzz>>Надо доставить какой-то пакет?
S>да. brains

# dnf install brains
Last metadata expiration check: 3:25:14 ago on Mon 21 Feb 2022 09:56:12 PM MSK.
No match for argument: brains
Error: Unable to find a match: brains


Re[23]: Язык Go - слабые стороны
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.02.22 02:17
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>То, что на момент отправки первого сообщения, данных для следующих сообщений пока ещё нет.

И?

_>))) Обычно на эту тему рисуют такие картинки (кстати, там кажется тестировали даже на вашем родном .net'е) с разницей раз в 10:

_>
  Диаграммка тестов
_>Image: 3526a19782d163fb2d4b39b0ed2fcd3b.png

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

_>И что мешает сделать тоже самое с gRPC? )

То, что в него не встроены такие вещи. Вам придётся вносить всё это в сигнатуру метода, ломая обратную совместимость с клиентами, которые не знают про delta encoding.
А в REST это встроено из коробки. Поэтому можно допиливать сервер, не переживая за то, что часть клиентов не умеют такие вещи.
С учётом разнообразных хидеров аналогом одного REST-ендпоинта будут несколько десятков сигнатур RPC-методов. Чего, естественно, никто не делает.
Вот вам, к примеру, delta encoding даже в голову не пришёл — значит, если дать вам спроектировать сервис на основе gRPC, вы ничего подобного в него не заложите.

_>Ну вот https://tinkoff.github.io/investAPI/ тебе реальный пример. )

Ну я и говорю — для роботов REST может и не подойти.
_>Ну так а если это условие задачи (в биржевой торговле так и есть), то что тогда? )))
Тогда биржа просто забивает на то, что клиент может лечь. Это — его проблемы. Так ведь? Нет задачи "гарантированно известить обо всех событиях".

_>Я же писал, что экондера нет. Да и не нужен он, т.к. на устройстве камера, поток от которой параллельно тоже идёт к пользователю (и тот глазами по картинке легко определяет нужное ему положение).

Угу. С задержкой в 500мс, да?
Простите, эта схема — неработоспособна.
_>Кстати, тут подумалось, что в рамках gRPC можно и поток данных от камеры сделать не параллельным где-то рядом, а прямо в рамках того же API (как stream кадров от сервера).
А то. Можно. Но это — патологически неустойчивый вариант. Пользоваться им будет крайне неудобно. В разы неудобнее, чем через REST.
В то время, как REST архитектура (не протокол, а архитектура) позволит им пользоваться даже без человека на приёмном конце.
_>Я правильно понимаю, что данный поток слов надо воспринимать как слив по данному примеру? )))
Можно и так воспринимать. Но правильнее будет, если вы примете как слив саму формулировку архитектурного решения, т.к. оно вряд ли решит задачу конечного потребителя.

_>С учётом наличия такой https://github.com/grpc-ecosystem/grpc-gateway штуки, мне кажется что выбор о базовой реализации должен быть однозначным. ))) Хотя конечно же по настоящему модные возможности (типа двунаправленных потоков) там отсутствуют — ну это цена за желание поддержки легаси (REST).

Пока что выглядит как попытка совместить недостатки обоих подходов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: Язык Go - слабые стороны
От: Sheridan Россия  
Дата: 22.02.22 06:55
Оценка:
Здравствуйте, Pzz, Вы писали:

S>>>>man онтогенез

Pzz>>>No manual entry for онтогенез
Pzz>>>Надо доставить какой-то пакет?
S>>да. brains
Pzz>
Pzz># dnf install brains
Pzz>Last metadata expiration check: 3:25:14 ago on Mon 21 Feb 2022 09:56:12 PM MSK.
Pzz>No match for argument: brains
Pzz>Error: Unable to find a match: brains
Pzz>

Pzz>

Всё ясно теперь.
# emerge brains -av
These are the packages that would be merged, in order:

Calculating dependencies          ... done!                  
[ebuild   R   ] sci-libs/brains-9999::hand-local  USE="hands intellect mind thinking thought" 0 KiB

Total: 1 package (1 reinstall), Size of downloads: 0 KiB

Matrix has you...
Re[24]: Язык Go - слабые стороны
От: Cyberax Марс  
Дата: 22.02.22 08:26
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>А в REST это встроено из коробки.

Ничерта в REST не встроено. Он просто даёт по морде HTTP запросом — и вперёд с песней реализовывать. В результате, 99 из 100 REST-серверов не будут нормально поддерживать чуть менее, чем весь HTTP.

S>С учётом разнообразных хидеров аналогом одного REST-ендпоинта будут несколько десятков сигнатур RPC-методов.

Не будут. Делаем нужные параметры запроса явным параметром и всё. Для примера, если что-то типа DownloadFile, то в запрос добавляем опциональные поля типа Range и прочих. В качестве бонуса, не нужно заниматься разбором формата Range.

В результате, на практике GRPC уделывает REST по скорости и надёжности разработки.
Sapienti sat!
Re[25]: Язык Go - слабые стороны
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.02.22 10:08
Оценка: +1
Здравствуйте, Cyberax, Вы писали:
C>Ничерта в REST не встроено. Он просто даёт по морде HTTP запросом — и вперёд с песней реализовывать. В результате, 99 из 100 REST-серверов не будут нормально поддерживать чуть менее, чем весь HTTP.
Вы так говорите, как будто это плохо.
А на практике это позволяет делать graceful degradation. Например, мы можем поставить прокси в любом месте соединения между клиентом и сервером (хоть прямой прокси на стороне клиента, хоть реверс прокси на стороне сервера), и получить оптимизацию conditional get, не написав ни строчки кода ни там ни там.
Более того — именно так и делается в 99 из 100 промышленных API, которые отдаются через CDN.

S>>С учётом разнообразных хидеров аналогом одного REST-ендпоинта будут несколько десятков сигнатур RPC-методов.

C>Не будут. Делаем нужные параметры запроса явным параметром и всё. Для примера, если что-то типа DownloadFile, то в запрос добавляем опциональные поля типа Range и прочих. В качестве бонуса, не нужно заниматься разбором формата Range.
Покажите мне реальный (g)RPC API в котором есть опциональные параметры типа Range и прочих.
C>В результате, на практике GRPC уделывает REST по скорости и надёжности разработки.
Ну... Может быть. У меня нет практики работы с gRPC, поэтому я (пока) поверю вам на слово.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Язык Go - слабые стороны
От: alex_public  
Дата: 22.02.22 16:18
Оценка:
Здравствуйте, night beast, Вы писали:

NB>>>тут чувствуется возможность на уровне прикси-сервера распределять нагрузку ничего не зная о реализации конкретных ендпоинтов.

_>>Балансировка запросов встроена прямо в gRPC. )))
NB>и?

Что и? ) Это означает, что абсолютно незачем мучиться с убогим набором команд http, объясняя это убожество возможностью автоматической балансировки. Та же самая автоматическая балансировка спокойно работает и в gRPC (с произвольным набором команд).
Re[24]: Язык Go - слабые стороны
От: alex_public  
Дата: 22.02.22 18:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>То, что на момент отправки первого сообщения, данных для следующих сообщений пока ещё нет.

S>И?

Что и? В gPRC это возможно в рамках одного соединения, а в REST нет.

_>>И что мешает сделать тоже самое с gRPC? )

S>То, что в него не встроены такие вещи. Вам придётся вносить всё это в сигнатуру метода, ломая обратную совместимость с клиентами, которые не знают про delta encoding.
S>А в REST это встроено из коробки. Поэтому можно допиливать сервер, не переживая за то, что часть клиентов не умеют такие вещи.

Так встроено или надо допиливать сервер?

S>С учётом разнообразных хидеров аналогом одного REST-ендпоинта будут несколько десятков сигнатур RPC-методов. Чего, естественно, никто не делает.


Бредим? )

S>Вот вам, к примеру, delta encoding даже в голову не пришёл — значит, если дать вам спроектировать сервис на основе gRPC, вы ничего подобного в него не заложите.


Ты вот это сейчас серьёзно? ) Ты считаешь, что при запросе коллекции данных никому не придёт в голову указывать в запросе её срез и все будут возвращать только коллекцию целиком? )))

_>>Ну вот https://tinkoff.github.io/investAPI/ тебе реальный пример. )

S>Ну я и говорю — для роботов REST может и не подойти.

Ой, т.е. оказывается уже целая большая область обнаружилась, где REST сливает RPC? А кто же у нас вот только что писал:

Прямо на этом сайте уже поднимались примеры "сложных задач", где применение RPC "очевидно" эффективнее. Во всех случаях, АФАИР, RPC проиграл. В рамках CRUD можно представить всё, что угодно. Более того — как раз такое представление и является единственно возможным способом строить распределённые приложения.

И вот уже "неожиданно" оказывается что не "во всех случаях"? )))

А если дальше пойдём разбираться, то вообще окажется что всё наоборот... )))

Да, кстати, у ребят в указанном примере ещё год назад был REST интерфейс (OpenAPI и всё такое)... )))

_>>Ну так а если это условие задачи (в биржевой торговле так и есть), то что тогда? )))

S>Тогда биржа просто забивает на то, что клиент может лечь. Это — его проблемы. Так ведь? Нет задачи "гарантированно известить обо всех событиях".

Нет, как раз требуется гарантированное извещение. И более того, условия ещё более жёсткие — оно требуется в чёткие интервалы времени (чуть позже и эта информация уже бесполезна). Однако сама эта задача априори требует нормальной работоспособности обеих сторон (иначе она просто не может быть решена). Так что вариант с корректной обработкой ситуации умершего клиента смешно даже рассматривать — это априори форс-мажор и потенциальная потеря денег.

_>>Я же писал, что экондера нет. Да и не нужен он, т.к. на устройстве камера, поток от которой параллельно тоже идёт к пользователю (и тот глазами по картинке легко определяет нужное ему положение).

S>Угу. С задержкой в 500мс, да?

И? В чём проблема то?

S>Простите, эта схема — неработоспособна.


Да я смотрю ты и в этой области специалист.

_>>Кстати, тут подумалось, что в рамках gRPC можно и поток данных от камеры сделать не параллельным где-то рядом, а прямо в рамках того же API (как stream кадров от сервера).

S>А то. Можно. Но это — патологически неустойчивый вариант. Пользоваться им будет крайне неудобно. В разы неудобнее, чем через REST.

Оу, видеопоток через REST... Это прямо максимально интересно становится.

S>В то время, как REST архитектура (не протокол, а архитектура) позволит им пользоваться даже без человека на приёмном конце.


Эээ что? ) Весь смысл всего это в том, чтобы человек пейзажики смотрел...

_>>Я правильно понимаю, что данный поток слов надо воспринимать как слив по данному примеру? )))

S>Можно и так воспринимать. Но правильнее будет, если вы примете как слив саму формулировку архитектурного решения, т.к. оно вряд ли решит задачу конечного потребителя.

Какого ещё архитектурного решения? У тебя есть физическая железка с заданными параметрами (условно двумя кнопками влево/вправо и кнопкой включения камеры, возвращающей поток кадров) и надо приделать к ней удалённый доступ. Архитектуру можешь плодить какую хочешь. Но ты уже показал, что в рамках REST подхода ты можешь только слиться с невнятными оправданиями.

_>>С учётом наличия такой https://github.com/grpc-ecosystem/grpc-gateway штуки, мне кажется что выбор о базовой реализации должен быть однозначным. ))) Хотя конечно же по настоящему модные возможности (типа двунаправленных потоков) там отсутствуют — ну это цена за желание поддержки легаси (REST).

S> Пока что выглядит как попытка совместить недостатки обоих подходов.

Это просто инструмент переходного периода. Когда хочется перейти на быстрые современные решения, но при этом надо поддерживать ещё и клиентов с устаревшими подходами...
Отредактировано 22.02.2022 18:49 alex_public . Предыдущая версия .
Re[23]: Язык Go - слабые стороны
От: night beast СССР  
Дата: 22.02.22 18:45
Оценка:
Здравствуйте, alex_public, Вы писали:

NB>>и?


_>Что и? ) Это означает, что абсолютно незачем мучиться с убогим набором команд http, объясняя это убожество возможностью автоматической балансировки. Та же самая автоматическая балансировка спокойно работает и в gRPC (с произвольным набором команд).


чтобы эта балансировка в gRPC работала также, тебе там так-же придется формализовать набор команд как это сделано в REST.
причем, если хочешь работать не только со своим велосипедом, то этот набор команд нужно как-то стандартизировать.
так и в чем в итоге преимущество?
Re[24]: Язык Go - слабые стороны
От: alex_public  
Дата: 22.02.22 19:55
Оценка:
Здравствуйте, night beast, Вы писали:

_>>Что и? ) Это означает, что абсолютно незачем мучиться с убогим набором команд http, объясняя это убожество возможностью автоматической балансировки. Та же самая автоматическая балансировка спокойно работает и в gRPC (с произвольным набором команд).

NB>чтобы эта балансировка в gRPC работала также, тебе там так-же придется формализовать набор команд как это сделано в REST.
NB>причем, если хочешь работать не только со своим велосипедом, то этот набор команд нужно как-то стандартизировать.
NB>так и в чем в итоге преимущество?

Эээ зачем???

И я даже не буду говорить о том, что в реализацию gRPC уже встроена автоматически работающая клиентская балансировка (https://github.com/grpc/grpc/blob/master/doc/load-balancing.md). Предположим что этого всего нет и будем говорить только о серверной балансировке. И так, зачем для неё нужна формализация команд?
Re[25]: Язык Go - слабые стороны
От: night beast СССР  
Дата: 22.02.22 20:06
Оценка:
Здравствуйте, alex_public, Вы писали:

_>И я даже не буду говорить о том, что в реализацию gRPC уже встроена автоматически работающая клиентская балансировка (https://github.com/grpc/grpc/blob/master/doc/load-balancing.md). Предположим что этого всего нет и будем говорить только о серверной балансировке. И так, зачем для неё нужна формализация команд?


я же пример приводил -- команды гет в одну сторону, другие в другую.
как ты это будешь в grpc делать?
Re[26]: Язык Go - слабые стороны
От: Cyberax Марс  
Дата: 23.02.22 01:09
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

C>>Ничерта в REST не встроено. Он просто даёт по морде HTTP запросом — и вперёд с песней реализовывать. В результате, 99 из 100 REST-серверов не будут нормально поддерживать чуть менее, чем весь HTTP.

S>Вы так говорите, как будто это плохо.
Да, это плохо. Все ограничения и способности API должны быть описаны в его схеме. По факту в REST это совсем не так.

Например, имеем вот это API: https://docs.docker.com/engine/api/v1.41/#operation/ContainerArchiveInfo — "взять архив файловой системы".

Внимание, вопрос! Как это API будет взаимодействовать с Range?

S>А на практике это позволяет делать graceful degradation. Например, мы можем поставить прокси в любом месте соединения между клиентом и сервером (хоть прямой прокси на стороне клиента, хоть реверс прокси на стороне сервера), и получить оптимизацию conditional get, не написав ни строчки кода ни там ни там.

S>Более того — именно так и делается в 99 из 100 промышленных API, которые отдаются через CDN.
Не видел пока вообще ни одного API, где был бы conditional get. Более того, я даже не видел клиентов, которые его бы поддерживали.

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

C>>Не будут. Делаем нужные параметры запроса явным параметром и всё. Для примера, если что-то типа DownloadFile, то в запрос добавляем опциональные поля типа Range и прочих. В качестве бонуса, не нужно заниматься разбором формата Range.

S> Покажите мне реальный (g)RPC API в котором есть опциональные параметры типа Range и прочих.
То есть? Это будет просто параметр в API.

Типа:
service FileService {
  rpc DownloadData(in DownloadDataRequest) returns (stream DataChunk);
}

message DownloadDataRequest {
   message ChunkRange {
      uint64 offset = 1;
      uint64 size = 2;
   }
   string file_id = 1;
   repeated ChunkRange chunks = 2;
}

message DataChunk {
   uint64 chunk_index = 1;
   uint64 offset = 2;
   uint64 size = 3;
   bytes data = 4;
}


По API сразу понятно что и как использовать. Не надо гадать: "А поддерживает ли API-сервер Range?"
Sapienti sat!
Re[27]: Язык Go - слабые стороны
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.02.22 05:55
Оценка:
Здравствуйте, Cyberax, Вы писали:
C>Да, это плохо. Все ограничения и способности API должны быть описаны в его схеме. По факту в REST это совсем не так.
По факту это никогда не так. Схема описывает только маленький кусочек поведения API. Тут по соседству обсуждали вопросы тестирования — я там иллюстрацию приводил.
C>Например, имеем вот это API: https://docs.docker.com/engine/api/v1.41/#operation/ContainerArchiveInfo — "взять архив файловой системы".
Нет, "взять архив файловой системы" — это https://docs.docker.com/engine/api/v1.41/#operation/ContainerArchive. А то, что вы показали — это "взять информацию об архиве файловой системы".
C>Внимание, вопрос! Как это API будет взаимодействовать с Range?
Тот, который вы указали — никак. Запрос HEAD не поддерживает хидер Range
Зато вызвав HEAD, мы получим (или не получим) заголовок Accept-Ranges, который скажет всё, что нам надо знать.

А можем просто сразу сделать GET запрос с Range.
Если сервер не умеет в Range, то он просто вернёт полный файл.
При этом мы никогда не перепутаем частичный респонс с полным — поэтому у нас корректно работают любые комбинации клиента и сервера.

C>Не видел пока вообще ни одного API, где был бы conditional get. Более того, я даже не видел клиентов, которые его бы поддерживали.

Любой браузер и любой прокси-сервер.

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

Отчего же "статических"?

C>>>Не будут. Делаем нужные параметры запроса явным параметром и всё. Для примера, если что-то типа DownloadFile, то в запрос добавляем опциональные поля типа Range и прочих. В качестве бонуса, не нужно заниматься разбором формата Range.

S>> Покажите мне реальный (g)RPC API в котором есть опциональные параметры типа Range и прочих.
C>То есть? Это будет просто параметр в API.

C>Типа:

C>
C>service FileService {
C>  rpc DownloadData(in DownloadDataRequest) returns (stream DataChunk);
C>}

C>message DownloadDataRequest {
C>   message ChunkRange {
C>      uint64 offset = 1;
C>      uint64 size = 2;
C>   }
C>   string file_id = 1;
C>   repeated ChunkRange chunks = 2;
C>}

C>message DataChunk {
C>   uint64 chunk_index = 1;
C>   uint64 offset = 2;
C>   uint64 size = 3;
C>   bytes data = 4;
C>}
C>

Пример такого gRPC API в живой природе можно увидеть?

C>По API сразу понятно что и как использовать. Не надо гадать: "А поддерживает ли API-сервер Range?"

При желании, так можно сделать и в REST. Например, многие протоколы вместо Range:items поддерживают явные параметры size и page.
А можно просто пробовать, что поддерживает сервер. Например, если мы получили частичный ответ, а потом соединение упало, то мы можем попытаться запросить недостающую часть.
Не умеет сервер так — ну ок, перевыкачаем целиком. Умеет — сэкономим трафик.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: Язык Go - слабые стороны
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.02.22 06:34
Оценка: +1 :)
Здравствуйте, alex_public, Вы писали:

_>Что и? В gPRC это возможно в рамках одного соединения, а в REST нет.

Возможно, хотя и с натяжкой.

_>Так встроено или надо допиливать сервер?

Встроено в протокол. Реализация в сервере — дело добровольное.
_>Ты вот это сейчас серьёзно? ) Ты считаешь, что при запросе коллекции данных никому не придёт в голову указывать в запросе её срез и все будут возвращать только коллекцию целиком? )))
Конечно. Именно так. Давайте посмотрим на ваш "реальный пример" и убедимся, что, к примеру, в https://tinkoff.github.io/investAPI/marketdata/#getlastpricesrequest не предусмотрено никакого способа запросить "изменения цен с прошлого запроса".
Только коллекция целиком. И так всё и везде.

_>Ой, т.е. оказывается уже целая большая область обнаружилась, где REST сливает RPC?


А кто же у нас вот только что писал:
_>

_> Прямо на этом сайте уже поднимались примеры "сложных задач", где применение RPC "очевидно" эффективнее. Во всех случаях, АФАИР, RPC проиграл. В рамках CRUD можно представить всё, что угодно. Более того — как раз такое представление и является единственно возможным способом строить распределённые приложения.

_>И вот уже "неожиданно" оказывается что не "во всех случаях"? )))
Ну так это же как раз несложная задача.

_>А если дальше пойдём разбираться, то вообще окажется что всё наоборот... )))

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

_>Да, кстати, у ребят в указанном примере ещё год назад был REST интерфейс (OpenAPI и всё такое)... )))

Во-первых, почему "был"? Вот он и сейчас есть: https://tinkoff.github.io/invest-openapi/rest/
Во-вторых, он никакой не REST. Это легко понять, посмотрев на список глаголов. У них все операции сделаны через POST — это как раз означает, что архитекторы тинькова — недоучки, и про REST не поняли ничего.
Это подтверждает мою гипотезу — на gRPC переходит не вся индустрия, а те, кто не осилил REST.

_>Нет, как раз требуется гарантированное извещение. И более того, условия ещё более жёсткие — оно требуется в чёткие интервалы времени (чуть позже и эта информация уже бесполезна). Однако сама эта задача априори требует нормальной работоспособности обеих сторон (иначе она просто не может быть решена). Так что вариант с корректной обработкой ситуации умершего клиента смешно даже рассматривать — это априори форс-мажор и потенциальная потеря денег.

Совершенно верно. Поэтому опытные HFT-пользователи размещают свои сервера в том же датацентре, что и биржа, не так ли
Но большинству простых смертных приложений такой роскоши, как сеть с надёжностью в шесть девяток, никто не даст. Поэтому делать вид, что решение, уместное для биржевых спекулянтов, подойдёт и "списку дел на сегодня" — как-то странно.

_>Да я смотрю ты и в этой области специалист.

Не надо быть специалистом, чтобы понять, как это будет работать. Во времена моей юности мышки были "продвинутым оборудованием", и часть народу на полном серьёзе утверждала, что в кваку можно играть и с клавиатурой.
Сетевой режим расставил всё по своим местам — мышевозы вытеснили клавишников.
Впрочем, мы же рассуждаем о воображаемой задаче. Вообразить-то можно всё что угодно — и пользователя, которому безразлично, в какую сторону смотреть. И оборудование, где на веб-камеру денег хватило, а на енкодер (или хотя бы оптопары для детектирования нулевого положения) — нет.
Я вот могу вам поверх вашей воображаемой задачи предложить другую, на которой ваше "очевидное" решение тут же сольётся: я хочу написать робота, который каждый час заходит в этот API, делает снимки с шагом в 15 градусов, и склеивает из них панораму. При этом связь, как обычно, ненадёжная, а каждая панорама должна быть корректной и выровненной по углу — я потом склею из неё time-lapse.

Если посмотреть с точки зрения архитектуры, то у вашей задачи и HFT есть одна общая черта: мы пренебрегаем ненадёжностью сети. В одном случае — потому, что мы готовы переплачивать за надёжность сети. В другом — потому что нам наплевать на результат. Ну, как eventual-to-never consistency: даже если у нас какой-то из визитов на страницу и не запишется в лог — ничего страшного.
_>Оу, видеопоток через REST... Это прямо максимально интересно становится.
А что вас удивляет? Сейчас так делают более-менее все. Вот, пару недель назад жена участвовала в конференции удалённо. Аудиовидеостриминг в реальном времени.
Благодаря тому, что это было сделано через REST, мы смогли записать полное видео — причём на второй день, записали и первый и второй дни.
Потому что вот так вот устроен стриминг — это не fire-and-forget протокол вроде UDP или RTP, а честный HTTP, причём именно в стиле REST. То есть там лежит некоторый ресурс, который мы можем "читать", а кто-то одновременно дописывает новые данные в хвост этого ресурса.
_>Эээ что? ) Весь смысл всего это в том, чтобы человек пейзажики смотрел...
Это вам сейчас так кажется. А потом выяснится, что человеку интересно, на север он смотрит, или на юг. И что его раздражает невозможность прицелиться в нужную сторону из-за лагающей обратной связи и теряющихся prev/next.
Даже формы опросников, сделанные в RPC стиле, раздражают до неимоверности (это те, где нельзя сделать back в браузере, а надо непременно жать кнопку "Назад").

_>Какого ещё архитектурного решения? У тебя есть физическая железка с заданными параметрами (условно двумя кнопками влево/вправо и кнопкой включения камеры, возвращающей поток кадров) и надо приделать к ней удалённый доступ.


_>Архитектуру можешь плодить какую хочешь. Но ты уже показал, что в рамках REST подхода ты можешь только слиться с невнятными оправданиями.
Почему же? я прикручу к этой железке датчик нуля, сделаю процедуру инициализации, и выставлю REST-протокол по управлению положением.

_>Это просто инструмент переходного периода. Когда хочется перейти на быстрые современные решения, но при этом надо поддерживать ещё и клиентов с устаревшими подходами...


Посмотрим, посмотрим.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[28]: Язык Go - слабые стороны
От: Cyberax Марс  
Дата: 23.02.22 08:13
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Да, это плохо. Все ограничения и способности API должны быть описаны в его схеме. По факту в REST это совсем не так.

S>По факту это никогда не так. Схема описывает только маленький кусочек поведения API. Тут по соседству обсуждали вопросы тестирования — я там иллюстрацию приводил.
Схема может описывать достаточно большой кусок API. По крайней мере, она однозначно может описывать все аргументы метода. В REST на практике нет даже этого.

C>>Например, имеем вот это API: https://docs.docker.com/engine/api/v1.41/#operation/ContainerArchiveInfo — "взять архив файловой системы".

S>Нет, "взять архив файловой системы" — это https://docs.docker.com/engine/api/v1.41/#operation/ContainerArchive. А то, что вы показали — это "взять информацию об архиве файловой системы".
Ага. Но это скорее вопрос к уродам, которые делают документацию в виде бесконечной страницы, которая меняет адресную строку при прокрутке.

C>>Внимание, вопрос! Как это API будет взаимодействовать с Range?

S>Тот, который вы указали — никак. Запрос HEAD не поддерживает хидер Range
S>Зато вызвав HEAD, мы получим (или не получим) заголовок Accept-Ranges, который скажет всё, что нам надо знать.
Т.е. надо иметь копию сервера, причём работающую. И создать ситуацию, когда этот метод можно вызвать.

S>А можем просто сразу сделать GET запрос с Range.

S>Если сервер не умеет в Range, то он просто вернёт полный файл.
S>При этом мы никогда не перепутаем частичный респонс с полным — поэтому у нас корректно работают любые комбинации клиента и сервера.
И как мы это счастье будем тестировать? Код с использованием Range в интеграционных тестах не будет использоваться. Писать сразу нетленку без багов и надеяться, что если Docker в какой-то момент таки добавит Range, то всё будет работать сразу правильно?

Никакие из известных мне генераторов кода по OpenAPI автоматически Range не поддерживают, кстати. Так что надеяться на инструментарий тоже не получится.

C>>Не видел пока вообще ни одного API, где был бы conditional get. Более того, я даже не видел клиентов, которые его бы поддерживали.

S>Любой браузер и любой прокси-сервер.
Браузер тоже не поддерживает для всего. XMLHttpRequest его автоматически не умеет. Так что автоматически он будет только для ресурсов, которые включаются в HTML (т.е. изображения, скрипты, CSS).

Это такое мизерное достоинство, что несерьёзно.

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

S>Отчего же "статических"?
Из-за того, что для нестатических conditional get бессмыслен. Т.е. файл не должен меняться, по крайней мере часто.

S>Пример такого gRPC API в живой природе можно увидеть?

Это практически пример из моего API в приложении, только у меня он в обратную сторону (upload).

Но если хочется публичного API, то вот: https://github.com/googleapis/googleapis/blob/master/google/storage/v2/storage.proto#L623

C>>По API сразу понятно что и как использовать. Не надо гадать: "А поддерживает ли API-сервер Range?"

S>При желании, так можно сделать и в REST. Например, многие протоколы вместо Range:items поддерживают явные параметры size и page.
Можно. Но тогда нет никаких преимуществ перед gRPC.
Sapienti sat!
Re[29]: Язык Go - слабые стороны
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.02.22 09:26
Оценка:
Здравствуйте, Cyberax, Вы писали:


C>>>Внимание, вопрос! Как это API будет взаимодействовать с Range?

S>>Тот, который вы указали — никак. Запрос HEAD не поддерживает хидер Range
S>>Зато вызвав HEAD, мы получим (или не получим) заголовок Accept-Ranges, который скажет всё, что нам надо знать.
C>Т.е. надо иметь копию сервера, причём работающую. И создать ситуацию, когда этот метод можно вызвать.
Нет, не надо. Надо читать RFC2616

C>И как мы это счастье будем тестировать? Код с использованием Range в интеграционных тестах не будет использоваться. Писать сразу нетленку без багов и надеяться, что если Docker в какой-то момент таки добавит Range, то всё будет работать сразу правильно?

Да, лучше всего — писать нетленку без багов. Прокси-сервера предоставляют такую нетленку.
В том то и разница между RPC и REST, что в последнем можно написать универсальный код, который корректно работает.

C>Никакие из известных мне генераторов кода по OpenAPI автоматически Range не поддерживают, кстати. Так что надеяться на инструментарий тоже не получится.

Конечно. И Accept-Encoding, и прочие Accept: не умеют.
C>Браузер тоже не поддерживает для всего. XMLHttpRequest его автоматически не умеет. Так что автоматически он будет только для ресурсов, которые включаются в HTML (т.е. изображения, скрипты, CSS).
И когда это XHR разучился использовать кэш браузера? В последний раз, как я этим интересовался, XHR работали точно так же, как и всё остальное.
C>Это такое мизерное достоинство, что несерьёзно.
Ну, ок.
C>Из-за того, что для нестатических conditional get бессмыслен. Т.е. файл не должен меняться, по крайней мере часто.
Всё ровно наоборот. Для статических мы ставим expiration:never, и никогда не перезапрашиваем.
А вот для контента, который может измениться, conditional get — то, что доктор прописал.
Он позволяет нам дёргать документ хоть раз в секунду — и сразу же получить новую версию, если она есть. Или очень компактный 304, если нету.
S>>При желании, так можно сделать и в REST. Например, многие протоколы вместо Range:items поддерживают явные параметры size и page.
C>Можно. Но тогда нет никаких преимуществ перед gRPC.
Вот именно
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[26]: Язык Go - слабые стороны
От: blacktea  
Дата: 23.02.22 10:52
Оценка: -1
Здравствуйте, Sinclair, Вы писали:

S>А что вас удивляет? Сейчас так делают более-менее все. Вот, пару недель назад жена участвовала в конференции удалённо. Аудиовидеостриминг в реальном времени.

S>Благодаря тому, что это было сделано через REST, мы смогли записать полное видео — причём на второй день, записали и первый и второй дни.
S>Потому что вот так вот устроен стриминг — это не fire-and-forget протокол вроде UDP или RTP, а честный HTTP, причём именно в стиле REST. То есть там лежит некоторый ресурс, который мы можем "читать", а кто-то одновременно дописывает новые данные в хвост этого ресурса.

Господи, да что же ты такое несешь *facepalm*.
Re[27]: Язык Go - слабые стороны
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.02.22 15:46
Оценка:
Здравствуйте, blacktea, Вы писали:

B>Господи, да что же ты такое несешь *facepalm*.

Есть возражения?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[30]: Язык Go - слабые стороны
От: Cyberax Марс  
Дата: 23.02.22 17:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

C>>Т.е. надо иметь копию сервера, причём работающую. И создать ситуацию, когда этот метод можно вызвать.

S>Нет, не надо. Надо читать RFC2616
Ну то есть, опять писать сразу нетленку без тестирования.

C>>И как мы это счастье будем тестировать? Код с использованием Range в интеграционных тестах не будет использоваться. Писать сразу нетленку без багов и надеяться, что если Docker в какой-то момент таки добавит Range, то всё будет работать сразу правильно?

S>Да, лучше всего — писать нетленку без багов. Прокси-сервера предоставляют такую нетленку.
S>В том то и разница между RPC и REST, что в последнем можно написать универсальный код, который корректно работает.
Т.е. для REST мы должны сразу писать код, который возможно будет мёртвым грузом вечно, и который может скрывать в себе дыры в безопасности.

Замечательно.

C>>Никакие из известных мне генераторов кода по OpenAPI автоматически Range не поддерживают, кстати. Так что надеяться на инструментарий тоже не получится.

S>Конечно. И Accept-Encoding, и прочие Accept: не умеют.
Ага.

C>>Браузер тоже не поддерживает для всего. XMLHttpRequest его автоматически не умеет. Так что автоматически он будет только для ресурсов, которые включаются в HTML (т.е. изображения, скрипты, CSS).

S>И когда это XHR разучился использовать кэш браузера? В последний раз, как я этим интересовался, XHR работали точно так же, как и всё остальное.
Не использует. fetch может использовать. При этом, ни один из известных мне небраузерных клиентов не поддерживает.
Sapienti sat!
Re[26]: Язык Go - слабые стороны
От: alex_public  
Дата: 23.02.22 20:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Что и? В gPRC это возможно в рамках одного соединения, а в REST нет.

S>Возможно, хотя и с натяжкой.

Ой, ну к чему эти глупые фантазии))) Двухсторонний канал банально невозможен в REST.

_>>Так встроено или надо допиливать сервер?

S>Встроено в протокол. Реализация в сервере — дело добровольное.

Ну т.е. чтобы это заработало, это надо написать руками. Так и в gRPC тоже самое. В чём отличие то по твоему? )))

_>>Ты вот это сейчас серьёзно? ) Ты считаешь, что при запросе коллекции данных никому не придёт в голову указывать в запросе её срез и все будут возвращать только коллекцию целиком? )))

S>Конечно. Именно так. Давайте посмотрим на ваш "реальный пример" и убедимся, что, к примеру, в https://tinkoff.github.io/investAPI/marketdata/#getlastpricesrequest не предусмотрено никакого способа запросить "изменения цен с прошлого запроса".
S>Только коллекция целиком. И так всё и везде.

О, очень хороший пример по целому ряду пунктов.

Ну для начала здесь у нас как раз каноничный срез коллекции. Просто видимо ты запутался и не заметил, что тут у нас коллекцией является не массив с монотонным индексом (типа времени), а словарь (по всем инструментам). И соответственно срез описывается не интервалом "от и до", а полным перечислением ключей.

Если же ты хотел именно банальный срез монотонного массива, то там прямо рядом лежит функция https://tinkoff.github.io/investAPI/marketdata/#getcandlesrequest с классическими параметрами среза from и to, возвращающая классический кусок массива.

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

И теперь вот вопросик, а как тоже самое канонично описать в REST архитектуре? Просто идеологически тут явно должно быть GET, но при этом передавать массив строк в url как-то крайне печально... )))

_>>Ой, т.е. оказывается уже целая большая область обнаружилась, где REST сливает RPC?

_>>А кто же у нас вот только что писал:
_>>

Прямо на этом сайте уже поднимались примеры "сложных задач", где применение RPC "очевидно" эффективнее. Во всех случаях, АФАИР, RPC проиграл. В рамках CRUD можно представить всё, что угодно. Более того — как раз такое представление и является единственно возможным способом строить распределённые приложения.

_>>И вот уже "неожиданно" оказывается что не "во всех случаях"? )))
S>Ну так это же как раз несложная задача.

Ааа, ну т.е. "в рамках CRUD можно представить всё, что угодно", если это сложные задачи, а вот простые задачи с помощью CRUD плохо представляются... Понятно, понятно...

_>>А если дальше пойдём разбираться, то вообще окажется что всё наоборот... )))

S>Не, если мы пойдём дальше разбираться, то как раз и окажется, что RPC уместен там, где не нужна надёжность.

Так надёжность или сложность? ) Я уже что-то запутался... )))

А особенно забавно это всё звучит с учётом того факта, что REST по сути является строгим подмножеством RPC.

_>>Да, кстати, у ребят в указанном примере ещё год назад был REST интерфейс (OpenAPI и всё такое)... )))

S>Во-первых, почему "был"? Вот он и сейчас есть: https://tinkoff.github.io/invest-openapi/rest/

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

S>Во-вторых, он никакой не REST. Это легко понять, посмотрев на список глаголов. У них все операции сделаны через POST — это как раз означает, что архитекторы тинькова — недоучки, и про REST не поняли ничего.

S>Это подтверждает мою гипотезу — на gRPC переходит не вся индустрия, а те, кто не осилил REST.

Что-то ты сам себе противоречишь. В предыдущем сообщение же сам признал, что для данной задачи REST не особо подходит.

_>>Нет, как раз требуется гарантированное извещение. И более того, условия ещё более жёсткие — оно требуется в чёткие интервалы времени (чуть позже и эта информация уже бесполезна). Однако сама эта задача априори требует нормальной работоспособности обеих сторон (иначе она просто не может быть решена). Так что вариант с корректной обработкой ситуации умершего клиента смешно даже рассматривать — это априори форс-мажор и потенциальная потеря денег.

S>Совершенно верно. Поэтому опытные HFT-пользователи размещают свои сервера в том же датацентре, что и биржа, не так ли
S>Но большинству простых смертных приложений такой роскоши, как сеть с надёжностью в шесть девяток, никто не даст. Поэтому делать вид, что решение, уместное для биржевых спекулянтов, подойдёт и "списку дел на сегодня" — как-то странно.

Не обязательно в том же дата-центре. Но точно в каком-то дата-центре (а не на домашнем компьютере).

_>>Оу, видеопоток через REST... Это прямо максимально интересно становится.

S>А что вас удивляет? Сейчас так делают более-менее все. Вот, пару недель назад жена участвовала в конференции удалённо. Аудиовидеостриминг в реальном времени.
S>Благодаря тому, что это было сделано через REST, мы смогли записать полное видео — причём на второй день, записали и первый и второй дни.
S>Потому что вот так вот устроен стриминг — это не fire-and-forget протокол вроде UDP или RTP, а честный HTTP, причём именно в стиле REST. То есть там лежит некоторый ресурс, который мы можем "читать", а кто-то одновременно дописывает новые данные в хвост этого ресурса.


У меня тут один старый сайтик есть, сохраняемый из ностальгических соображений. Он полностью статический. И теперь я кажется начинаю понимать, что он на самом деле сделан по архитектуре REST! Ну у него там есть разные URL'ы, к ним можно послать GET запросы и получить данные...

_>>Эээ что? ) Весь смысл всего это в том, чтобы человек пейзажики смотрел...

S>Это вам сейчас так кажется. А потом выяснится, что человеку интересно, на север он смотрит, или на юг. И что его раздражает невозможность прицелиться в нужную сторону из-за лагающей обратной связи и теряющихся prev/next.

Вообще, когда человек отвечает подобным образом на подобную задачу, то это может означать только одно из двух:
1. Он абсолютно не компетентен как инженер (не понимает слов ТЗ и т.п.)
2. Он вполне компетентен и всё понимает, но честный ответ на задачу демонстрирует его неправоту, поэтому он начинает вилять и менять ТЗ.

S>Даже формы опросников, сделанные в RPC стиле, раздражают до неимоверности (это те, где нельзя сделать back в браузере, а надо непременно жать кнопку "Назад").


Забавно, у нас в приложение по сути являющемся RPC клиентом (причём не gRPC, а вообще самодельном на базе WebSocket) в браузере, кнопка back отлично работает. Может всё дело в кривизне рук? )))

_>>Какого ещё архитектурного решения? У тебя есть физическая железка с заданными параметрами (условно двумя кнопками влево/вправо и кнопкой включения камеры, возвращающей поток кадров) и надо приделать к ней удалённый доступ.

S>
_>>Архитектуру можешь плодить какую хочешь. Но ты уже показал, что в рамках REST подхода ты можешь только слиться с невнятными оправданиями.
S>Почему же? я прикручу к этой железке датчик нуля, сделаю процедуру инициализации, и выставлю REST-протокол по управлению положением.

Да я уже понял, что ты выставишь требование изменения железа по причине того, что оно плохо сочетается с любимой тобой программной архитектурой. Интересно, как тебя на работу принимали с такими подходами? ) Или ты там при приёме скрывал подобные замашки? )))
Re[26]: Язык Go - слабые стороны
От: alex_public  
Дата: 23.02.22 21:10
Оценка: :))
Здравствуйте, night beast, Вы писали:

_>>И я даже не буду говорить о том, что в реализацию gRPC уже встроена автоматически работающая клиентская балансировка (https://github.com/grpc/grpc/blob/master/doc/load-balancing.md). Предположим что этого всего нет и будем говорить только о серверной балансировке. И так, зачем для неё нужна формализация команд?

NB>я же пример приводил -- команды гет в одну сторону, другие в другую.

Да, прошу прощения, что пропустил это тогда, хотя ещё тогда должен был среагировать. Собственно реакция:

А зачем собственно может понадобится подобная сомнительная балансировка?

NB>как ты это будешь в grpc делать?


Если мне вдруг всё же понадобится реализовывать подобное (крайне сомневаюсь в полезности подобной задачи), то я просто поделю весь сервис на две части (с мутабельными и иммутабельными функциями), разместив их соответственно по разным адресам (т.е. так весь gRPC сервис живёт на одном URL, а так будет на двух).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.