
Alex
30.03.2017
07:21:11
Апишка внешняя, повлиять не можем.

Rustam
30.03.2017
07:22:58
Но, как я уже сказал, том же запросе к АПИ могут быть разные ошибки и бывает нужно раграничивать их и реагировать на разные типы ошибок по разному
Очень может быть, что в твоем проекте этот подход оправдан. Но ты спросил мнения людей в чате. Я поделился своим фидбеком

Alex
30.03.2017
07:23:36

Google

Alex
30.03.2017
07:24:01
Я само собой не буду спорить что это ужастнейший костыль, но это лучше чем вечно падающий прод.

Rustam
30.03.2017
07:25:00
Насчет применения exponential backoff в http запросах есть хорошее решение - https://github.com/lostisland/faraday/blob/master/lib/faraday/request/retry.rb

Alex
30.03.2017
07:25:29
ха, не знал что у фарадея это есть.

Rustam
30.03.2017
07:26:29
А еще, у него есть поддержка адаптеров. Если надло делать кучу запросов, то можно обнаружить, что дефолтный Net::Http у руби - мееедленный
Тогда можно подключить typhoeus(враппер над curl)

Alex
30.03.2017
07:26:57
То что это свитчер адаптеров это я знаю )

Rustam
30.03.2017
07:27:00
и код не надо переписывать

Alex
30.03.2017
07:27:05
я сам тифеус юзаю, только напрямую.

Rustam
30.03.2017
07:32:22
А как инициируется дергание апишки?
По расписанию? Пользователь на веб-морде кнопочку жмакнул?
Или цикл бесконечный?

Alex
30.03.2017
07:34:19
реалтайм

Google

Alex
30.03.2017
07:34:44
бизнеслогика так устроена

Rustam
30.03.2017
07:34:54
а что видит пользователь, когда запрос к апишке завалился?

Alex
30.03.2017
07:35:11
данные по остальным апишкам.

Rustam
30.03.2017
07:36:24
хм.. получается, параллельно делаются запросы?
в тредах?
может, потому и каша, что не thread-safe?

Alex
30.03.2017
07:37:26
апишки друг за другом отрабатываются, они очень быстро отвечают
разбить на фронте на три запроса:
1. Не нужно
2. Дорого, ибо внутри месиво

Rustam
30.03.2017
07:38:09
Понятно.

Alex
30.03.2017
07:38:17
ну да, сплошные костыли

Rustam
30.03.2017
07:41:30
Но если бы нужно было бы сделать вебморду максимально отзывчивой, то рекомендовал бы:
1. Вынести все запросы к API в threaded бекграунд (sidekiq)
2. Обновлять статус прямо в браурере пользователя через websockets / sse

Alex
30.03.2017
07:42:46
> Вынести все запросы к API в threaded бекграунд (sidekiq)
Не понимаю как это будет выглядеть если результаты нужны прямо сейчас
кешировать бесполезно.
делать заранее - бесполезный огромный оверхэд

Rustam
30.03.2017
07:43:53
да, конечно, зависит от задач проекта
Просто сталкивался с подобным. И в какой-то момент приходилось решать проблемы производительности

Alex
30.03.2017
07:49:42
А так да, понятно что если можно закешировать хотя бы на время и делать в фоне, то стоит это делать. К счастью пока таких мест нет.

Rustam
30.03.2017
07:52:37
Можно еще сделать так:
1) от пользователя поступил запрос
2) не заставляя его ждать, сервер сразу рендерит страницу результатов, где на месте каждого блока - спиннер
3) тем временем в бекграунде делаются запросы и по мере выполнения каждого - соотнесенный спиннер заменяется результатом
Конечно, реализация зависит от вашего фронтенда

Alex
30.03.2017
07:53:52
Да, это очевидно. Просто проект - сплошное месиво.

Vasiliy
30.03.2017
07:56:48
забавная вещь тут, все топят за TDD, DRY, но выкладывается код, который делает то же самое что уже готовые отлаженные решения, кто-то критикует код по поводу того что это уже есть и все начинают топить - да ладно, у меня тоже такой костыль, норм, да проверенное решение это оверхед

Google

Alex
30.03.2017
07:57:21
готовые отлаженные решения? это какие же?
ты привел пример rollbar, который просто постфактум отправляет стэктрейс. У меня именно перехватывает ошибку.
причем я не говорю что это не велосипед, мне было интересно мнение по подходу.

Vasiliy
30.03.2017
08:04:28
собственно я об этом как раз и говорю
привели newrelic, sentry
написали что перехват ошибок довольно плохая затея

