Closed knopki closed 3 years ago
@nkrkv Ребейзнул последний коммит.
throttle_fn
теперь принимает current
и total
из API-Usage-Limit
и может быть задана аргументом throttle
.
Саму функцию подкрутил, чтобы начинала с 100мс задержки, а потом накидывала по чуть-чуть. В сумме опять же 5 минут.
Навставлял локов где попало.
Задержка считается не от "сейчас", а от начала предыдущего запроса.
Для 503 и Retry-After
выставляется именно "покуда ждать". Для API-Usage-Limit
увеличивается текущее "покуда ждать". Благодаря этому корректно работает с тредами - треды стартуют одновременно и они начинают постепенно отставать друг от друга из-за удаляющейся даты ожидания. Когда счётчик обнуляется, то опять начинают строем ходить.
Теперь поддерживается подключение по HTTPS. По-умолчанию остаётся HTTP.
Ошибки, возвращаемые InSales, теперь декодируются из байт в текст и их может прочитать человек.
Если после исчерпания лимита на количество запросов к API мы получаем заголовок
Retry-After
с количеством секунд, то мы повторяем не черезretry_timeout
(1s by default), а ждём столько, сколько нам рекомендовали. Однако, ограничиваем время ожидания 60 секундами, чтобы не быть уязвимыми к какой-нибудь ошибке с другой стороны, когда нас попросили подождать миллион лет. Благодаря этому значительно меньше тратятся ресурсы с нашей стороны и со стороны InSales, особенно при многопоточной работе, когда у каждого потока свойretry_after
. Плюс запросы, возвращающие 503, тоже увеличивают счетчик запросов.Далее немного спорная опция. InSales даёт делать 500 запросов в 5 минут. Причём этот лимит не размазан как-то во времени, а прям строго через пять минут после первого запроса в серии обнуляется счетчик сделанных запросов и у тебя опять есть 500 запросов. В некоторых сценариях получается, что скрипт употребляет весь лимит за несколько секунд, а потом почти пять минут "висит". CircleCI, например, несколько раз прибивал job из-за отсутствия вывода :) Плюс, если трудится несколько скриптов одновременно, то один может просто напрочь заблокировать остальных.
InSales передаёт в заголовке
API-Usage-Limit
максимальное количество запросов в этот промежуток времени и сколько их уже было. Т.е. фактически известен баланс после каждого запроса.Добавляется возможность включить флаг
throttle
(выключен по умолчанию) и даже передать функцию замедленияthrottle_fn
. Текущий баланс передаётся вthrottle_fn
, она возвращает задержку в секундах. Можно нафантазировать себе линейный рейт запросов 5*60/500, например. По-умолчанию подобрана такая функция, что сумма числового ряда от 0 до 500 даёт как раз 300 секунд ожидания. При этом большую часть пути ожидания нет (потому что ожидание меньше round trip) и только в самом конце ожидание между запросами радикально прогрессирует до максимальных 10 секунд. При работе в один поток баланс никогда не выгребается, потому что после последнего запроса добавляется новые 500 запросов и всё опять ускоряется.Побочное явление: Использование
datetime
дляConnection.retry_after
делает удобным недобросовестное использование, когда делается пул подключений с разными credentials и запрос делается через то, где ждать меньше.