Alex
30.03.2017
08:13:24
Объяснил же что получить часть данных лучше чем увидеть 500

Vasiliy
30.03.2017
08:17:18
лучше обернуть непосредственное обращение к api в обёртку которая контроллируемо делает вызовы(возвращает данные ошибок, если апи недоступно, ещё чего) и там же обрабатывает исключения, чем оборачивать всё в такое вот
но... я думаю это опять бесполезно спорить

Alex
30.03.2017
08:19:10
это и есть та самая обертка внутри класса которые пытается получить данные ЕСЛИ данные от апи пришли ...

Vasiliy
30.03.2017
08:25:19
ну так сделай путём что-то типа
def call_to_api_server(action, params)
open('http://your_server.com/#{action}#{params')
rescue Net::OpenTimeout => e
do_something
rescue SocketError => e
do_something
end
и у тебя будет ясно сразу при 500 ошибке что-то явно не то

Eugene
30.03.2017
08:25:43
глючный класс

Eugene
30.03.2017
08:25:47
так мож его переписать лол

Alex
30.03.2017
08:27:52
Данные - бред, класс ломается.
(очень редко но случается)

Eugene
30.03.2017
08:28:47

Alex
30.03.2017
08:29:02

Eugene
30.03.2017
08:29:08
что это за код, если он не может обработать некорректные данные?
Или там на входе может быть вообще что угодно, даже небо, даже аллах?

Google

Alex
30.03.2017
08:29:22
Который ожидает что апишка нормально работает, нет?

Eugene
30.03.2017
08:29:32
И ты на все случаи жизни этот класс гоняешь?

Alex
30.03.2017
08:29:36
Там на входе иногда приходит бред, редко но приходит.

Eugene
30.03.2017
08:29:41
Велкам Роман

Alex
30.03.2017
08:29:44
это есть т.н исключение

Eugene
30.03.2017
08:29:53
Ye
Ну

Admin
ERROR: S client not available

Vasiliy
30.03.2017
08:29:54
ну сделай метод
def handle_data
do_something
end

Eugene
30.03.2017
08:30:00
в таких случаях код должен не падать
а говорить "ничоси, я такое не умею"
и работать дальше
это как бы основы

Alex
30.03.2017
08:31:32
это как бы основы
Active model serializers например падает если не может получить доступ к какому то аттрибуту который заявлен

Eugene
30.03.2017
08:31:44
Значит ты неправильно описал этот код

Alex
30.03.2017
08:31:45
ничоси, он кидает эксепшен потому что это действительно эксепшен!

Eugene
30.03.2017
08:31:47
если он прям падает

Alex
30.03.2017
08:33:15
Он падает потому что это исключительная ситуация.

Roman
30.03.2017
08:33:22
эксепшены такого рода обрабатывать надо ну

Eugene
30.03.2017
08:33:38

Google

Roman
30.03.2017
08:33:44
какой смысл ими в юзера стрелять или кто там пользуется твоим приложением

Eugene
30.03.2017
08:33:54
это не конец света, пишешь код для обработки эксепшена и программа работает дальше

Alex
30.03.2017
08:34:00
Причем тут юзеры?
суть как раз в том что если от апишки пришел бред то в юзера я как раз таки 500-ой не стреляю

Eugene
30.03.2017
08:34:16
Я уже потерялся, у тебя проблема в чем конкретно?

Alex
30.03.2017
08:34:20
а возвращаю те данные которые доступны
таким образом я хотя бы часть данных отображаю.

Vasiliy
30.03.2017
08:34:50
ну смотри - ты же можешь проверить что пришло от апишки?

Alex
30.03.2017
08:34:52
Привет ✌ ! у меня есть таблица products и welcome_pages, которая has_many :products с такой схемой
create_table "welcome_pages", force: :cascade do |t|
t.integer "product_id"
t.integer "seq"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["product_id"], name: "index_welcome_pages_on_product_id", using: :btree
endв контроллере я хочу получить эти продукты
@featured_products = WelcomePage.joins(:products) - вот так не получается ?. Буду признателен, если покажете чяднт. С рельсами и sql и орм ами только туториалы проходил)

Alex
30.03.2017
08:35:35
WelcomePage.products?
WelcomePage.find(page_id).products

Vasiliy
30.03.2017
08:36:19
аааааа

Alex
30.03.2017
08:36:21
по некоторым норм.
Ну да, плохо описал задачу, сорян.

Vasiliy
30.03.2017
08:36:43
ты понимаешь что ты прогер и у тебя в принципе не может быть слова в лексиконе слова бред

Alex
30.03.2017
08:36:45
Если бы там полный бред был - было бы проще проверить, да.